git.iko.soy/opencode-android
on 29df003 help sign in
113 lines 4.3 kB history raw
1name: Release
3# Build a minified, signed release APK and publish it as a GitHub Release.
4#
5# Runs automatically on every push to `master` (e.g. a merged PR), on a pushed
6# version tag (e.g. `git tag v1.2.0 && git push --tags`), or manually from the
7# Actions tab (workflow_dispatch). For a branch push or manual run the version
8# is derived from the current UTC time as YYYY.MM.DD.HHMM; a tag push uses the
9# tag name (with the leading `v` stripped) as the version.
11# The `v*` tag this workflow pushes when publishing a release does NOT retrigger
12# it: events created with the default GITHUB_TOKEN don't start new workflow runs.
14# Signing: if the `OPENCODE_STORE_*` secrets are configured the APK is signed
15# with that keystore; otherwise the Gradle build falls back to the debug key so
16# the released APK is still installable (see app/build.gradle.kts). The version
17# is passed to Gradle as `-PversionName/-PversionCode` and stamped into the APK.
18on:
19 push:
20 branches: [master]
21 tags: ["v*"]
22 workflow_dispatch:
24# Never abort a release mid-flight — a half-published release with a missing
25# artifact is worse than a slightly delayed one.
26concurrency:
27 group: ${{ github.workflow }}-${{ github.ref }}
28 cancel-in-progress: false
30jobs:
31 release:
32 runs-on: ubuntu-latest
33 permissions:
34 contents: write # push the tag and create the release
35 id-token: write # OIDC so GitHub can sign the provenance attestation
36 attestations: write # publish the attestation record
37 env:
38 OPENCODE_STORE_BASE64: ${{ secrets.OPENCODE_STORE_BASE64 }}
39 OPENCODE_STORE_PASSWORD: ${{ secrets.OPENCODE_STORE_PASSWORD }}
40 OPENCODE_KEY_ALIAS: ${{ secrets.OPENCODE_KEY_ALIAS }}
41 OPENCODE_KEY_PASSWORD: ${{ secrets.OPENCODE_KEY_PASSWORD }}
42 steps:
43 - uses: actions/checkout@v4
44 with:
45 # Full history so the versionCode (git rev-list --count HEAD) is
46 # accurate instead of collapsing to 1 on a shallow clone.
47 fetch-depth: 0
49 - name: Compute version
50 id: version
51 run: |
52 if [ "${{ github.ref_type }}" = "tag" ]; then
53 VERSION="${GITHUB_REF_NAME#v}"
54 TAG="${GITHUB_REF_NAME}"
55 else
56 VERSION="$(TZ=UTC date +%Y.%m.%d.%H%M)"
57 TAG="v${VERSION}"
58 fi
59 CODE="$(git rev-list --count HEAD)"
60 {
61 echo "version=$VERSION"
62 echo "tag=$TAG"
63 echo "code=$CODE"
64 } >> "$GITHUB_OUTPUT"
65 echo "Releasing $TAG (version $VERSION, code $CODE)"
67 - uses: actions/setup-java@v4
68 with:
69 distribution: temurin
70 java-version: 17
72 - uses: android-actions/setup-android@v3
74 - uses: gradle/actions/setup-gradle@v4
76 # The keystore ships as base64 in a secret so it never touches the repo.
77 # Job-level env makes OPENCODE_STORE_BASE64 available to this `if`.
78 - name: Decode signing keystore
79 if: env.OPENCODE_STORE_BASE64 != ''
80 run: |
81 STORE_FILE="$RUNNER_TEMP/release.keystore"
82 printf '%s' "$OPENCODE_STORE_BASE64" | base64 -d > "$STORE_FILE"
83 echo "OPENCODE_STORE_FILE=$STORE_FILE" >> "$GITHUB_ENV"
85 - name: Build release APK
86 run: |
87 ./gradlew assembleRelease \
88 -PversionName="${{ steps.version.outputs.version }}" \
89 -PversionCode="${{ steps.version.outputs.code }}" \
90 --no-daemon
92 # Rename to a stable, version-tagged filename for the release attachment.
93 - name: Stage APK
94 run: |
95 mkdir -p staging
96 APK="$(find app/build/outputs/apk/release -name '*.apk' | head -n1)"
97 cp "$APK" "staging/opencode-${{ steps.version.outputs.version }}.apk"
99 # Signed build-provenance attestation for the exact artifact being
100 # published; later verifiable with `gh attestation verify <apk>`.
101 - name: Attest build provenance
102 uses: actions/attest-build-provenance@v2
103 with:
104 subject-path: staging/*.apk
106 - name: Create release
107 uses: softprops/action-gh-release@v2
108 with:
109 tag_name: ${{ steps.version.outputs.tag }}
110 name: ${{ steps.version.outputs.version }}
111 make_latest: true
112 generate_release_notes: true
113 files: staging/*.apk