Repository navigation
nostream-website@1.3.4 #44
Workflow file for this run
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 | |
| on: | |
| release: | |
| types: [published] | |
| # A published release is immutable, so a build that fails while publishing it | |
| # cannot be retried by re-publishing the event that triggered it — GitHub | |
| # refuses the draft/publish round trip with `immutable cannot be changed when | |
| # release is immutable`. This is the only path to (re)build an image for a tag | |
| # whose release already exists (#964). | |
| workflow_dispatch: | |
| inputs: | |
| tag: | |
| description: 'Relay release tag to build, e.g. nostream@3.7.0' | |
| required: true | |
| type: string | |
| jobs: | |
| build-and-push-image: | |
| # Changesets tags each workspace package on publish: relay releases tag | |
| # nostream@X.Y.Z, website releases tag nostream-website@X.Y.Z. Only a relay | |
| # tag should build the relay container image. The v* branch is kept for the | |
| # releases cut before the repo moved to changesets tagging. | |
| if: github.event_name == 'workflow_dispatch' || startsWith(github.event.release.tag_name, 'nostream@') || startsWith(github.event.release.tag_name, 'v') | |
| name: Build and push container image | |
| runs-on: ubuntu-latest | |
| env: | |
| REGISTRY: ghcr.io | |
| IMAGE_NAME: ${{ github.repository }} | |
| permissions: | |
| contents: read | |
| packages: write | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v3 | |
| # Build the code the tag names, not the branch the dispatch was started | |
| # from. A release event already carries the tag as GITHUB_REF, so the | |
| # input only overrides it; checking out `main` while pushing the image as | |
| # `3.7.0` would publish the wrong source under a release version. | |
| with: | |
| ref: ${{ inputs.tag && format('refs/tags/{0}', inputs.tag) || github.ref }} | |
| - name: Log in to the Container registry | |
| uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Extract metadata (tags, labels) for Docker | |
| id: meta | |
| uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 | |
| with: | |
| images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} | |
| # The image tags are computed here rather than by metadata-action's rules | |
| # because a changesets relay release is tagged `nostream@3.7.0`, and `@` is | |
| # not legal in a Docker tag: it separates the repository path from a digest | |
| # in an image reference. A `type=ref,event=tag` rule emitted that string | |
| # verbatim, and buildx refused the whole build with `invalid tag ...: | |
| # invalid reference format`, so a published release produced no image at | |
| # all (#964). Nothing in the action's output is legal just because the | |
| # action emitted it, so every tag is checked against Docker's grammar here | |
| # and an illegal one fails by name instead of at buildx. | |
| - name: Compute image tags | |
| id: tags | |
| shell: bash | |
| env: | |
| RELEASE_TAG: ${{ github.event.release.tag_name || inputs.tag }} | |
| PRERELEASE: ${{ github.event.release.prerelease }} | |
| run: | | |
| set -euo pipefail | |
| image="$REGISTRY/$IMAGE_NAME" | |
| # A dispatch has no release flags, so a tag that is not a relay release | |
| # is refused here rather than built: `github.event.release.tag_name` is | |
| # empty, and only this check stands between a typo and a pushed image. | |
| case "$RELEASE_TAG" in | |
| nostream@*|v*) ;; | |
| *) echo "::error::not a relay release tag: '$RELEASE_TAG'"; exit 1 ;; | |
| esac | |
| # `nostream@3.7.0` -> `3.7.0`; the pre-changesets form `v3.4.1` -> `3.4.1`. | |
| version="${RELEASE_TAG##*@}" | |
| version="${version#v}" | |
| tags="$image:$version" | |
| # A legacy `vX.Y.Z` release also keeps the form hosts pinned before the | |
| # changesets migration. A changesets tag has no legal form of its own. | |
| case "$RELEASE_TAG" in | |
| v*) tags="$tags,$image:$RELEASE_TAG" ;; | |
| esac | |
| # `latest` is the tag both deploy stacks pull, so a prerelease must not | |
| # move it onto a test build. A release event states this directly; a | |
| # dispatch does not, so a pre-release version is read from the tag. | |
| prerelease="${PRERELEASE:-}" | |
| if [ -z "$prerelease" ]; then | |
| case "$version" in | |
| *-*) prerelease=true ;; | |
| *) prerelease=false ;; | |
| esac | |
| fi | |
| if [ "$prerelease" != "true" ]; then | |
| tags="$tags,$image:latest" | |
| fi | |
| for tag in ${tags//,/ }; do | |
| name="${tag##*:}" | |
| if ! printf '%s' "$name" | grep -qE '^[A-Za-z0-9_][A-Za-z0-9_.-]{0,127}$'; then | |
| echo "::error::'$name' is not a legal Docker tag (release tag: $RELEASE_TAG)" | |
| exit 1 | |
| fi | |
| done | |
| echo "tags=$tags" >> "$GITHUB_OUTPUT" | |
| echo "publishing: $tags" | |
| - name: Build and push Docker image | |
| uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc | |
| with: | |
| context: . | |
| push: true | |
| tags: ${{ steps.tags.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} |