diff --git a/.github/workflows/build-addon.yaml b/.github/workflows/build-addon.yaml index 7d1a5e8..212ea17 100644 --- a/.github/workflows/build-addon.yaml +++ b/.github/workflows/build-addon.yaml @@ -53,6 +53,39 @@ jobs: version=$(grep '^version:' panelbench/config.yaml | sed 's/version: *"\(.*\)"/\1/') echo "version=${version}" >> "$GITHUB_OUTPUT" + # `:latest` is what an unversioned pull gets, so only main moves it. A build + # dispatched from any other ref, a pre-release branch above all, publishes its + # version tag alone. + # + # That version tag is what an installed add-on pulls, so only main may build a + # stable version. A pre-release branch is cut while config.yaml still names the + # last release, and a dispatch from it before the bump would overwrite that + # release's image under every installation; it is refused instead. + - name: Check the version and choose image tags + id: tags + env: + IMAGE: ${{ env.REGISTRY }}/spanpanel/panelbench/${{ matrix.arch }} + VERSION: ${{ steps.version.outputs.version }} + run: | + stable='^[0-9]+\.[0-9]+\.[0-9]+$' + prerelease='^[0-9]+\.[0-9]+\.[0-9]+(a|b|rc)[0-9]+$' + if [[ ! "${VERSION}" =~ ${stable} && ! "${VERSION}" =~ ${prerelease} ]]; then + echo "::error::panelbench/config.yaml declares version '${VERSION}', which is neither X.Y.Z nor a pre-release such as X.Y.ZbN." + exit 1 + fi + if [ "${GITHUB_REF}" != "refs/heads/main" ] && [[ ! "${VERSION}" =~ ${prerelease} ]]; then + echo "::error::${GITHUB_REF} declares the stable version ${VERSION}, which only main may build. Bump panelbench/config.yaml to a pre-release version such as X.Y.ZbN first." + exit 1 + fi + { + echo "tags<> "$GITHUB_OUTPUT" + - name: Build and push uses: docker/build-push-action@v7 with: @@ -62,6 +95,4 @@ jobs: push: true build-args: | BUILD_FROM=${{ matrix.base }} - tags: | - ${{ env.REGISTRY }}/spanpanel/panelbench/${{ matrix.arch }}:${{ steps.version.outputs.version }} - ${{ env.REGISTRY }}/spanpanel/panelbench/${{ matrix.arch }}:latest + tags: ${{ steps.tags.outputs.tags }} diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 1325617..52c3987 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -2,14 +2,14 @@ name: Lint & Type Check on: pull_request: - branches: [main] + branches: [main, "prerelease/**"] # Also on push, because pull_request alone leaves `main` unwatched. The mypy hook # was broken from the moment the emitter stopped being vendored and stayed broken # across several pushes, all of them reporting green — the only workflow running on # push was the add-on image build. The breakage surfaced on the next unrelated # dependabot PR, which is a confusing place to learn about it. push: - branches: [main] + branches: [main, "prerelease/**"] jobs: lint: diff --git a/.github/workflows/spec-provenance.yaml b/.github/workflows/spec-provenance.yaml index 833c2d1..a76e145 100644 --- a/.github/workflows/spec-provenance.yaml +++ b/.github/workflows/spec-provenance.yaml @@ -10,7 +10,7 @@ name: Spec Provenance on: pull_request: - branches: [main] + branches: [main, "prerelease/**"] paths: - ".ebus-spec.json" # Where the vendored catalogs actually are. This filter named diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index f304b59..1bce3ed 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -15,9 +15,9 @@ name: Tests on: pull_request: - branches: [main] + branches: [main, "prerelease/**"] push: - branches: [main] + branches: [main, "prerelease/**"] jobs: test: