release.yml RawHistoryFolder
1name: release
2
3# Every morning at 07:00 Europe/Paris, ermite tags main when its unreleased
4# conventional commits call for a release, then publishes it in the same run (a
5# tag pushed with the job token starts no run). A v* tag pushed by hand also
6# publishes. The GitHub mirror never tags: it receives the forge's tags and
7# publishes a copy, because installed `zut update` only reads GitHub.
8on:
9 schedule:
10 - cron: "0 7 * * *"
11 timezone: Europe/Paris
12 workflow_dispatch:
13 push:
14 tags: ["v*"]
15
16permissions:
17 contents: write
18
19concurrency:
20 group: release
21 cancel-in-progress: false
22
23jobs:
24 tag:
25 if: github.event_name != 'push' && github.server_url != 'https://github.com'
26 runs-on: ubuntu-latest
27 outputs:
28 tag: ${{ steps.version.outputs.tag }}
29 steps:
30 - name: Check out main
31 uses: actions/checkout@v4
32 with:
33 fetch-depth: 0
34 fetch-tags: true
35 ref: main
36
37 - name: Compute the next release tag
38 id: version
39 shell: bash
40 run: |
41 set -euo pipefail
42 if git log -1 --format=%B | grep -Fq '[release=skip]'; then
43 echo "The latest commit requested that the release be skipped."
44 exit 0
45 fi
46 tag=$(bash .github/scripts/next-release-tag.sh)
47 if [ -z "$tag" ]; then
48 echo "No releasable conventional commits for this run."
49 exit 0
50 fi
51 echo "Releasing $tag from $(git rev-parse --short HEAD)"
52 echo "tag=$tag" >> "$GITHUB_OUTPUT"
53
54 - name: Create and push the tag
55 if: steps.version.outputs.tag != ''
56 env:
57 TAG: ${{ steps.version.outputs.tag }}
58 run: |
59 # A retry finds the tag already on HEAD: it is published again as is.
60 if git rev-parse -q --verify "refs/tags/$TAG" >/dev/null; then
61 exit 0
62 fi
63 git config user.name "github-actions[bot]"
64 git config user.email "github-actions[bot]@users.noreply.github.com"
65 git tag -a "$TAG" -m "release $TAG"
66 git push origin "refs/tags/$TAG"
67
68 release:
69 needs: tag
70 # A pushed tag publishes on ermite and on the mirror (the tag job is
71 # skipped there); a scheduled or dispatched run publishes what it tagged.
72 if: >-
73 !cancelled() && needs.tag.result != 'failure' &&
74 (github.event_name == 'push' || needs.tag.outputs.tag != '')
75 runs-on: ubuntu-latest
76 steps:
77 - name: Check out the tag
78 uses: actions/checkout@v4
79 with:
80 fetch-depth: 0
81 ref: ${{ needs.tag.outputs.tag && format('refs/tags/{0}', needs.tag.outputs.tag) || github.ref }}
82
83 - name: Set up Go
84 uses: actions/setup-go@v7
85 with:
86 go-version-file: go.mod
87
88 - name: Run GoReleaser
89 uses: goreleaser/goreleaser-action@v6
90 with:
91 distribution: goreleaser
92 version: "~> v2"
93 args: release --clean
94 env:
95 GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}