beta release #79
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: beta release | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: "Immutable prerelease tag, for example v0.128.0-beta.1" | |
| required: true | |
| type: string | |
| permissions: | |
| contents: write | |
| packages: write | |
| concurrency: | |
| group: beta-${{ inputs.version }} | |
| cancel-in-progress: false | |
| jobs: | |
| tag: | |
| name: validate and anchor beta tag | |
| runs-on: ubuntu-latest | |
| outputs: | |
| version: ${{ steps.version.outputs.version }} | |
| state_schema: ${{ steps.version.outputs.state_schema }} | |
| steps: | |
| - name: Checkout selected commit | |
| uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 0 | |
| - name: Validate and create immutable tag | |
| id: version | |
| env: | |
| TAG: ${{ inputs.version }} | |
| run: | | |
| set -euo pipefail | |
| if [[ ! "${TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+-beta\.[0-9]+$ ]]; then | |
| echo "version must match vX.Y.Z-beta.N" >&2 | |
| exit 1 | |
| fi | |
| PACKAGE_VERSION="$(node -p "require('./package.json').version")" | |
| BASE_VERSION="${TAG#v}" | |
| BASE_VERSION="${BASE_VERSION%-beta.*}" | |
| if [ "${BASE_VERSION}" != "${PACKAGE_VERSION}" ]; then | |
| echo "${TAG} does not match package.json version ${PACKAGE_VERSION}" >&2 | |
| exit 1 | |
| fi | |
| STATE_SCHEMA="$(node -p "require('./state-schema.json').version")" | |
| if [[ ! "${STATE_SCHEMA}" =~ ^[1-9][0-9]*$ ]]; then | |
| echo "state-schema.json must contain a positive integer version" >&2 | |
| exit 1 | |
| fi | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| if git ls-remote --exit-code --tags origin "refs/tags/${TAG}" >/dev/null 2>&1; then | |
| git fetch --force origin "refs/tags/${TAG}:refs/tags/${TAG}" | |
| TAG_COMMIT="$(git rev-list -n 1 "${TAG}")" | |
| if [ "${TAG_COMMIT}" != "${GITHUB_SHA}" ]; then | |
| echo "${TAG} already points to ${TAG_COMMIT}, not ${GITHUB_SHA}" >&2 | |
| exit 1 | |
| fi | |
| else | |
| git tag -a "${TAG}" -m "Beta release ${TAG}" "${GITHUB_SHA}" | |
| git push origin "refs/tags/${TAG}" | |
| fi | |
| echo "version=${TAG}" >> "${GITHUB_OUTPUT}" | |
| echo "state_schema=${STATE_SCHEMA}" >> "${GITHUB_OUTPUT}" | |
| docker: | |
| name: beta docker (${{ matrix.target }}) | |
| runs-on: ubuntu-latest | |
| needs: tag | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - target: main | |
| dockerfile: ./Dockerfile | |
| image_suffix: "" | |
| - target: updater | |
| dockerfile: ./Dockerfile.updater | |
| image_suffix: "-updater" | |
| steps: | |
| - name: Checkout beta tag | |
| uses: actions/checkout@v5 | |
| with: | |
| ref: ${{ needs.tag.outputs.version }} | |
| # drivers/ is gitignored and fetched from the commit pinned in | |
| # drivers/BUNDLED_SOURCE.json. The image copies it, so it has to exist | |
| # in the build context before buildx runs. | |
| - name: Fetch the bundled drivers | |
| run: make drivers | |
| - name: Set up QEMU | |
| uses: docker/setup-qemu-action@v3 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v4 | |
| - name: Login to canonical GHCR namespace | |
| uses: docker/login-action@v4.5.2 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ vars.SOURCEFUL_GHCR_USER || github.actor }} | |
| password: ${{ secrets.SOURCEFUL_GHCR_TOKEN || secrets.GITHUB_TOKEN }} | |
| - name: Build and publish beta image | |
| id: build | |
| uses: docker/build-push-action@v7 | |
| with: | |
| context: . | |
| file: ${{ matrix.dockerfile }} | |
| platforms: linux/amd64,linux/arm64 | |
| push: true | |
| tags: | | |
| ghcr.io/srcfl/ftw${{ matrix.image_suffix }}:${{ needs.tag.outputs.version }} | |
| ghcr.io/srcfl/ftw${{ matrix.image_suffix }}:beta | |
| labels: | | |
| org.opencontainers.image.source=https://github.com/srcfl/ftw | |
| org.opencontainers.image.revision=${{ github.sha }} | |
| org.opencontainers.image.version=${{ needs.tag.outputs.version }} | |
| org.opencontainers.image.licenses=Apache-2.0 | |
| build-args: | | |
| VERSION=${{ needs.tag.outputs.version }} | |
| BUILD_SHA=${{ github.sha }} | |
| # Reuse the same content-addressed layers as stable. | |
| cache-from: type=gha,scope=${{ matrix.target }} | |
| cache-to: type=gha,mode=max,scope=${{ matrix.target }} | |
| - name: Login to compatibility GHCR namespace | |
| uses: docker/login-action@v4.5.2 | |
| with: | |
| registry: ghcr.io | |
| username: frahlg | |
| password: ${{ secrets.LEGACY_GHCR_TOKEN || secrets.GITHUB_TOKEN }} | |
| - name: Mirror exact beta manifests to compatibility namespace | |
| env: | |
| IMAGE_SUFFIX: ${{ matrix.image_suffix }} | |
| SOURCE_DIGEST: ${{ steps.build.outputs.digest }} | |
| VERSION: ${{ needs.tag.outputs.version }} | |
| run: | | |
| set -euo pipefail | |
| test -n "${SOURCE_DIGEST}" | |
| for tag in "${VERSION}" beta; do | |
| source="ghcr.io/srcfl/ftw${IMAGE_SUFFIX}:${tag}" | |
| legacy="ghcr.io/frahlg/forty-two-watts${IMAGE_SUFFIX}:${tag}" | |
| docker buildx imagetools create --prefer-index=false --tag "${legacy}" "${source}" | |
| legacy_digest="$(scripts/inspect-image-digest.sh "${legacy}")" | |
| test "${SOURCE_DIGEST}" = "${legacy_digest}" | |
| done | |
| release: | |
| name: publish GitHub prerelease | |
| runs-on: ubuntu-latest | |
| needs: [tag, docker] | |
| steps: | |
| - name: Publish prerelease after images are available | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| TAG: ${{ needs.tag.outputs.version }} | |
| STATE_SCHEMA: ${{ needs.tag.outputs.state_schema }} | |
| run: | | |
| set -euo pipefail | |
| if gh release view "${TAG}" --repo "${GITHUB_REPOSITORY}" >/dev/null 2>&1; then | |
| echo "GitHub prerelease ${TAG} already exists" | |
| exit 0 | |
| fi | |
| gh release create "${TAG}" \ | |
| --repo "${GITHUB_REPOSITORY}" \ | |
| --title "${TAG}" \ | |
| --prerelease \ | |
| --notes "<!-- ftw-state-schema:${STATE_SCHEMA} -->" \ | |
| --generate-notes |