mirror of
https://github.com/kunkundi/crossdesk.git
synced 2026-10-25 14:47:00 +08:00
[feat] support standalone iOS and Android releases
This commit is contained in:
@@ -3,6 +3,12 @@ name: Build Android
|
|||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
source_tag:
|
||||||
|
description: "Existing source tag for a standalone Android release."
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
default: ""
|
||||||
outputs:
|
outputs:
|
||||||
version:
|
version:
|
||||||
description: "Independent Android version and build date."
|
description: "Independent Android version and build date."
|
||||||
@@ -11,6 +17,7 @@ on:
|
|||||||
paths:
|
paths:
|
||||||
- ".github/workflows/build-android.yml"
|
- ".github/workflows/build-android.yml"
|
||||||
- ".github/workflows/build.yml"
|
- ".github/workflows/build.yml"
|
||||||
|
- ".github/workflows/release-mobile.yml"
|
||||||
- ".gitmodules"
|
- ".gitmodules"
|
||||||
- "LICENSE"
|
- "LICENSE"
|
||||||
- "apps/android/**"
|
- "apps/android/**"
|
||||||
@@ -32,11 +39,14 @@ jobs:
|
|||||||
version: ${{ steps.package.outputs.version }}
|
version: ${{ steps.package.outputs.version }}
|
||||||
env:
|
env:
|
||||||
XMAKE_VERSION: "3.1.1"
|
XMAKE_VERSION: "3.1.1"
|
||||||
|
CROSSDESK_SOURCE_TAG: ${{ inputs.source_tag || '' }}
|
||||||
|
CROSSDESK_RELEASE_BUILD: ${{ inputs.source_tag && 'YES' || 'NO' }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
ref: ${{ inputs.source_tag || github.ref }}
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
@@ -120,13 +130,19 @@ jobs:
|
|||||||
raise ValueError(f"Invalid Android version: {version!r}")
|
raise ValueError(f"Invalid Android version: {version!r}")
|
||||||
build_date = datetime.datetime.now(ZoneInfo("Asia/Shanghai")).strftime("%Y%m%d")
|
build_date = datetime.datetime.now(ZoneInfo("Asia/Shanghai")).strftime("%Y%m%d")
|
||||||
# Match the dated release tags used by the desktop and iOS jobs.
|
# Match the dated release tags used by the desktop and iOS jobs.
|
||||||
if os.environ["GITHUB_REF_TYPE"] == "tag":
|
tag = os.environ.get("CROSSDESK_SOURCE_TAG")
|
||||||
|
if not tag and os.environ["GITHUB_REF_TYPE"] == "tag":
|
||||||
tag = os.environ["GITHUB_REF_NAME"]
|
tag = os.environ["GITHUB_REF_NAME"]
|
||||||
|
if tag:
|
||||||
|
tag = tag.removeprefix("android-")
|
||||||
match = re.fullmatch(r"v?[0-9]+(?:\.[0-9]+){1,3}-(?:[0-9]+-)?([0-9]{8})(?:-[0-9]+)?", tag)
|
match = re.fullmatch(r"v?[0-9]+(?:\.[0-9]+){1,3}-(?:[0-9]+-)?([0-9]{8})(?:-[0-9]+)?", tag)
|
||||||
if match:
|
if match:
|
||||||
build_date = match[1]
|
build_date = match[1]
|
||||||
datetime.datetime.strptime(build_date, "%Y%m%d")
|
datetime.datetime.strptime(build_date, "%Y%m%d")
|
||||||
version = f"v{version}-{build_date}"
|
version = f"v{version}-{build_date}"
|
||||||
|
source_tag = os.environ.get("CROSSDESK_SOURCE_TAG", "")
|
||||||
|
if source_tag.startswith("android-v") and source_tag.removeprefix("android-") != version:
|
||||||
|
raise ValueError(f"Android source tag does not match the app version: {source_tag} vs {version}")
|
||||||
output = Path(os.environ["RUNNER_TEMP"]) / "crossdesk-android"
|
output = Path(os.environ["RUNNER_TEMP"]) / "crossdesk-android"
|
||||||
for variant, source in (
|
for variant, source in (
|
||||||
("unsigned", "release/app-release-unsigned.apk"),
|
("unsigned", "release/app-release-unsigned.apk"),
|
||||||
|
|||||||
@@ -10,6 +10,11 @@ on:
|
|||||||
default: "0"
|
default: "0"
|
||||||
workflow_call:
|
workflow_call:
|
||||||
inputs:
|
inputs:
|
||||||
|
source_tag:
|
||||||
|
description: "Existing source tag for a standalone iOS release."
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
default: ""
|
||||||
patch:
|
patch:
|
||||||
description: "Optional patch number from the main build workflow."
|
description: "Optional patch number from the main build workflow."
|
||||||
required: false
|
required: false
|
||||||
@@ -23,6 +28,7 @@ on:
|
|||||||
paths:
|
paths:
|
||||||
- ".github/workflows/build-ios.yml"
|
- ".github/workflows/build-ios.yml"
|
||||||
- ".github/workflows/build.yml"
|
- ".github/workflows/build.yml"
|
||||||
|
- ".github/workflows/release-mobile.yml"
|
||||||
- ".gitmodules"
|
- ".gitmodules"
|
||||||
- "LICENSE"
|
- "LICENSE"
|
||||||
- "apps/ios/**"
|
- "apps/ios/**"
|
||||||
@@ -42,6 +48,7 @@ jobs:
|
|||||||
version: ${{ steps.ios_version.outputs.version }}
|
version: ${{ steps.ios_version.outputs.version }}
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ github.token }}
|
GITHUB_TOKEN: ${{ github.token }}
|
||||||
|
CROSSDESK_SOURCE_TAG: ${{ inputs.source_tag || '' }}
|
||||||
IOS_DEPLOYMENT_TARGET: "16.0"
|
IOS_DEPLOYMENT_TARGET: "16.0"
|
||||||
EXPECTED_IOS_SDK: "26.5"
|
EXPECTED_IOS_SDK: "26.5"
|
||||||
XMAKE_VERSION: "3.1.1"
|
XMAKE_VERSION: "3.1.1"
|
||||||
@@ -53,7 +60,8 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
PATCH_NUMBER: ${{ inputs.patch || '0' }}
|
PATCH_NUMBER: ${{ inputs.patch || '0' }}
|
||||||
run: |
|
run: |
|
||||||
VERSION_REF="${GITHUB_REF##*/}"
|
VERSION_REF="${CROSSDESK_SOURCE_TAG:-${GITHUB_REF##*/}}"
|
||||||
|
VERSION_REF="${VERSION_REF#ios-}"
|
||||||
VERSION_BASE="${VERSION_REF#v}"
|
VERSION_BASE="${VERSION_REF#v}"
|
||||||
BUILD_DATE=$(TZ=Asia/Shanghai date +%Y%m%d)
|
BUILD_DATE=$(TZ=Asia/Shanghai date +%Y%m%d)
|
||||||
|
|
||||||
@@ -101,11 +109,14 @@ jobs:
|
|||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
ref: ${{ inputs.source_tag || github.ref }}
|
||||||
|
|
||||||
- name: Select corresponding source tag
|
- name: Select corresponding source tag
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
|
if [[ -n "${CROSSDESK_SOURCE_TAG}" ]]; then
|
||||||
|
echo "CROSSDESK_RELEASE_BUILD=YES" >> "${GITHUB_ENV}"
|
||||||
|
elif [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
|
||||||
echo "CROSSDESK_SOURCE_TAG=${GITHUB_REF_NAME}" >> "${GITHUB_ENV}"
|
echo "CROSSDESK_SOURCE_TAG=${GITHUB_REF_NAME}" >> "${GITHUB_ENV}"
|
||||||
echo "CROSSDESK_RELEASE_BUILD=YES" >> "${GITHUB_ENV}"
|
echo "CROSSDESK_RELEASE_BUILD=YES" >> "${GITHUB_ENV}"
|
||||||
fi
|
fi
|
||||||
@@ -126,6 +137,10 @@ jobs:
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
VERSION_NUM="v${IOS_VERSION_BASE}-${VERSION_NUM##*-}"
|
VERSION_NUM="v${IOS_VERSION_BASE}-${VERSION_NUM##*-}"
|
||||||
|
if [[ "${CROSSDESK_SOURCE_TAG}" == ios-v* && "${CROSSDESK_SOURCE_TAG#ios-}" != "${VERSION_NUM}" ]]; then
|
||||||
|
echo "iOS source tag does not match the app version: ${CROSSDESK_SOURCE_TAG} vs ${VERSION_NUM}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
echo "IOS_VERSION_BASE=${IOS_VERSION_BASE}" >> "${GITHUB_ENV}"
|
echo "IOS_VERSION_BASE=${IOS_VERSION_BASE}" >> "${GITHUB_ENV}"
|
||||||
echo "VERSION_NUM=${VERSION_NUM}" >> "${GITHUB_ENV}"
|
echo "VERSION_NUM=${VERSION_NUM}" >> "${GITHUB_ENV}"
|
||||||
echo "version=${VERSION_NUM}" >> "${GITHUB_OUTPUT}"
|
echo "version=${VERSION_NUM}" >> "${GITHUB_OUTPUT}"
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ on:
|
|||||||
- "!ci/linux-build-image"
|
- "!ci/linux-build-image"
|
||||||
tags:
|
tags:
|
||||||
- "*"
|
- "*"
|
||||||
|
- "!ios-v*"
|
||||||
|
- "!android-v*"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
inputs:
|
inputs:
|
||||||
patch:
|
patch:
|
||||||
|
|||||||
@@ -0,0 +1,149 @@
|
|||||||
|
name: Release Mobile
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- "ios-v*"
|
||||||
|
- "android-v*"
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
source_tag:
|
||||||
|
description: "Existing tag: ios-v0.0.1-20261002 or android-v0.1.0-20261002."
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
prepare:
|
||||||
|
name: Validate mobile source tag
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
outputs:
|
||||||
|
platform: ${{ steps.source.outputs.platform }}
|
||||||
|
tag: ${{ steps.source.outputs.tag }}
|
||||||
|
version: ${{ steps.source.outputs.version }}
|
||||||
|
sha: ${{ steps.source.outputs.sha }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v5
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
|
- name: Resolve source tag
|
||||||
|
id: source
|
||||||
|
shell: python
|
||||||
|
env:
|
||||||
|
SOURCE_TAG: ${{ inputs.source_tag || github.ref_name }}
|
||||||
|
run: |
|
||||||
|
import datetime
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
tag = os.environ["SOURCE_TAG"]
|
||||||
|
match = re.fullmatch(r"(ios|android)-(v[0-9]+\.[0-9]+\.[0-9]+-([0-9]{8}))", tag)
|
||||||
|
if not match:
|
||||||
|
raise ValueError("Use an existing ios-v<app-version>-YYYYMMDD or android-v<app-version>-YYYYMMDD tag")
|
||||||
|
datetime.datetime.strptime(match[3], "%Y%m%d")
|
||||||
|
sha = subprocess.check_output(
|
||||||
|
["git", "rev-parse", "--verify", f"refs/tags/{tag}^{{commit}}"], text=True).strip()
|
||||||
|
with open(os.environ["GITHUB_OUTPUT"], "a") as stream:
|
||||||
|
stream.write(f"platform={match[1]}\ntag={tag}\nversion={match[2]}\nsha={sha}\n")
|
||||||
|
|
||||||
|
build-ios:
|
||||||
|
name: Build iOS release
|
||||||
|
needs: prepare
|
||||||
|
if: needs.prepare.outputs.platform == 'ios'
|
||||||
|
uses: ./.github/workflows/build-ios.yml
|
||||||
|
with:
|
||||||
|
source_tag: ${{ needs.prepare.outputs.tag }}
|
||||||
|
|
||||||
|
build-android:
|
||||||
|
name: Build Android release
|
||||||
|
needs: prepare
|
||||||
|
if: needs.prepare.outputs.platform == 'android'
|
||||||
|
uses: ./.github/workflows/build-android.yml
|
||||||
|
with:
|
||||||
|
source_tag: ${{ needs.prepare.outputs.tag }}
|
||||||
|
|
||||||
|
release:
|
||||||
|
name: Publish mobile release
|
||||||
|
needs: [prepare, build-ios, build-android]
|
||||||
|
if: ${{ !cancelled() && (needs.build-ios.result == 'success' || needs.build-android.result == 'success') }}
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
concurrency:
|
||||||
|
group: mobile-release-${{ needs.prepare.outputs.tag }}
|
||||||
|
cancel-in-progress: false
|
||||||
|
env:
|
||||||
|
PLATFORM: ${{ needs.prepare.outputs.platform }}
|
||||||
|
SOURCE_TAG: ${{ needs.prepare.outputs.tag }}
|
||||||
|
SOURCE_SHA: ${{ needs.prepare.outputs.sha }}
|
||||||
|
VERSION: ${{ needs.prepare.outputs.version }}
|
||||||
|
BUILD_VERSION: ${{ needs.build-ios.outputs.version || needs.build-android.outputs.version }}
|
||||||
|
steps:
|
||||||
|
- name: Verify release version
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
if [[ "${BUILD_VERSION}" != "${VERSION}" ]]; then
|
||||||
|
echo "Source tag version ${VERSION} does not match the app version ${BUILD_VERSION}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Download mobile release artifact
|
||||||
|
uses: actions/download-artifact@v8
|
||||||
|
with:
|
||||||
|
name: crossdesk-${{ env.PLATFORM }}-arm64-unsigned-${{ env.VERSION }}
|
||||||
|
path: release
|
||||||
|
|
||||||
|
- name: Prepare release notes
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
if [[ "${PLATFORM}" == "ios" ]]; then
|
||||||
|
PLATFORM_NAME="iOS"
|
||||||
|
SIGNING_NOTE="The arm64 ZIP contains an unsigned app, source metadata, third-party sources and any generated dSYM. Sign the app before device installation."
|
||||||
|
else
|
||||||
|
PLATFORM_NAME="Android"
|
||||||
|
SIGNING_NOTE="The arm64 Release APK is unsigned. Sign it with your own key before installation. It includes source metadata, license documents and native build recipes."
|
||||||
|
fi
|
||||||
|
cat > "${RUNNER_TEMP}/mobile-release-notes.md" << EOF
|
||||||
|
${PLATFORM_NAME} ${VERSION}
|
||||||
|
|
||||||
|
${SIGNING_NOTE}
|
||||||
|
|
||||||
|
Source: [${SOURCE_TAG}](https://github.com/${GITHUB_REPOSITORY}/tree/${SOURCE_SHA}).
|
||||||
|
Clone this tag with recursive submodules to obtain the corresponding source.
|
||||||
|
[Source and rebuild instructions](https://github.com/${GITHUB_REPOSITORY}/blob/${SOURCE_SHA}/apps/${PLATFORM}/README.md).
|
||||||
|
EOF
|
||||||
|
|
||||||
|
- name: Publish GitHub Release
|
||||||
|
uses: softprops/action-gh-release@v2
|
||||||
|
with:
|
||||||
|
tag_name: ${{ env.SOURCE_TAG }}
|
||||||
|
target_commitish: ${{ env.SOURCE_SHA }}
|
||||||
|
name: ${{ env.PLATFORM == 'ios' && 'iOS' || 'Android' }} ${{ env.VERSION }}
|
||||||
|
draft: false
|
||||||
|
prerelease: false
|
||||||
|
make_latest: "false"
|
||||||
|
files: release/*
|
||||||
|
fail_on_unmatched_files: true
|
||||||
|
generate_release_notes: false
|
||||||
|
body_path: ${{ runner.temp }}/mobile-release-notes.md
|
||||||
|
|
||||||
|
- name: Upload mobile artifact to download server
|
||||||
|
uses: burnett01/rsync-deployments@5.2
|
||||||
|
with:
|
||||||
|
switches: -avzr --progress
|
||||||
|
path: release/*
|
||||||
|
remote_path: /var/www/html/downloads/
|
||||||
|
remote_host: ${{ secrets.SERVER_HOST }}
|
||||||
|
remote_user: ${{ secrets.SERVER_USER }}
|
||||||
|
remote_key: ${{ secrets.SERVER_KEY }}
|
||||||
|
|
||||||
|
- name: Summarize release
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
echo "Published [${SOURCE_TAG}](https://github.com/${GITHUB_REPOSITORY}/releases/tag/${SOURCE_TAG}) and uploaded its unsigned ${PLATFORM} artifact to the download server." >> "${GITHUB_STEP_SUMMARY}"
|
||||||
@@ -10,6 +10,7 @@ permissions:
|
|||||||
jobs:
|
jobs:
|
||||||
update-version-json:
|
update-version-json:
|
||||||
name: Update version.json with release information
|
name: Update version.json with release information
|
||||||
|
if: ${{ !startsWith(github.event.release.tag_name, 'ios-v') && !startsWith(github.event.release.tag_name, 'android-v') }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
@@ -75,6 +75,17 @@ Release 构建使用 `./gradlew :app:assembleRelease`,默认输出未签名 AP
|
|||||||
|
|
||||||
[`Build Android`](../../.github/workflows/build-android.yml) 可在 Actions 页面单独手动运行;修改 Android、MiniRTC、共享协议或许可证资料的 Pull Request 也会触发。仓库原有的 [`Build and Release`](../../.github/workflows/build.yml) 在分支推送、标签推送及手动运行时调用同一工作流,`v` 标签发布会等待安卓构建成功,并将未签名 Release APK 加入 GitHub Release 和现有下载服务器的产物集合。推送主仓库前,先确保它引用的 MiniRTC 提交已推送到子模块远程仓库,否则 CI 无法完成检出。
|
[`Build Android`](../../.github/workflows/build-android.yml) 可在 Actions 页面单独手动运行;修改 Android、MiniRTC、共享协议或许可证资料的 Pull Request 也会触发。仓库原有的 [`Build and Release`](../../.github/workflows/build.yml) 在分支推送、标签推送及手动运行时调用同一工作流,`v` 标签发布会等待安卓构建成功,并将未签名 Release APK 加入 GitHub Release 和现有下载服务器的产物集合。推送主仓库前,先确保它引用的 MiniRTC 提交已推送到子模块远程仓库,否则 CI 无法完成检出。
|
||||||
|
|
||||||
|
单独发布使用 [`Release Mobile`](../../.github/workflows/release-mobile.yml)。先提交 `app/build.gradle` 中需要发布的 `versionName`,再为该提交创建 `android-v<versionName>-YYYYMMDD` 标签,例如:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git tag android-v0.1.0-20261002
|
||||||
|
git push origin android-v0.1.0-20261002
|
||||||
|
```
|
||||||
|
|
||||||
|
该标签只触发安卓构建,将未签名 Release APK 发布到独立的 GitHub Release 和现有下载服务器。标签版本必须与应用版本一致,日期必须有效。重试发布时,在 Actions 页面手动运行 `Release Mobile`,将已有标签填入 `source_tag`;即使从其他分支触发,也会检出该标签的源码。APK 的源码资料记录安卓标签及准确的应用、MiniRTC 提交。
|
||||||
|
|
||||||
|
移动端独立发布不会更新桌面 `latest` 标签、GitHub 的最新 Release 选择或桌面 `version.json`。下载服务器上传保留其他平台文件,复用仓库已有的 `SERVER_HOST`、`SERVER_USER`、`SERVER_KEY` Secrets。普通桌面版本标签仍通过 `Build and Release` 发布全部平台;单独运行 `Build Android` 仍只上传 Actions 构建产物。
|
||||||
|
|
||||||
工作流使用 Ubuntu 24.04、JDK 17、Python 3.13、SDK 36、Build Tools 36.0.0、NDK r28c 和 Xmake 3.1.1。Gradle 使用工程内的 Wrapper,原生构建器固定 Xmake 包仓库版本。Gradle 缓存与 Android 原生依赖缓存分别管理;原生缓存按宿主架构、构建脚本及 MiniRTC 配方区分,不复用桌面或 iOS 的配置和目标文件。
|
工作流使用 Ubuntu 24.04、JDK 17、Python 3.13、SDK 36、Build Tools 36.0.0、NDK r28c 和 Xmake 3.1.1。Gradle 使用工程内的 Wrapper,原生构建器固定 Xmake 包仓库版本。Gradle 缓存与 Android 原生依赖缓存分别管理;原生缓存按宿主架构、构建脚本及 MiniRTC 配方区分,不复用桌面或 iOS 的配置和目标文件。
|
||||||
|
|
||||||
CI 构建 Debug、Release 和设备测试 APK,执行 Debug / Release Lint、本机 C++ 协议与画面队列测试,并校验 APK 的 arm64 ABI、16 KB ELF / ZIP 对齐、完整许可证及 Debug 签名。Ubuntu x64 构建机上不运行 arm64 设备测试;使用下面的设备验证流程在 arm64 手机或模拟器上执行。Lint 报告在构建失败时也会保留。
|
CI 构建 Debug、Release 和设备测试 APK,执行 Debug / Release Lint、本机 C++ 协议与画面队列测试,并校验 APK 的 arm64 ABI、16 KB ELF / ZIP 对齐、完整许可证及 Debug 签名。Ubuntu x64 构建机上不运行 arm64 设备测试;使用下面的设备验证流程在 arm64 手机或模拟器上执行。Lint 报告在构建失败时也会保留。
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
"""Package existing reviewed notices for the Android runtime dependency set."""
|
"""Package existing reviewed notices for the Android runtime dependency set."""
|
||||||
import json
|
import json
|
||||||
import hashlib
|
import hashlib
|
||||||
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import subprocess
|
import subprocess
|
||||||
from urllib.parse import quote
|
from urllib.parse import quote
|
||||||
@@ -74,10 +75,19 @@ def write_pages(output, catalog, additional, revision, minirtc):
|
|||||||
component['documents'] = documents
|
component['documents'] = documents
|
||||||
(output / 'ThirdPartyLicenses.json').write_text(json.dumps(
|
(output / 'ThirdPartyLicenses.json').write_text(json.dumps(
|
||||||
{'schemaVersion': 1, 'components': components}, ensure_ascii=False, indent=2)+'\n', encoding='utf-8')
|
{'schemaVersion': 1, 'components': components}, ensure_ascii=False, indent=2)+'\n', encoding='utf-8')
|
||||||
tags = sorted(tag for tag in git('tag', '--points-at', 'HEAD').splitlines() if tag.startswith('v'))
|
tags = git('tag', '--points-at', 'HEAD').splitlines()
|
||||||
|
tag = os.environ.get('CROSSDESK_SOURCE_TAG')
|
||||||
|
if tag and tag not in tags:
|
||||||
|
raise ValueError(f'Source tag {tag!r} does not point to the build commit')
|
||||||
|
if not tag:
|
||||||
|
versions = sorted(value for value in tags if value.startswith(('v', 'android-v')))
|
||||||
|
tag = versions[0] if versions else None
|
||||||
|
dirty = bool(git('status', '--porcelain', '--untracked-files=normal', '--ignore-submodules=none'))
|
||||||
|
if os.environ.get('CROSSDESK_RELEASE_BUILD') == 'YES' and (dirty or not tag or not tag.startswith(('v', 'android-v'))):
|
||||||
|
raise ValueError('Release source must be a clean checkout of a version tag, with matching submodules')
|
||||||
metadata = {
|
metadata = {
|
||||||
'schemaVersion': 1, 'revision': revision, 'tag': tags[0] if tags else None,
|
'schemaVersion': 1, 'revision': revision, 'tag': tag,
|
||||||
'isModified': bool(git('status', '--porcelain', '--untracked-files=normal', '--ignore-submodules=none')),
|
'isModified': dirty,
|
||||||
'sourceURL': source,
|
'sourceURL': source,
|
||||||
'buildInstructionsURL': f'https://github.com/kunkundi/crossdesk/blob/{quote(revision, safe="")}/apps/android/README.md',
|
'buildInstructionsURL': f'https://github.com/kunkundi/crossdesk/blob/{quote(revision, safe="")}/apps/android/README.md',
|
||||||
'buildDocuments': build_documents, 'miniRTCRevision': minirtc,
|
'buildDocuments': build_documents, 'miniRTCRevision': minirtc,
|
||||||
|
|||||||
+24
-1
@@ -93,7 +93,30 @@ including the app, source metadata, third-party source catalog, rights notice
|
|||||||
and any generated dSYM. The version comes from the iOS target; dated repository
|
and any generated dSYM. The version comes from the iOS target; dated repository
|
||||||
tags provide the build date, otherwise the date uses the Asia/Shanghai timezone.
|
tags provide the build date, otherwise the date uses the Asia/Shanghai timezone.
|
||||||
The main workflow collects this same ZIP for GitHub Releases and the download
|
The main workflow collects this same ZIP for GitHub Releases and the download
|
||||||
server. Standalone runs only upload the build artifact.
|
server. Standalone `Build iOS` runs only upload the build artifact.
|
||||||
|
|
||||||
|
For an independent release, use the
|
||||||
|
[`Release Mobile`](../../.github/workflows/release-mobile.yml) workflow. Commit
|
||||||
|
the intended `MARKETING_VERSION` in the iOS target, then tag that commit with
|
||||||
|
`ios-v<marketing-version>-YYYYMMDD`, for example:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git tag ios-v0.0.1-20261002
|
||||||
|
git push origin ios-v0.0.1-20261002
|
||||||
|
```
|
||||||
|
|
||||||
|
The tag starts only the iOS build and publishes its unsigned ZIP to a dedicated
|
||||||
|
GitHub Release and the existing download server. The tag version must match the
|
||||||
|
iOS target, and its date must be valid. To retry a release, run `Release Mobile`
|
||||||
|
manually and enter the existing tag in `source_tag`; it builds that tag's source
|
||||||
|
even when the workflow is dispatched from a different branch. Source metadata
|
||||||
|
records the iOS tag and exact application/MiniRTC commits.
|
||||||
|
|
||||||
|
Mobile releases keep the desktop `latest` tag, GitHub's latest release selection
|
||||||
|
and desktop `version.json` unchanged. Uploads preserve other platforms' files
|
||||||
|
on the download server and use the existing `SERVER_HOST`, `SERVER_USER` and
|
||||||
|
`SERVER_KEY` repository secrets. Regular desktop version tags still publish all
|
||||||
|
platforms through `Build and Release`.
|
||||||
|
|
||||||
No Apple signing secrets are needed. Sign the app yourself before installing
|
No Apple signing secrets are needed. Sign the app yourself before installing
|
||||||
it on a device. Push any referenced MiniRTC commit before the parent repository
|
it on a device. Push any referenced MiniRTC commit before the parent repository
|
||||||
|
|||||||
@@ -46,9 +46,9 @@ def source_metadata(require_release=False, tag=None):
|
|||||||
raise ValueError(f"Source tag {tag!r} does not point to the build commit")
|
raise ValueError(f"Source tag {tag!r} does not point to the build commit")
|
||||||
else:
|
else:
|
||||||
# 'latest' is a moving alias, never a corresponding-source identifier.
|
# 'latest' is a moving alias, never a corresponding-source identifier.
|
||||||
versions = sorted(t for t in tags if t.startswith("v"))
|
versions = sorted(t for t in tags if t.startswith(("v", "ios-v")))
|
||||||
tag = versions[0] if versions else None
|
tag = versions[0] if versions else None
|
||||||
if require_release and (dirty or not tag or not tag.startswith("v")):
|
if require_release and (dirty or not tag or not tag.startswith(("v", "ios-v"))):
|
||||||
raise ValueError("Release source must be a clean checkout of a version tag, with matching submodules")
|
raise ValueError("Release source must be a clean checkout of a version tag, with matching submodules")
|
||||||
mini_revision = git("rev-parse", "HEAD", root=REPO / "deps/submodules/minirtc")
|
mini_revision = git("rev-parse", "HEAD", root=REPO / "deps/submodules/minirtc")
|
||||||
lock_path = REPO / "apps/ios/licenses/sources.json"
|
lock_path = REPO / "apps/ios/licenses/sources.json"
|
||||||
|
|||||||
Reference in New Issue
Block a user