mirror of
https://github.com/stablyai/orca.git
synced 2026-09-21 16:02:20 +00:00
* fix(ci): stop Android release notes exceeding the GitHub body limit
gh release create --generate-notes let GitHub pick the previous tag. Release
tags live on side branches, so 0.0.46 and 0.0.47 are not ancestors of main and
detection reached back to 0.0.44, generating four releases' worth of notes:
130413 characters against a 125000 limit, which 422'd the publish after a full
Gradle build. The span grows every release.
Pin the comparison to the previous mobile-android release (0.0.47 -> 81862
characters) and cap the body so an unexpected span can never fail the publish.
* fix(ci): fall back when release-notes generation returns an HTTP error
gh writes the JSON error body to stdout on a failed request, so the redirect
left it in the notes file. The non-empty check then treated that blob as valid
notes and skipped the fallback, publishing {"message":...} as the release body.
Gate on exit status instead. Also match the current tag literally when picking
the previous release, so the dots are not regex wildcards.
* fix(ci): reuse the shared character-safe release-body truncation
The byte-based cap could split a multi-byte character at the boundary.
config/scripts/create-draft-release.mjs already exports truncateReleaseBody
with the same 120000 cap and a truncation notice, and the desktop release path
uses it. Import is side-effect free; its main() is guarded.
---------
Co-authored-by: Merge Sim <sim@local>
151 lines
5.5 KiB
YAML
151 lines
5.5 KiB
YAML
name: Mobile Android Release
|
|
|
|
# Why a separate workflow from iOS: iOS releases go through App Store review,
|
|
# which can take days. Decoupling the triggers lets an Android release ship
|
|
# immediately without waiting on iOS, and vice versa.
|
|
on:
|
|
push:
|
|
tags:
|
|
- 'mobile-android-v*'
|
|
workflow_dispatch:
|
|
inputs:
|
|
release_version:
|
|
description: 'Optional exact mobile marketing version assertion, e.g. 0.0.22'
|
|
required: false
|
|
type: string
|
|
publish_github_release:
|
|
description: 'Create or update the mobile-android-v<version> GitHub Release'
|
|
required: false
|
|
default: true
|
|
type: boolean
|
|
|
|
jobs:
|
|
android-build:
|
|
runs-on: ubuntu-latest
|
|
|
|
# Why: the "Create GitHub Release" step below uses the default GITHUB_TOKEN
|
|
# to call `gh release create`, which requires contents:write. Without this,
|
|
# the job builds the APK fine but fails at release time with
|
|
# "HTTP 403: Resource not accessible by integration".
|
|
permissions:
|
|
contents: write
|
|
|
|
defaults:
|
|
run:
|
|
working-directory: mobile
|
|
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v6
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@v6
|
|
with:
|
|
node-version: 24
|
|
|
|
- name: Setup pnpm
|
|
uses: pnpm/setup@v2
|
|
with:
|
|
install: false
|
|
|
|
- name: Install dependencies
|
|
run: pnpm install --frozen-lockfile
|
|
|
|
- name: Resolve release version and version code
|
|
id: release
|
|
env:
|
|
MOBILE_ANDROID_RELEASE_VERSION: ${{ github.event.inputs.release_version }}
|
|
MOBILE_ANDROID_PUBLISH_RELEASE: ${{ github.event.inputs.publish_github_release }}
|
|
run: node scripts/prepare-android-release.mjs
|
|
|
|
- name: Setup JDK 17
|
|
uses: actions/setup-java@v5
|
|
with:
|
|
distribution: temurin
|
|
java-version: 17
|
|
|
|
- name: Expo prebuild
|
|
run: npx expo prebuild --platform android --no-install
|
|
|
|
- name: Build Android release APK
|
|
run: cd android && ./gradlew assembleRelease
|
|
|
|
- name: Upload APK artifact
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: orca-mobile-apk
|
|
path: mobile/android/app/build/outputs/apk/release/*.apk
|
|
|
|
- name: Ensure GitHub release tag
|
|
if: steps.release.outputs.publish_release == 'true' && !startsWith(github.ref, 'refs/tags/mobile-android-v')
|
|
run: |
|
|
set -euo pipefail
|
|
tag="${{ steps.release.outputs.tag }}"
|
|
|
|
if git ls-remote --exit-code --tags origin "refs/tags/$tag" >/dev/null 2>&1; then
|
|
echo "Tag $tag already exists"
|
|
exit 0
|
|
fi
|
|
|
|
git tag "$tag" "$GITHUB_SHA"
|
|
git push origin "refs/tags/$tag"
|
|
|
|
- name: Create GitHub Release
|
|
if: steps.release.outputs.publish_release == 'true'
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
run: |
|
|
set -euo pipefail
|
|
tag="${{ steps.release.outputs.tag }}"
|
|
|
|
if gh release view "$tag" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
|
|
gh release upload "$tag" \
|
|
--repo "$GITHUB_REPOSITORY" \
|
|
--clobber \
|
|
android/app/build/outputs/apk/release/*.apk
|
|
else
|
|
# Why: release tags live on side branches, so GitHub's automatic
|
|
# previous-tag detection reaches back several releases; that body
|
|
# already exceeds the 125000-character API limit and grows each
|
|
# release. Pin the comparison base and cap the size.
|
|
notes_file="$RUNNER_TEMP/android-release-notes.md"
|
|
previous_tag="$(
|
|
gh release list --repo "$GITHUB_REPOSITORY" --limit 200 --json tagName --jq '.[].tagName' \
|
|
| grep '^mobile-android-v' | grep -Fxv "$tag" | sort -V | tail -1 || true
|
|
)"
|
|
|
|
if [ -n "$previous_tag" ]; then
|
|
# Why: gh writes the JSON error body to stdout on an HTTP error, so a
|
|
# non-empty file is not proof of success — gate on exit status.
|
|
if ! gh api "repos/$GITHUB_REPOSITORY/releases/generate-notes" -X POST \
|
|
-f tag_name="$tag" \
|
|
-f target_commitish="$GITHUB_SHA" \
|
|
-f previous_tag_name="$previous_tag" \
|
|
--jq .body > "$notes_file"; then
|
|
: > "$notes_file"
|
|
fi
|
|
fi
|
|
if [ ! -s "$notes_file" ]; then
|
|
printf 'Orca Mobile Android %s\n' "$tag" > "$notes_file"
|
|
fi
|
|
# Why: reuse the desktop release path's character-safe truncation so a
|
|
# multi-byte character cannot be split at the cap.
|
|
NOTES_FILE="$notes_file" \
|
|
NOTES_MODULE="$GITHUB_WORKSPACE/config/scripts/create-draft-release.mjs" \
|
|
node --input-type=module -e '
|
|
const { readFileSync, writeFileSync } = await import("node:fs")
|
|
const { pathToFileURL } = await import("node:url")
|
|
const { truncateReleaseBody } = await import(pathToFileURL(process.env.NOTES_MODULE).href)
|
|
const file = process.env.NOTES_FILE
|
|
writeFileSync(file, truncateReleaseBody(readFileSync(file, "utf8")))
|
|
'
|
|
|
|
gh release create "$tag" \
|
|
--repo "$GITHUB_REPOSITORY" \
|
|
--title "Orca Mobile Android $tag" \
|
|
--prerelease \
|
|
--latest=false \
|
|
--notes-file "$notes_file" \
|
|
android/app/build/outputs/apk/release/*.apk
|
|
fi
|