Unified Update System endpoints and SPA button (#43) #37
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release | |
| # Triggers: | |
| # push of a v[MAJOR].[MINOR].[PATCH] tag — full stable release: build | |
| # both arch binaries, assemble rootfs.tar.gz + manifest.json + SHA256SUMS, | |
| # publish a GitHub Release at that tag and mark it latest. | |
| # push to dev — moving prerelease at the "dev-latest" tag. The tag is | |
| # force-recreated to point at the new HEAD; the release is updated | |
| # in-place with new assets. This is what feeders on the dev channel | |
| # resolve via airplanes_webconfig_resolve_dev_latest_tag. | |
| # workflow_dispatch — manual rebuild of dev-latest (rare; for re-pushing | |
| # assets when something goes wrong). | |
| on: | |
| push: | |
| tags: ['v*'] | |
| branches: [dev] | |
| workflow_dispatch: {} | |
| permissions: | |
| contents: read | |
| jobs: | |
| classify: | |
| name: classify release type | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 2 | |
| outputs: | |
| kind: ${{ steps.k.outputs.kind }} | |
| tag: ${{ steps.k.outputs.tag }} | |
| steps: | |
| - id: k | |
| env: | |
| EVENT: ${{ github.event_name }} | |
| REF: ${{ github.ref }} | |
| REF_NAME: ${{ github.ref_name }} | |
| run: | | |
| if [[ "$EVENT" == "push" && "$REF" == refs/tags/* ]]; then | |
| if ! [[ "$REF_NAME" =~ ^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$ ]]; then | |
| echo "::error::Tag '$REF_NAME' does not match v[MAJOR].[MINOR].[PATCH]" | |
| exit 1 | |
| fi | |
| echo "kind=stable" >> "$GITHUB_OUTPUT" | |
| echo "tag=$REF_NAME" >> "$GITHUB_OUTPUT" | |
| elif [[ "$EVENT" == "push" && "$REF" == "refs/heads/dev" ]]; then | |
| echo "kind=dev" >> "$GITHUB_OUTPUT" | |
| echo "tag=dev-latest" >> "$GITHUB_OUTPUT" | |
| elif [[ "$EVENT" == "workflow_dispatch" ]]; then | |
| echo "kind=dev" >> "$GITHUB_OUTPUT" | |
| echo "tag=dev-latest" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "::error::Unsupported trigger: event=$EVENT ref=$REF" | |
| exit 1 | |
| fi | |
| build: | |
| name: cross-compile + package release assets | |
| needs: [classify] | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 15 | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| persist-credentials: false | |
| - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 | |
| with: | |
| go-version-file: go.mod | |
| - name: resolve commit sha | |
| id: sha | |
| # github.sha resolves to the tag-object SHA on annotated tag pushes, | |
| # which would not equal `git rev-parse HEAD` at runtime. Capture the | |
| # commit SHA explicitly so the manifest and ldflags both agree with | |
| # the cloned source HEAD. | |
| run: echo "commit=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" | |
| - name: assemble release (binaries + rootfs.tar.gz + manifest + SHA256SUMS) | |
| env: | |
| TAG: ${{ needs.classify.outputs.tag }} | |
| KIND: ${{ needs.classify.outputs.kind }} | |
| COMMIT_SHA: ${{ steps.sha.outputs.commit }} | |
| run: | | |
| bash scripts/lib/build-release.sh \ | |
| --version "$TAG" \ | |
| --kind "$KIND" \ | |
| --commit-sha "$COMMIT_SHA" \ | |
| --output "$RUNNER_TEMP/release" | |
| - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: release-assets | |
| path: | | |
| ${{ runner.temp }}/release/airplanes-webconfig-arm64 | |
| ${{ runner.temp }}/release/airplanes-webconfig-armhf | |
| ${{ runner.temp }}/release/rootfs.tar.gz | |
| ${{ runner.temp }}/release/manifest.json | |
| ${{ runner.temp }}/release/SHA256SUMS | |
| retention-days: 7 | |
| publish: | |
| name: publish GitHub Release | |
| needs: [classify, build] | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 10 | |
| permissions: | |
| contents: write | |
| # Two updates against the same target must not interleave: a slow older | |
| # run could overwrite a newer release's assets, leaving devices on an | |
| # older binary while the tag points at the newer commit. For dev pushes | |
| # cancel the older in-flight run; for stable tags fail fast on overlap. | |
| concurrency: | |
| group: publish-${{ needs.classify.outputs.tag }} | |
| cancel-in-progress: ${{ needs.classify.outputs.kind == 'dev' }} | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| # The dev path runs `git tag -f` and `git push --force` to move | |
| # dev-latest. Persist the default GITHUB_TOKEN credentials so git | |
| # has push auth without re-encoding the token in a remote URL. | |
| persist-credentials: true | |
| fetch-depth: 0 | |
| - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| name: release-assets | |
| path: dist/ | |
| - name: Verify SHA256SUMS | |
| working-directory: dist | |
| run: sha256sum -c SHA256SUMS | |
| - name: Stable release (tag push) | |
| if: needs.classify.outputs.kind == 'stable' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| TAG: ${{ needs.classify.outputs.tag }} | |
| run: | | |
| if gh release view "$TAG" >/dev/null 2>&1; then | |
| gh release upload "$TAG" --clobber \ | |
| dist/airplanes-webconfig-arm64 \ | |
| dist/airplanes-webconfig-armhf \ | |
| dist/rootfs.tar.gz \ | |
| dist/manifest.json \ | |
| dist/SHA256SUMS | |
| gh release edit "$TAG" --draft=false --latest | |
| else | |
| gh release create "$TAG" --title "$TAG" --generate-notes --latest \ | |
| dist/airplanes-webconfig-arm64 \ | |
| dist/airplanes-webconfig-armhf \ | |
| dist/rootfs.tar.gz \ | |
| dist/manifest.json \ | |
| dist/SHA256SUMS | |
| fi | |
| - name: Dev release (moving dev-latest) | |
| if: needs.classify.outputs.kind == 'dev' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| TAG: dev-latest | |
| SHA: ${{ github.sha }} | |
| run: | | |
| # Force-move dev-latest to point at the current commit and | |
| # rebuild the release in place. Concurrency: cancel-in-progress on | |
| # dev means an older run cannot land after this one. The release | |
| # is marked prerelease so the repo home page still shows the | |
| # latest stable tag as "Latest". | |
| if gh release view "$TAG" >/dev/null 2>&1; then | |
| gh release delete "$TAG" --yes --cleanup-tag | |
| fi | |
| git tag -f "$TAG" "$SHA" | |
| git push origin "refs/tags/$TAG" --force | |
| gh release create "$TAG" \ | |
| --title "dev-latest (${SHA:0:8})" \ | |
| --notes "Moving prerelease for the dev channel. Commit: $SHA" \ | |
| --prerelease \ | |
| dist/airplanes-webconfig-arm64 \ | |
| dist/airplanes-webconfig-armhf \ | |
| dist/rootfs.tar.gz \ | |
| dist/manifest.json \ | |
| dist/SHA256SUMS |