From 7ce93d03cac9406fcb4f9731d457749020a2cd48 Mon Sep 17 00:00:00 2001 From: wgqqqqq Date: Sat, 10 Oct 2026 10:31:43 +0800 Subject: [PATCH 1/7] ci: publish Android releases separately --- .github/workflows/desktop-package.yml | 10 +- .github/workflows/mobile-package.yml | 152 ++++++++++++++++++++++++++ README.md | 2 +- README.zh-CN.md | 2 +- docs/development/releasing.md | 19 ++++ scripts/check-github-config.test.mjs | 21 ++++ 6 files changed, 198 insertions(+), 8 deletions(-) create mode 100644 .github/workflows/mobile-package.yml diff --git a/.github/workflows/desktop-package.yml b/.github/workflows/desktop-package.yml index 50e7bdf341..e9abf18e88 100644 --- a/.github/workflows/desktop-package.yml +++ b/.github/workflows/desktop-package.yml @@ -757,19 +757,17 @@ jobs: run: | set -euo pipefail shopt -s globstar + # AppImage, deb, and rpm files are already copied into the + # canonical release-updater-assets directory above. Publishing the + # raw Tauri bundle names as well creates a second public copy of + # every Linux installer and doubles the signature count. node scripts/stage-github-release-assets.mjs \ --out-dir release-upload-assets \ release-updater-assets/* \ release-manual-assets/*.exe \ release-manual-assets/*.exe.sig \ - release-assets/**/*.AppImage \ - release-assets/**/*.AppImage.sig \ - release-assets/**/*.deb \ - release-assets/**/*.deb.sig \ release-assets/**/*.dmg \ release-assets/**/*.dmg.sig \ - release-assets/**/*.rpm \ - release-assets/**/*.rpm.sig \ release-assets/minisign.pub \ linux-release-assets/openbitfun-cli-*.tar.gz \ linux-release-assets/openbitfun-cli-*.tar.gz.sha256 \ diff --git a/.github/workflows/mobile-package.yml b/.github/workflows/mobile-package.yml new file mode 100644 index 0000000000..626bfc67b5 --- /dev/null +++ b/.github/workflows/mobile-package.yml @@ -0,0 +1,152 @@ +name: Mobile Package + +on: + push: + tags: + - 'mobile-v*' + workflow_dispatch: + inputs: + tag_name: + description: 'Mobile release tag (for example mobile-v1.0.0).' + required: true + type: string + +permissions: + contents: write + +concurrency: + group: mobile-package-${{ github.event.release.tag_name || inputs.tag_name || github.ref_name }} + cancel-in-progress: false + +jobs: + prepare: + name: Prepare mobile release + runs-on: ubuntu-latest + outputs: + tag_name: ${{ steps.meta.outputs.tag_name }} + version: ${{ steps.meta.outputs.version }} + prerelease: ${{ steps.meta.outputs.prerelease }} + steps: + - uses: actions/checkout@v5 + with: + ref: ${{ inputs.tag_name || github.ref_name }} + fetch-depth: 1 + + - name: Resolve mobile version + id: meta + shell: bash + env: + INPUT_TAG_NAME: ${{ inputs.tag_name }} + REF_NAME: ${{ github.ref_name }} + run: | + set -euo pipefail + TAG="${INPUT_TAG_NAME:-${REF_NAME}}" + case "$TAG" in + mobile-v*) ;; + *) echo "Expected a mobile-v* tag, got $TAG" >&2; exit 1 ;; + esac + VERSION="${TAG#mobile-v}" + node scripts/verify-release-version-sync.mjs --mobile-version "$VERSION" + if [[ "$VERSION" == *-* ]]; then + PRERELEASE=true + else + PRERELEASE=false + fi + printf 'tag_name=%s\nversion=%s\nprerelease=%s\n' \ + "$TAG" "$VERSION" "$PRERELEASE" >> "$GITHUB_OUTPUT" + + android: + name: Android package + needs: prepare + runs-on: ubuntu-latest + env: + OPENBITFUN_ANDROID_KEYSTORE_B64: ${{ secrets.OPENBITFUN_ANDROID_KEYSTORE_B64 }} + OPENBITFUN_ANDROID_KEYSTORE_PASSWORD: ${{ secrets.OPENBITFUN_ANDROID_KEYSTORE_PASSWORD }} + OPENBITFUN_ANDROID_KEY_ALIAS: ${{ secrets.OPENBITFUN_ANDROID_KEY_ALIAS }} + OPENBITFUN_ANDROID_KEY_PASSWORD: ${{ secrets.OPENBITFUN_ANDROID_KEY_PASSWORD }} + steps: + - uses: actions/checkout@v5 + with: + ref: ${{ needs.prepare.outputs.tag_name }} + + - uses: actions/setup-java@v5 + with: + distribution: temurin + java-version: '21' + + - uses: actions/setup-node@v5 + with: + node-version: '22.18.0' + + - uses: gradle/actions/setup-gradle@v4 + + - name: Configure Android release signing + shell: bash + run: | + set -euo pipefail + for value in \ + OPENBITFUN_ANDROID_KEYSTORE_B64 \ + OPENBITFUN_ANDROID_KEYSTORE_PASSWORD \ + OPENBITFUN_ANDROID_KEY_ALIAS \ + OPENBITFUN_ANDROID_KEY_PASSWORD; do + if [[ -z "${!value:-}" ]]; then + echo "Missing required Android signing secret: $value" >&2 + exit 1 + fi + done + KEYSTORE_PATH="$RUNNER_TEMP/openbitfun-release.keystore" + printf '%s' "$OPENBITFUN_ANDROID_KEYSTORE_B64" | base64 --decode > "$KEYSTORE_PATH" + echo "OPENBITFUN_ANDROID_KEYSTORE=$KEYSTORE_PATH" >> "$GITHUB_ENV" + + - name: Build signed Android package + working-directory: src/apps/mobile/android + run: ./gradlew :app:assembleRelease --no-daemon + + - name: Stage Android release assets + shell: bash + env: + VERSION: ${{ needs.prepare.outputs.version }} + run: | + set -euo pipefail + mkdir -p mobile-release-assets + cp src/apps/mobile/android/app/build/outputs/apk/release/app-release.apk \ + "mobile-release-assets/OpenBitFun-Mobile-${VERSION}-android.apk" + (cd mobile-release-assets && sha256sum ./*.apk > SHA256SUMS) + + - uses: actions/upload-artifact@v6 + with: + name: openbitfun-mobile-${{ needs.prepare.outputs.tag_name }}-android + path: mobile-release-assets/* + if-no-files-found: error + retention-days: 7 + + publish: + name: Publish mobile release + needs: [prepare, android] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + with: + ref: ${{ needs.prepare.outputs.tag_name }} + + - uses: actions/download-artifact@v7 + with: + name: openbitfun-mobile-${{ needs.prepare.outputs.tag_name }}-android + path: mobile-release-assets + + - name: Create mobile release + env: + GH_TOKEN: ${{ github.token }} + TAG_NAME: ${{ needs.prepare.outputs.tag_name }} + VERSION: ${{ needs.prepare.outputs.version }} + PRERELEASE: ${{ needs.prepare.outputs.prerelease }} + shell: bash + run: | + set -euo pipefail + gh release create "$TAG_NAME" \ + --repo "$GITHUB_REPOSITORY" \ + --verify-tag \ + --title "OpenBitFun Mobile $VERSION" \ + --generate-notes \ + --prerelease="$PRERELEASE" \ + mobile-release-assets/* diff --git a/README.md b/README.md index 14cc39e567..aae4e69c63 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ OpenBitFun is a highly customizable, open-source agent workspace that keeps work **If this is the kind of agent workspace you want, ⭐ Star OpenBitFun and help more people discover it.** -[Download](https://openbitfun.com/download) · [Mini App Marketplace](https://market.openbitfun.com/miniapp/) · [Contribute](./CONTRIBUTING.md) +[Download Desktop](https://openbitfun.com/download) · [Mobile Releases](https://github.com/GCWing/OpenBitFun/releases?q=mobile-&expanded=true) · [Mini App Marketplace](https://market.openbitfun.com/miniapp/) · [Contribute](./CONTRIBUTING.md) [![Website](https://img.shields.io/badge/Website-openbitfun.com-0b7285?style=flat-square)](https://openbitfun.com/) [![Core code: MIT](https://img.shields.io/badge/core_code-MIT-yellow?style=flat-square)](./LICENSE) diff --git a/README.zh-CN.md b/README.zh-CN.md index dc4b438cc3..059a86891e 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -12,7 +12,7 @@ OpenBitFun 是一个高度可定制的开源 Agent 工作台,让任务按你 **如果你也期待这样的 Agent,欢迎点亮 ⭐ Star,让更多人发现 OpenBitFun。** -[下载体验](https://openbitfun.com/zh/download) · [Mini App 市场](https://market.openbitfun.com/miniapp/) · [参与共建](./CONTRIBUTING_CN.md) +[下载桌面端](https://openbitfun.com/zh/download) · [移动端 Release](https://github.com/GCWing/OpenBitFun/releases?q=mobile-&expanded=true) · [Mini App 市场](https://market.openbitfun.com/miniapp/) · [参与共建](./CONTRIBUTING_CN.md) [![官网](https://img.shields.io/badge/%E5%AE%98%E7%BD%91-openbitfun.com-0b7285?style=flat-square)](https://openbitfun.com/zh) [![Core code: MIT](https://img.shields.io/badge/core_code-MIT-yellow?style=flat-square)](./LICENSE) diff --git a/docs/development/releasing.md b/docs/development/releasing.md index 122c26958c..2c52f94689 100644 --- a/docs/development/releasing.md +++ b/docs/development/releasing.md @@ -22,6 +22,25 @@ its tag automatically. Release creation and editing use GitHub CLI without `--target`: sending `target_commitish` for workflow-changing commits can require `workflows:write`, even for an existing tag. Asset upload precedes publication. +## Mobile Android releases + +Mobile Android packages are released independently from Desktop packages. Use a +`mobile-vMAJOR.MINOR.PATCH` tag (or a prerelease suffix such as +`mobile-v1.1.0-beta.1`) to trigger [`Mobile Package`](../../.github/workflows/mobile-package.yml). +The workflow builds a signed APK in GitHub Actions and publishes it to its own +GitHub Release. It does not add Android assets to the Desktop `v*` Release. + +The Android workflow requires the repository secrets +`OPENBITFUN_ANDROID_KEYSTORE_B64`, `OPENBITFUN_ANDROID_KEYSTORE_PASSWORD`, +`OPENBITFUN_ANDROID_KEY_ALIAS`, and `OPENBITFUN_ANDROID_KEY_PASSWORD`. The +keystore is decoded only into the ephemeral Actions runner. Mobile Android +versions are checked as a group across the Android, iOS, and HarmonyOS version +files, but they do not need to equal the Desktop version. + +GitHub exposes one repository-wide `Latest` release. Link the Desktop and Mobile +release pages separately from the project download page and the Desktop release +notes. + ## Legacy update isolation Desktop 1.x reads `latest-v1.json`; CLI 1.x reads `linux-binaries-v1.json`, diff --git a/scripts/check-github-config.test.mjs b/scripts/check-github-config.test.mjs index 280733ddcc..813cc0c48a 100644 --- a/scripts/check-github-config.test.mjs +++ b/scripts/check-github-config.test.mjs @@ -1094,10 +1094,31 @@ test('stages unique release asset names before publishing', () => { /release-assets\/\*\*\/\*\.sig(?:\s|\\)/, 'raw updater signatures have colliding names across macOS architectures', ); + assert.doesNotMatch( + steps[stagingIndex].run, + /release-assets\/\*\*\/\*(?:\.AppImage|\.deb|\.rpm)(?:\s|\\)/, + 'raw Linux bundles must not duplicate canonical updater assets in the public release', + ); } assert.match(steps[uploadIndex].run, /--clobber release-upload-assets\/\*/); }); +test('Mobile Package publishes Android assets from mobile-v tags', () => { + const workflow = yaml.parse( + readFileSync(path.join(repoRoot, '.github/workflows/mobile-package.yml'), 'utf8'), + ); + assert.ok(workflow.on.push.tags.includes('mobile-v*')); + assert.match( + workflow.jobs.android.steps.find((step) => step.name === 'Build signed Android package').run, + /:app:assembleRelease/, + ); + assert.equal(workflow.jobs.publish.needs.includes('android'), true); + assert.match( + workflow.jobs.publish.steps.find((step) => step.name === 'Create mobile release').run, + /gh release create/, + ); +}); + test('Desktop packaging installs Bun before preparing the OpenCode extension Host', () => { const workflow = yaml.parse( readFileSync(path.join(repoRoot, '.github/workflows/desktop-package.yml'), 'utf8'), From c6e47e3b5368f675322940c73e29f9ccaaefdb5e Mon Sep 17 00:00:00 2001 From: wgqqqqq Date: Sat, 10 Oct 2026 10:57:42 +0800 Subject: [PATCH 2/7] ci: install pnpm before Android packaging --- .github/workflows/mobile-package.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/mobile-package.yml b/.github/workflows/mobile-package.yml index 626bfc67b5..1d5c4d3ba5 100644 --- a/.github/workflows/mobile-package.yml +++ b/.github/workflows/mobile-package.yml @@ -74,6 +74,10 @@ jobs: distribution: temurin java-version: '21' + - uses: pnpm/action-setup@v5 + with: + version: 10.15.0 + - uses: actions/setup-node@v5 with: node-version: '22.18.0' From b3ba6d447142fa5dddbb818c1767e0a0527a3fe6 Mon Sep 17 00:00:00 2001 From: wgqqqqq Date: Sat, 10 Oct 2026 10:59:39 +0800 Subject: [PATCH 3/7] ci: use repository pnpm version for mobile builds --- .github/workflows/mobile-package.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/mobile-package.yml b/.github/workflows/mobile-package.yml index 1d5c4d3ba5..47887982de 100644 --- a/.github/workflows/mobile-package.yml +++ b/.github/workflows/mobile-package.yml @@ -75,8 +75,6 @@ jobs: java-version: '21' - uses: pnpm/action-setup@v5 - with: - version: 10.15.0 - uses: actions/setup-node@v5 with: From 30d3055fe07527642b87f7ef5a74760230d73d2c Mon Sep 17 00:00:00 2001 From: wgqqqqq Date: Sat, 10 Oct 2026 11:25:51 +0800 Subject: [PATCH 4/7] ci: use debug signing for fork mobile builds --- .github/workflows/mobile-package.yml | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/.github/workflows/mobile-package.yml b/.github/workflows/mobile-package.yml index 47887982de..f2f5180d43 100644 --- a/.github/workflows/mobile-package.yml +++ b/.github/workflows/mobile-package.yml @@ -60,6 +60,7 @@ jobs: needs: prepare runs-on: ubuntu-latest env: + USE_DEBUG_SIGNING: ${{ github.repository != 'GCWing/OpenBitFun' && 'true' || 'false' }} OPENBITFUN_ANDROID_KEYSTORE_B64: ${{ secrets.OPENBITFUN_ANDROID_KEYSTORE_B64 }} OPENBITFUN_ANDROID_KEYSTORE_PASSWORD: ${{ secrets.OPENBITFUN_ANDROID_KEYSTORE_PASSWORD }} OPENBITFUN_ANDROID_KEY_ALIAS: ${{ secrets.OPENBITFUN_ANDROID_KEY_ALIAS }} @@ -86,6 +87,10 @@ jobs: shell: bash run: | set -euo pipefail + if [[ "$USE_DEBUG_SIGNING" == "true" ]]; then + echo "Fork build: using the runner-generated Android debug keystore." + exit 0 + fi for value in \ OPENBITFUN_ANDROID_KEYSTORE_B64 \ OPENBITFUN_ANDROID_KEYSTORE_PASSWORD \ @@ -108,11 +113,16 @@ jobs: shell: bash env: VERSION: ${{ needs.prepare.outputs.version }} + DEBUG_SIGNING: ${{ github.repository != 'GCWing/OpenBitFun' && 'true' || 'false' }} run: | set -euo pipefail mkdir -p mobile-release-assets + suffix='' + if [[ "$DEBUG_SIGNING" == "true" ]]; then + suffix='-debug' + fi cp src/apps/mobile/android/app/build/outputs/apk/release/app-release.apk \ - "mobile-release-assets/OpenBitFun-Mobile-${VERSION}-android.apk" + "mobile-release-assets/OpenBitFun-Mobile-${VERSION}-android${suffix}.apk" (cd mobile-release-assets && sha256sum ./*.apk > SHA256SUMS) - uses: actions/upload-artifact@v6 @@ -142,9 +152,14 @@ jobs: TAG_NAME: ${{ needs.prepare.outputs.tag_name }} VERSION: ${{ needs.prepare.outputs.version }} PRERELEASE: ${{ needs.prepare.outputs.prerelease }} + FORK_DEBUG_BUILD: ${{ github.repository != 'GCWing/OpenBitFun' && 'true' || 'false' }} shell: bash run: | set -euo pipefail + if [[ "$FORK_DEBUG_BUILD" == "true" ]]; then + PRERELEASE=true + VERSION="$VERSION (fork debug signing)" + fi gh release create "$TAG_NAME" \ --repo "$GITHUB_REPOSITORY" \ --verify-tag \ From 7db44156a724e7ad7657aff345791227f1ef41c3 Mon Sep 17 00:00:00 2001 From: wgqqqqq Date: Sat, 10 Oct 2026 11:34:13 +0800 Subject: [PATCH 5/7] ci: avoid unused node setup in mobile package --- .github/workflows/mobile-package.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/mobile-package.yml b/.github/workflows/mobile-package.yml index f2f5180d43..c5d52a956f 100644 --- a/.github/workflows/mobile-package.yml +++ b/.github/workflows/mobile-package.yml @@ -75,11 +75,6 @@ jobs: distribution: temurin java-version: '21' - - uses: pnpm/action-setup@v5 - - - uses: actions/setup-node@v5 - with: - node-version: '22.18.0' - uses: gradle/actions/setup-gradle@v4 From 94ceeae4697397a020706eda3b3efb8033c0f56c Mon Sep 17 00:00:00 2001 From: wgqqqqq Date: Sat, 10 Oct 2026 11:47:57 +0800 Subject: [PATCH 6/7] ci: use debug signing for all mobile prereleases --- .github/workflows/mobile-package.yml | 39 +++------------------------- docs/development/releasing.md | 15 +++++------ 2 files changed, 10 insertions(+), 44 deletions(-) diff --git a/.github/workflows/mobile-package.yml b/.github/workflows/mobile-package.yml index c5d52a956f..57c6bd5dc4 100644 --- a/.github/workflows/mobile-package.yml +++ b/.github/workflows/mobile-package.yml @@ -59,12 +59,6 @@ jobs: name: Android package needs: prepare runs-on: ubuntu-latest - env: - USE_DEBUG_SIGNING: ${{ github.repository != 'GCWing/OpenBitFun' && 'true' || 'false' }} - OPENBITFUN_ANDROID_KEYSTORE_B64: ${{ secrets.OPENBITFUN_ANDROID_KEYSTORE_B64 }} - OPENBITFUN_ANDROID_KEYSTORE_PASSWORD: ${{ secrets.OPENBITFUN_ANDROID_KEYSTORE_PASSWORD }} - OPENBITFUN_ANDROID_KEY_ALIAS: ${{ secrets.OPENBITFUN_ANDROID_KEY_ALIAS }} - OPENBITFUN_ANDROID_KEY_PASSWORD: ${{ secrets.OPENBITFUN_ANDROID_KEY_PASSWORD }} steps: - uses: actions/checkout@v5 with: @@ -75,30 +69,13 @@ jobs: distribution: temurin java-version: '21' - - uses: gradle/actions/setup-gradle@v4 - name: Configure Android release signing shell: bash run: | set -euo pipefail - if [[ "$USE_DEBUG_SIGNING" == "true" ]]; then - echo "Fork build: using the runner-generated Android debug keystore." - exit 0 - fi - for value in \ - OPENBITFUN_ANDROID_KEYSTORE_B64 \ - OPENBITFUN_ANDROID_KEYSTORE_PASSWORD \ - OPENBITFUN_ANDROID_KEY_ALIAS \ - OPENBITFUN_ANDROID_KEY_PASSWORD; do - if [[ -z "${!value:-}" ]]; then - echo "Missing required Android signing secret: $value" >&2 - exit 1 - fi - done - KEYSTORE_PATH="$RUNNER_TEMP/openbitfun-release.keystore" - printf '%s' "$OPENBITFUN_ANDROID_KEYSTORE_B64" | base64 --decode > "$KEYSTORE_PATH" - echo "OPENBITFUN_ANDROID_KEYSTORE=$KEYSTORE_PATH" >> "$GITHUB_ENV" + echo "Using the runner-generated Android debug keystore for this mobile prerelease." - name: Build signed Android package working-directory: src/apps/mobile/android @@ -108,14 +85,10 @@ jobs: shell: bash env: VERSION: ${{ needs.prepare.outputs.version }} - DEBUG_SIGNING: ${{ github.repository != 'GCWing/OpenBitFun' && 'true' || 'false' }} run: | set -euo pipefail mkdir -p mobile-release-assets - suffix='' - if [[ "$DEBUG_SIGNING" == "true" ]]; then - suffix='-debug' - fi + suffix='-debug' cp src/apps/mobile/android/app/build/outputs/apk/release/app-release.apk \ "mobile-release-assets/OpenBitFun-Mobile-${VERSION}-android${suffix}.apk" (cd mobile-release-assets && sha256sum ./*.apk > SHA256SUMS) @@ -146,15 +119,11 @@ jobs: GH_TOKEN: ${{ github.token }} TAG_NAME: ${{ needs.prepare.outputs.tag_name }} VERSION: ${{ needs.prepare.outputs.version }} - PRERELEASE: ${{ needs.prepare.outputs.prerelease }} - FORK_DEBUG_BUILD: ${{ github.repository != 'GCWing/OpenBitFun' && 'true' || 'false' }} + PRERELEASE: true shell: bash run: | set -euo pipefail - if [[ "$FORK_DEBUG_BUILD" == "true" ]]; then - PRERELEASE=true - VERSION="$VERSION (fork debug signing)" - fi + VERSION="$VERSION (debug signing)" gh release create "$TAG_NAME" \ --repo "$GITHUB_REPOSITORY" \ --verify-tag \ diff --git a/docs/development/releasing.md b/docs/development/releasing.md index 2c52f94689..e2ce50d1ea 100644 --- a/docs/development/releasing.md +++ b/docs/development/releasing.md @@ -27,15 +27,12 @@ its tag automatically. Release creation and editing use GitHub CLI without Mobile Android packages are released independently from Desktop packages. Use a `mobile-vMAJOR.MINOR.PATCH` tag (or a prerelease suffix such as `mobile-v1.1.0-beta.1`) to trigger [`Mobile Package`](../../.github/workflows/mobile-package.yml). -The workflow builds a signed APK in GitHub Actions and publishes it to its own -GitHub Release. It does not add Android assets to the Desktop `v*` Release. - -The Android workflow requires the repository secrets -`OPENBITFUN_ANDROID_KEYSTORE_B64`, `OPENBITFUN_ANDROID_KEYSTORE_PASSWORD`, -`OPENBITFUN_ANDROID_KEY_ALIAS`, and `OPENBITFUN_ANDROID_KEY_PASSWORD`. The -keystore is decoded only into the ephemeral Actions runner. Mobile Android -versions are checked as a group across the Android, iOS, and HarmonyOS version -files, but they do not need to equal the Desktop version. +The workflow builds an Android APK with the runner-generated debug keystore and +publishes it to its own prerelease GitHub Release. It does not add Android assets +to the Desktop `v*` Release. A production signing key can be introduced later +without changing the mobile tag or release layout. Mobile Android versions are +checked as a group across the Android, iOS, and HarmonyOS version files, but they +do not need to equal the Desktop version. GitHub exposes one repository-wide `Latest` release. Link the Desktop and Mobile release pages separately from the project download page and the Desktop release From af228ab9591387c5d498ae38d0a1d1da5a184134 Mon Sep 17 00:00:00 2001 From: wgqqqqq Date: Sat, 10 Oct 2026 12:00:29 +0800 Subject: [PATCH 7/7] ci: link mobile prerelease from desktop notes --- .github/workflows/desktop-package.yml | 20 ++++++++++++++++++-- docs/development/releasing.md | 6 +++--- scripts/check-github-config.test.mjs | 15 +++++++++++++++ 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/.github/workflows/desktop-package.yml b/.github/workflows/desktop-package.yml index e9abf18e88..bf9df5f4c0 100644 --- a/.github/workflows/desktop-package.yml +++ b/.github/workflows/desktop-package.yml @@ -825,9 +825,25 @@ jobs: esac gh release upload "${RELEASE_TAG}" --repo "${GITHUB_REPOSITORY}" \ --clobber release-upload-assets/* + MOBILE_VERSION="$(sed -nE 's/.*versionName = "([^"]+)".*/\1/p' \ + src/apps/mobile/android/app/build.gradle.kts 2>/dev/null | head -n1 || true)" + MOBILE_VERSION="${MOBILE_VERSION:-$RELEASE_VERSION}" + gh release view "${RELEASE_TAG}" --repo "${GITHUB_REPOSITORY}" \ + --json body --jq .body > release-notes.md + if ! grep -q '' release-notes.md; then + cat >> release-notes.md < + ### Android mobile + + Android mobile version **${MOBILE_VERSION}** is published separately as a prerelease: + [Download the Android prerelease](https://github.com/${GITHUB_REPOSITORY}/releases/tag/mobile-v${MOBILE_VERSION}). + The current APK uses the runner-generated debug signing key. + EOF + fi gh release edit "${RELEASE_TAG}" --repo "${GITHUB_REPOSITORY}" \ - --title "OpenBitFun ${RELEASE_VERSION}" --draft=false \ - --prerelease="${RELEASE_PRERELEASE}" --latest="${RELEASE_LATEST}" + --title "OpenBitFun ${RELEASE_VERSION}" --notes-file release-notes.md \ + --draft=false --prerelease="${RELEASE_PRERELEASE}" --latest="${RELEASE_LATEST}" - name: Verify published legacy update feeds if: needs.prepare.outputs.release_channel == 'stable' diff --git a/docs/development/releasing.md b/docs/development/releasing.md index e2ce50d1ea..be2d33378f 100644 --- a/docs/development/releasing.md +++ b/docs/development/releasing.md @@ -34,9 +34,9 @@ without changing the mobile tag or release layout. Mobile Android versions are checked as a group across the Android, iOS, and HarmonyOS version files, but they do not need to equal the Desktop version. -GitHub exposes one repository-wide `Latest` release. Link the Desktop and Mobile -release pages separately from the project download page and the Desktop release -notes. +GitHub exposes one repository-wide `Latest` release. Desktop release notes also +include the Android version and a link to the corresponding Mobile prerelease, +while the Desktop release itself contains no Android APK assets. ## Legacy update isolation diff --git a/scripts/check-github-config.test.mjs b/scripts/check-github-config.test.mjs index 813cc0c48a..5435132d42 100644 --- a/scripts/check-github-config.test.mjs +++ b/scripts/check-github-config.test.mjs @@ -1103,6 +1103,21 @@ test('stages unique release asset names before publishing', () => { assert.match(steps[uploadIndex].run, /--clobber release-upload-assets\/\*/); }); +test('Desktop release notes link the separately published Android prerelease', () => { + const workflow = yaml.parse( + readFileSync( + path.join(repoRoot, '.github/workflows/desktop-package.yml'), + 'utf8', + ), + ); + const uploadStep = workflow.jobs['upload-release-assets'].steps.find( + (step) => step.name === 'Upload to release', + ); + assert.match(uploadStep.run, /mobile-v\$\{MOBILE_VERSION\}/); + assert.match(uploadStep.run, /runner-generated debug signing key/); + assert.match(uploadStep.run, /--notes-file release-notes\.md/); +}); + test('Mobile Package publishes Android assets from mobile-v tags', () => { const workflow = yaml.parse( readFileSync(path.join(repoRoot, '.github/workflows/mobile-package.yml'), 'utf8'),