super-productivity/.github/workflows/build-android.yml
dependabot[bot] b047f5926f
chore(deps)(deps): bump the github-actions-minor group with 7 updates
Bumps the github-actions-minor group with 7 updates:

| Package | From | To |
| --- | --- | --- |
| [step-security/harden-runner](https://github.com/step-security/harden-runner) | `2.19.4` | `2.20.0` |
| [actions/setup-java](https://github.com/actions/setup-java) | `5.4.0` | `5.5.0` |
| [anthropics/claude-code-action](https://github.com/anthropics/claude-code-action) | `1.0.165` | `1.0.170` |
| [github/codeql-action/init](https://github.com/github/codeql-action) | `4.36.3` | `4.37.0` |
| [github/codeql-action/autobuild](https://github.com/github/codeql-action) | `4.36.3` | `4.37.0` |
| [github/codeql-action/analyze](https://github.com/github/codeql-action) | `4.36.3` | `4.37.0` |
| [actions/stale](https://github.com/actions/stale) | `10.3.0` | `10.4.0` |


Updates `step-security/harden-runner` from 2.19.4 to 2.20.0
- [Release notes](https://github.com/step-security/harden-runner/releases)
- [Commits](9af89fc715...bf7454d06d)

Updates `actions/setup-java` from 5.4.0 to 5.5.0
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](1bcf9fb12c...0f481fcb61)

Updates `anthropics/claude-code-action` from 1.0.165 to 1.0.170
- [Release notes](https://github.com/anthropics/claude-code-action/releases)
- [Commits](558b1d6cab...536f2c32a3)

Updates `github/codeql-action/init` from 4.36.3 to 4.37.0
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](54f647b7e1...99df26d4f1)

Updates `github/codeql-action/autobuild` from 4.36.3 to 4.37.0
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](54f647b7e1...99df26d4f1)

Updates `github/codeql-action/analyze` from 4.36.3 to 4.37.0
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](54f647b7e1...99df26d4f1)

Updates `actions/stale` from 10.3.0 to 10.4.0
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](eb5cf3af3a...1e223db275)

---
updated-dependencies:
- dependency-name: step-security/harden-runner
  dependency-version: 2.20.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions-minor
- dependency-name: actions/setup-java
  dependency-version: 5.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions-minor
- dependency-name: anthropics/claude-code-action
  dependency-version: 1.0.170
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions-minor
- dependency-name: github/codeql-action/init
  dependency-version: 4.37.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions-minor
- dependency-name: github/codeql-action/autobuild
  dependency-version: 4.37.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions-minor
- dependency-name: github/codeql-action/analyze
  dependency-version: 4.37.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions-minor
- dependency-name: actions/stale
  dependency-version: 10.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-13 07:15:14 +00:00

199 lines
8.8 KiB
YAML

name: Create android Play Store APK
on:
push:
branches: [master, release/*, test/git-actions]
tags:
- v*
workflow_dispatch:
inputs: {}
permissions:
contents: write
# Per-ref so rapid non-tag master pushes supersede each other (newest dev build
# wins). Groups are keyed by ref, so a master push can never cancel a `v*` tag
# release build (different ref = different group).
concurrency:
group: build-android-${{ github.ref }}
cancel-in-progress: true
jobs:
build-android:
runs-on: ubuntu-latest
env:
UNSPLASH_KEY: ${{ secrets.UNSPLASH_KEY }}
UNSPLASH_CLIENT_ID: ${{ secrets.UNSPLASH_CLIENT_ID }}
steps:
- name: Checkout sources
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v6
with:
# Full commit/tag graph (blobless, so cheap) is needed to derive the
# per-push dev versionCode from the last stable tag.
fetch-depth: 0
filter: blob:none
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version: 22
- name: Setup Java
uses: actions/setup-java@0f481fcb613427c0f801b606911222b5b6f3083a # v5
with:
distribution: 'temurin'
java-version: 21
- name: Setup Gradle
uses: gradle/actions/setup-gradle@3f131e8634966bd73d06cc69884922b02e6faf92 # v6.2.0
# - name: Build with Gradle
# run: ./gradlew build
- name: Setup android-sdk
uses: android-actions/setup-android@40fd30fb8d7440372e1316f5d1809ec01dcd3699 # v4.0.1
with:
accept-android-sdk-licenses: true
log-accepted-android-sdk-licenses: true #make accepting the android sdk license verbose
packages: 'platform-tools platforms;android-36 build-tools;35.0.0'
- name: Get npm cache directory
id: npm-cache-dir
run: |
echo "dir=$(npm config get cache)" >> $GITHUB_OUTPUT
- uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v5
id: npm-cache # use this to check for `cache-hit` ==> if: steps.npm-cache.outputs.cache-hit != 'true'
with:
path: ${{ steps.npm-cache-dir.outputs.dir }}
key: ${{ runner.os }}-node22-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node22-
- name: Install npm Packages
# if: steps.npm-cache.outputs.cache-hit != 'true'
run: npm i
- name: Decode Keystore
env:
RELEASE_KEYSTORE_PASSWORD: ${{ secrets.DROID_KEYSTORE_PASSWORD }}
RELEASE_KEYSTORE_ALIAS: ${{ secrets.DROID_KEYSTORE_ALIAS }}
RELEASE_KEY_PASSWORD: ${{ secrets.DROID_KEY_PASSWORD }}
run: |
echo "${{ secrets.DROID_KEYSTORE_BASE_64 }}" | base64 --decode > keystore.jks
# --- Per-push dev build (non-tag master pushes only) --------------------
# On plain master pushes the release-signed APK is otherwise artifact-only;
# here we stamp it with a dev versionCode and (after Build) ship it to the
# Play `internal` track so a fresh build auto-updates on the phone. All
# steps are gated to refs/heads/master (non-tag), so the tag/release path
# is untouched. Nothing is committed — the versionCode is only sed'd into
# the working copy of build.gradle at build time.
- name: Compute dev versionCode
id: devvc
# Dev distribution must never redden the release-critical build; on any
# failure the downstream gates read '' and simply skip.
continue-on-error: true
if: github.ref == 'refs/heads/master'
run: node tools/android-dev-version-code.js
- name: Apply dev versionCode
id: applyvc
# continue-on-error: a dev-versioning hiccup must never break the
# release-critical build; on failure `applied` stays unset and the Play
# upload below is skipped (the artifact build still succeeds).
continue-on-error: true
if: github.ref == 'refs/heads/master' && steps.devvc.outputs.skip == 'false'
env:
CODE: ${{ steps.devvc.outputs.code }}
run: |
set -euo pipefail
sed -i -E "s/versionCode [0-9_]+/versionCode ${CODE}/" android/app/build.gradle
grep -qE "versionCode ${CODE}( |$)" android/app/build.gradle \
|| { echo "::error::versionCode override did not apply"; exit 1; }
grep -nE 'versionCode [0-9_]+' android/app/build.gradle
echo "applied=true" >> "$GITHUB_OUTPUT"
- name: Build
run: npm run dist:android:prod
env:
RELEASE_KEYSTORE_PASSWORD: ${{ secrets.DROID_KEYSTORE_PASSWORD }}
RELEASE_KEYSTORE_ALIAS: ${{ secrets.DROID_KEYSTORE_ALIAS }}
RELEASE_KEY_PASSWORD: ${{ secrets.DROID_KEY_PASSWORD }}
- name: DEBUG
run: |
ls -la android/app/build/outputs
ls -la android/app/build/outputs/apk
ls -la android/app/build/outputs/apk/play
ls -la android/app/build/outputs/apk/play/release
# APK is now signed automatically by Gradle using signingConfig
- name: 'Upload APK files'
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: sup-android-release
path: android/app/build/outputs/apk/**/*.apk
# Ship the dev-versioned APK to the Play `internal` track (non-tag master
# pushes only, and only when the versionCode was actually applied). This is
# the same track the tag build stages real releases on below; dev builds
# (code base+1..999) and releases (base+9000) stay distinct by versionCode,
# so they interleave on the track without colliding. Chosen over a closed
# track because internal testing skips review, so builds land in minutes.
- name: Upload dev build to Play (internal track)
# continue-on-error: re-runs (same commit -> same versionCode, which Play
# rejects as already used), the post-release window (a just-tagged release
# has a higher code on this track until the tag propagates to the dev
# step — closed by `git push --follow-tags`), and transient Play API
# errors must not fail the release-critical workflow.
continue-on-error: true
if: github.ref == 'refs/heads/master' && steps.applyvc.outputs.applied == 'true'
uses: r0adkll/upload-google-play@e738b9dd8f2476ea806d921b64aacd24f34515a5 # v1.1.5
with:
serviceAccountJsonPlainText: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_JSON }}
packageName: com.superproductivity.superproductivity
releaseFiles: android/app/build/outputs/apk/play/release/*.apk
releaseName: 'dev ${{ steps.devvc.outputs.code }} (${{ steps.devvc.outputs.sha }})'
tracks: internal
status: completed
- name: Wait for main release to be created
if: startsWith(github.ref, 'refs/tags/v')
run: |
echo "Waiting for main release to be created..."
for i in {1..40}; do
if gh release view ${{ github.ref_name }} --repo ${{ github.repository }} >/dev/null 2>&1; then
echo "Release found!"
break
fi
echo "Waiting for release... (attempt $i/40)"
sleep 30
done
# Fail if release still doesn't exist
if ! gh release view ${{ github.ref_name }} --repo ${{ github.repository }} >/dev/null 2>&1; then
echo "ERROR: Release ${{ github.ref_name }} was not created after 20 minutes"
exit 1
fi
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload APK to existing GitHub Release
if: startsWith(github.ref, 'refs/tags/v')
run: |
for apk in android/app/build/outputs/apk/play/release/*.apk; do
if [ -f "$apk" ]; then
echo "Uploading $apk to release ${{ github.ref_name }}"
gh release upload ${{ github.ref_name }} "$apk" --repo ${{ github.repository }}
fi
done
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Prepare Google Play release notes
if: startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '-')
run: npm run release-notes:prepare-play-store
- name: Upload to Google Play Console
if: startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '-')
uses: r0adkll/upload-google-play@e738b9dd8f2476ea806d921b64aacd24f34515a5 # v1.1.5
with:
serviceAccountJsonPlainText: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_JSON }}
packageName: com.superproductivity.superproductivity
releaseFiles: android/app/build/outputs/apk/play/release/*.apk
tracks: internal
status: completed
inAppUpdatePriority: 2
whatsNewDirectory: build/generated-release-notes/play-store