Publish the dev channel from any build of dev, not only a push
The dev prerelease steps were gated on the event as well as the branch, so a manual run from the Actions tab built, tested and linted dev and then skipped the publish. That matters because a push does not always fire the workflow: anything pushed by an automation token is suppressed by GitHub's own recursion guard, which leaves the dev channel stuck on an older build with no way to move it from the Actions tab. Gated on the branch alone now, which is how release.yml has always gated main — the inconsistency was between the two pipelines, not a deliberate rule. Nothing about the safety property changes: publishing still only happens after the same job has built, tested and linted clean, and a pull request is still excluded without being named, because a PR build runs against refs/pull/N/merge and never refs/heads/dev. PLG_CHANNEL moves to the same condition, which is the part that would bite if it were missed. It decides whether the APK is stamped with its run number, and the publish steps decide whether that APK ships. Leave them out of step and the dev channel gets an APK claiming versionCode 1 — an "update" the installed app can never see as newer than what it already has. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_015pyhC1KyFkQk6hUnnX2Tof
This commit is contained in:
@@ -31,10 +31,17 @@ jobs:
|
||||
name: Build and check
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
# Stamp the APK as a dev-channel build only when this is a real push to
|
||||
# dev. Pull request builds stay unstamped at 1.0.0-dev, since they are
|
||||
# never published and must not claim a channel version.
|
||||
PLG_CHANNEL: ${{ (github.event_name == 'push' && github.ref == 'refs/heads/dev') && 'dev' || '' }}
|
||||
# Stamp the APK as a dev-channel build exactly when it is a build of the
|
||||
# dev branch, which is exactly when it can be published below. Pull
|
||||
# request builds run against refs/pull/N/merge, so they stay unstamped at
|
||||
# 1.0.0-dev: they are never published and must not claim a channel
|
||||
# version.
|
||||
#
|
||||
# This condition has to stay in step with the publish steps' own. Stamping
|
||||
# a build the publish steps would ship, or shipping one this left
|
||||
# unstamped, both end the same way — an APK claiming versionCode 1, which
|
||||
# the updater can never see as an upgrade over anything.
|
||||
PLG_CHANNEL: ${{ github.ref == 'refs/heads/dev' && 'dev' || '' }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
@@ -77,11 +84,16 @@ jobs:
|
||||
if-no-files-found: ignore
|
||||
retention-days: 14
|
||||
|
||||
# Everything below publishes the dev channel, and only ever from a push
|
||||
# to dev that has already built, tested and linted clean above.
|
||||
# Everything below publishes the dev channel, and only ever from the dev
|
||||
# branch itself, after it has built, tested and linted clean above.
|
||||
#
|
||||
# Gated on the branch alone rather than on the event, which is how
|
||||
# release.yml has always gated main. A pull request is still excluded
|
||||
# without needing to name it: a PR build runs against refs/pull/N/merge,
|
||||
# never refs/heads/dev, so a fork still cannot ship anything.
|
||||
- name: Stage dev APK
|
||||
id: stage
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/dev'
|
||||
if: github.ref == 'refs/heads/dev'
|
||||
run: |
|
||||
set -euo pipefail
|
||||
version="v1.0.${{ github.run_number }}-dev"
|
||||
@@ -92,7 +104,7 @@ jobs:
|
||||
echo "apk=$dest" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Publish dev channel prerelease
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/dev'
|
||||
if: github.ref == 'refs/heads/dev'
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
|
||||
@@ -139,15 +139,28 @@ Both pipelines publish, to two separate channels:
|
||||
| Channel | Published by | Tag | Marked |
|
||||
| --- | --- | --- | --- |
|
||||
| Production | `release.yml`, push to `main` | `v1.0.<n>` | release |
|
||||
| Dev | `ci.yml`, push to `dev` | `v1.0.<n>-dev` | prerelease |
|
||||
| Dev | `ci.yml`, any build of `dev` | `v1.0.<n>-dev` | prerelease |
|
||||
|
||||
Dev builds are published as **prereleases** deliberately: GitHub's "latest
|
||||
release" endpoint skips prereleases, so a production-channel install can never
|
||||
be handed a dev build even by accident. Pull requests build and check but never
|
||||
publish, so a PR from a fork cannot ship anything.
|
||||
|
||||
`release.yml` additionally refuses to run off any branch but `main`, so a manual
|
||||
dispatch aimed elsewhere does nothing rather than shipping unreviewed code.
|
||||
**Both pipelines gate publishing on the branch rather than on what triggered
|
||||
the build**, so a manual run from the Actions tab publishes exactly as a push
|
||||
does — useful when a push cannot fire the workflow itself, which is the case
|
||||
for anything pushed by an automation token. The safety property is unchanged,
|
||||
because publishing still happens only after that same job has built, tested and
|
||||
linted clean. A pull request is still excluded without having to be named: a PR
|
||||
build runs against `refs/pull/<n>/merge`, never `refs/heads/dev`.
|
||||
|
||||
In `ci.yml` the `PLG_CHANNEL` stamp is gated on the same condition as the
|
||||
publish steps, and the two have to stay in step. Stamping a build that then
|
||||
ships, or shipping one that was left unstamped, both end with an APK claiming
|
||||
`versionCode` 1 — which the updater can never see as an upgrade over anything.
|
||||
|
||||
`release.yml` refuses to run off any branch but `main`, so a manual dispatch
|
||||
aimed elsewhere does nothing rather than shipping unreviewed code.
|
||||
|
||||
**The two channels have independent version sequences** — a build's `versionCode`
|
||||
is the run number of the workflow that produced it, and the two workflows count
|
||||
|
||||
Reference in New Issue
Block a user