diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d41f320..0debc3b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -108,7 +108,10 @@ jobs: # it cannot name different versions. series="$(sed -n 's/^plgVersionSeries=//p' gradle.properties)" test -n "$series" - version="v${series}.${{ github.run_number }}-dev" + offset="$(sed -n 's/^plgVersionRunOffset=//p' gradle.properties)" + test -n "$offset" + # Same arithmetic as build.gradle.kts, so the tag names the APK's own number. + version="v${series}.$(( ${{ github.run_number }} + offset ))-dev" src="app/build/outputs/apk/debug/app-debug.apk" dest="ProLibertateGames-${version}.apk" cp "$src" "$dest" @@ -124,27 +127,8 @@ jobs: if-no-files-found: error retention-days: 1 - - name: Publish dev channel prerelease - if: github.ref == 'refs/heads/dev' - env: - GH_TOKEN: ${{ github.token }} - run: | - set -euo pipefail - gh release create "${{ steps.stage.outputs.version }}" \ - "${{ steps.stage.outputs.apk }}" \ - --repo "${{ github.repository }}" \ - --target "${{ github.sha }}" \ - --title "ProLibertateGames ${{ steps.stage.outputs.version }}" \ - --prerelease \ - --notes "Automated **dev channel** build from \`${{ github.sha }}\` on \`dev\`. - - Preview build: newer than production, and less tested. Switch to the - Dev update channel in Settings to be offered these. Marked as a - prerelease so production-channel installs never see it." - - # Publishes the build to https://plg.wallacenet.ca (Cloudflare Pages). Runs - # alongside the GitHub release above for one deployment so already-installed - # apps, which still read GitHub, can fetch the updater that reads Cloudflare. + # Publishes the build to https://plg.wallacenet.ca (Cloudflare Pages), which is + # the only release channel: the in-app updater reads latest.json from there. # # Both workflows deploy into one Pages site, and a deploy replaces the whole # site, so they share a concurrency group and never run at the same time. diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 91260c3..8e9bc93 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -61,7 +61,10 @@ jobs: # it cannot name different versions. series="$(sed -n 's/^plgVersionSeries=//p' gradle.properties)" test -n "$series" - version="v${series}.${{ github.run_number }}" + offset="$(sed -n 's/^plgVersionRunOffset=//p' gradle.properties)" + test -n "$offset" + # Same arithmetic as build.gradle.kts, so the tag names the APK's own number. + version="v${series}.$(( ${{ github.run_number }} + offset ))" src="app/build/outputs/apk/debug/app-debug.apk" dest="ProLibertateGames-${version}.apk" cp "$src" "$dest" @@ -80,28 +83,8 @@ jobs: path: ${{ steps.stage.outputs.apk }} if-no-files-found: error - - name: Create GitHub release - env: - GH_TOKEN: ${{ github.token }} - run: | - set -euo pipefail - gh release create "${{ steps.stage.outputs.version }}" \ - "${{ steps.stage.outputs.apk }}" \ - "ProLibertateGames.apk" \ - --repo "${{ github.repository }}" \ - --target "${{ github.sha }}" \ - --title "ProLibertateGames ${{ steps.stage.outputs.version }}" \ - --notes "Automated release built from \`${{ github.sha }}\` on push to \`main\`. - - Download **${{ steps.stage.outputs.apk }}** below and install it on an Android device (you may need to allow *Install unknown apps*). This is a debug-signed build. - - Both files below are the same build. \`ProLibertateGames.apk\` is a copy under a fixed name, so this link always fetches the newest release and can be bookmarked or shared: - - https://github.com/${{ github.repository }}/releases/latest/download/ProLibertateGames.apk" - - # Publishes the build to https://plg.wallacenet.ca (Cloudflare Pages). Runs - # alongside the GitHub release above for one deployment so already-installed - # apps, which still read GitHub, can fetch the updater that reads Cloudflare. + # Publishes the build to https://plg.wallacenet.ca (Cloudflare Pages), which is + # the only release channel: the in-app updater reads latest.json from there. # # Both workflows deploy into one Pages site, and a deploy replaces the whole # site, so they share a concurrency group and never run at the same time. diff --git a/CLAUDE.md b/CLAUDE.md index 858e8b5..8c4d71d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,3 +1,9 @@ +> **Moved to Gitea.** CI now runs on Gitea Actions at +> `git.wallacenet.ca/devadmin/ProLibertateGames`, publishing to Cloudflare Pages +> (`plg.wallacenet.ca`) only. The sandbox notes below describe the earlier GitHub +> setup (no CI run from session pushes, `workflow_dispatch` as the workaround); +> re-verify them against Gitea before relying on them. + # Working on this repo with Claude ## Nothing a session does triggers CI. Dispatch it explicitly. diff --git a/README.md b/README.md index cd3414f..1f3a454 100644 --- a/README.md +++ b/README.md @@ -218,13 +218,19 @@ Pages → Edit) and `CLOUDFLARE_ACCOUNT_ID`. Pages caps files at 25 MiB. **First deploy:** the site does not exist yet, so the domain answers 403 (Cloudflare error 1014) and the carry-over fetch would abort. Dispatch the workflow once with `first_deploy` ticked, then attach `plg.wallacenet.ca` as a custom domain on the new `plg` Pages project. Later runs need no input. -The in-app updater reads these `latest.json` files. GitHub Releases are still -published for one transition deployment so installs that predate this change can -fetch it; after that, remove the GitHub release steps from both workflows. +The in-app updater reads these `latest.json` files, and this is the only release +channel: the workflows no longer create GitHub or Gitea releases. They run on +Gitea Actions (`https://git.wallacenet.ca/devadmin/ProLibertateGames`); the GitHub +repository is frozen and should stay public with its last releases, because +installs that predate the Cloudflare updater still read them to reach it. + +Build numbers are `run number + plgVersionRunOffset` (1000, in `gradle.properties`), +so moving CI hosts, which restarts run numbers, can never publish a `versionCode` +lower than one already installed. ### Installing without the app -The newest production build is always at **https://plg.wallacenet.ca/prod/ProLibertateGames.apk** (dev: `/dev/ProLibertateGames.apk`). The GitHub link below remains during the transition: +The newest production build is always at **https://plg.wallacenet.ca/prod/ProLibertateGames.apk** (dev: `/dev/ProLibertateGames.apk`). The GitHub link below is the frozen pre-migration release: **https://github.com/adrianoftyriel/ProLibertateGames/releases/latest/download/ProLibertateGames.apk** diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 4a0628f..1e36084 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -16,6 +16,12 @@ val buildChannel = System.getenv("PLG_CHANNEL").orEmpty() val runNumber = (System.getenv("GITHUB_RUN_NUMBER") ?: "").toIntOrNull() ?: 0 val stampVersion = buildChannel.isNotEmpty() && runNumber > 0 +// See plgVersionRunOffset in gradle.properties: the stamped build number is the +// CI run number plus a permanent floor, so a counter that restarts on a new CI +// host can never produce a lower versionCode than one already installed. +val runOffset = (project.findProperty("plgVersionRunOffset") as String?)?.toIntOrNull() ?: 0 +val buildNumber = runNumber + runOffset + // The version series, from gradle.properties. Both workflows read the same // property when they name a release tag, so the tag and the APK inside it // cannot disagree about which series they belong to. @@ -51,10 +57,10 @@ android { // versionCode stays the run number and nothing else, so it keeps // climbing across a change of series: bumping 1.0 to 1.1 must not make // an update look like a downgrade to Android. - versionCode = if (stampVersion) runNumber else 1 + versionCode = if (stampVersion) buildNumber else 1 versionName = when { - stampVersion && buildChannel == "production" -> "$versionSeries.$runNumber" - stampVersion -> "$versionSeries.$runNumber-dev" + stampVersion && buildChannel == "production" -> "$versionSeries.$buildNumber" + stampVersion -> "$versionSeries.$buildNumber-dev" isDevBuild -> "$versionSeries.0-dev" else -> "$versionSeries.0" } diff --git a/gradle.properties b/gradle.properties index 8b173d2..c301034 100644 --- a/gradle.properties +++ b/gradle.properties @@ -23,3 +23,11 @@ android.nonTransitiveRClass=true # it keeps climbing on its own and an APK's versionCode never goes backwards # when this changes. plgVersionSeries=1.4 + +# The permanent floor under every stamped build number: versionCode, versionName +# and the release tag are all `run number + this`. Run numbers restart at 1 on a +# new CI host (Gitea Actions), and Android refuses any versionCode lower than the +# one installed, so without a floor the first build after a move would look like +# a downgrade. 1000 sits above every number GitHub reached (prod 30, dev ~172). +# Set once and never changed. +plgVersionRunOffset=1000