chore(release): prepare CrossGlyph 0.5.1 #10
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: | |
| push: | |
| tags: ["v*"] | |
| permissions: | |
| contents: write # create the release | |
| pages: write # publish the manifest | |
| id-token: write # what deploy-pages authenticates with | |
| packages: write # publish the container image | |
| jobs: | |
| # The gate. A tag is the one push nobody reviews, and it is the one that | |
| # reaches other people, so the suite runs against both platforms before | |
| # anything is built or published. | |
| test: | |
| uses: ./.github/workflows/test.yml | |
| release: | |
| needs: test | |
| runs-on: ubuntu-latest | |
| environment: | |
| name: github-pages | |
| url: ${{ steps.pages.outputs.page_url }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| # The annotation is the release body. Refuse a lightweight tag before | |
| # building or publishing anything, rather than falling back to its | |
| # commit message and calling that release notes. | |
| - name: The tag carries the release notes | |
| run: | | |
| # checkout records github.sha at the tag name, which peels an | |
| # annotated tag to its commit. Fetch the published object itself. | |
| git fetch --force --depth=1 origin \ | |
| "refs/tags/$GITHUB_REF_NAME:refs/tags/$GITHUB_REF_NAME" | |
| if [ "$(git cat-file -t "$GITHUB_REF_NAME")" != tag ]; then | |
| echo "$GITHUB_REF_NAME must be an annotated tag" >&2 | |
| exit 1 | |
| fi | |
| notes="$(git for-each-ref --format='%(contents)' "refs/tags/$GITHUB_REF_NAME")" | |
| if [ -z "$notes" ]; then | |
| echo "$GITHUB_REF_NAME has no release notes" >&2 | |
| exit 1 | |
| fi | |
| - uses: astral-sh/setup-uv@v5 | |
| # The tag is what people install; pyproject.toml is what the tool | |
| # reports as its version. A release where they disagree misdescribes | |
| # itself for as long as it exists, and the manifest built from it points | |
| # at a file named after the other one. | |
| - name: The tag and the version agree | |
| run: | | |
| tagged="${GITHUB_REF_NAME#v}" | |
| declared="$(uv run python -c 'import tomllib, pathlib; print(tomllib.loads(pathlib.Path("pyproject.toml").read_text())["project"]["version"])')" | |
| if [ "$tagged" != "$declared" ]; then | |
| echo "tag $GITHUB_REF_NAME does not match version $declared" >&2 | |
| exit 1 | |
| fi | |
| # Builds the zip and the manifest, and refuses if the archive has lost a | |
| # line ending, an executable bit or a file it cannot run without. | |
| - name: Build the release | |
| run: uv run tools/make-release.py | |
| - uses: docker/setup-qemu-action@v3 | |
| - uses: docker/setup-buildx-action@v3 | |
| - name: Sign in to the GitHub Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Name the container image | |
| id: container | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: ghcr.io/crazycoder/crossglyph | |
| tags: | | |
| type=semver,pattern={{version}} | |
| type=semver,pattern={{major}}.{{minor}} | |
| type=raw,value=latest | |
| - name: Publish the container image | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| platforms: linux/amd64,linux/arm64 | |
| push: true | |
| tags: ${{ steps.container.outputs.tags }} | |
| labels: ${{ steps.container.outputs.labels }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| provenance: mode=max | |
| sbom: true | |
| - name: Publish the release | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: > | |
| gh release create "$GITHUB_REF_NAME" dist/crossglyph-*.zip | |
| --title "$GITHUB_REF_NAME" --verify-tag --notes-from-tag | |
| # Pages serves the manifest: CDN backed and unmetered, where the REST | |
| # API is 60 requests an hour per address and shared behind a NAT. | |
| - name: Stage the manifest | |
| run: mkdir -p site && cp dist/latest.json site/ | |
| - uses: actions/configure-pages@v5 | |
| - uses: actions/upload-pages-artifact@v3 | |
| with: | |
| path: site | |
| - id: pages | |
| uses: actions/deploy-pages@v4 |