name: Release # Publishes a release with the staged artefacts whenever a tag v* is pushed — # what ./01-release.tag.sh does at its last line. They are staged by # ./02-build-releases.sh, the same script one runs on a laptop, so a local # staging and a published one are the same pipeline. # # turbo-core is a library, so the tag alone already publishes the module: the # proxy serves `go get …@TAG` the moment 01 has run, with or without this # workflow. What this adds is the page a person reads, and an archive of the # tagged source with a checksum to verify it against. # # Rickub runs this as an ordinary GitHub Actions workflow. Two platform facts # matter here: the job's GITHUB_TOKEN is the ONLY credential the release API # (the /gh shim behind $GITHUB_API_URL) accepts — a personal token is refused — # and it is read-only unless the workflow asks for `contents: write` below. # That is why there is no longer a token file to keep out of git. # # No workflow_dispatch on purpose: Rickub's dispatch API fires EVERY # dispatchable workflow of a ref, so a repository should declare at most one. on: push: tags: - "v*" permissions: contents: write concurrency: group: release-${{ github.ref_name }} cancel-in-progress: false jobs: release: name: publish ${{ github.ref_name }} runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 with: # The whole history and the tags: the release notes below are read # from the annotated tag's message, and ./02-build-releases.sh takes # its archive from the commit the tag is on. fetch-depth: 0 - name: Set up Go uses: actions/setup-go@v5 with: go-version-file: go.mod cache: true - name: go test # The suite includes tests that run ./01-release.tag.sh against a # throwaway clone. They skip themselves when they see this, exactly as # they do when the script itself calls make check — without it, a # release job would start a release inside itself. env: TURBO_CORE_RELEASING: "1" run: go test ./... -count=1 - name: Stage the release # release.env is git-ignored, so the tag is passed explicitly and the # script falls back to "Turbo Core " for the description. run: bash ./02-build-releases.sh "${GITHUB_REF_NAME}" - name: Release notes id: notes # The message ./01-release.tag.sh put on the annotated tag (ABOUT in # release.env), then the one line that installs the module and the # links to the documentation AT THAT TAG — a release page is not inside # the repository tree, so a relative path from it 404s, and a link to # the branch would rot as the branch moves. A lightweight tag has no # message: the tag name stands in. run: | set -euo pipefail message="$(git for-each-ref "refs/tags/${GITHUB_REF_NAME}" --format='%(contents)' | sed '/^-----BEGIN PGP SIGNATURE-----/,$d')" if [ -z "$(printf '%s' "${message}" | tr -d '[:space:]')" ]; then message="Turbo Core ${GITHUB_REF_NAME}" fi tree="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/blob/${GITHUB_REF_NAME}" { printf '%s\n\n' "${message}" echo '```bash' echo "go get $(go list -m)@${GITHUB_REF_NAME}" echo '```' echo echo "Documentation: [English](${tree}/docs/en/README.md) · [Français](${tree}/docs/fr/README.md)" echo echo "- Commit: \`${GITHUB_SHA}\`" echo "- Published by the Release workflow, run #${GITHUB_RUN_NUMBER}, with $(go env GOVERSION)" echo echo '## Checksums' echo echo 'The archive below is the tagged source. `go get` does not download it — the module proxy serves the module straight from the tag — so it is here to verify against, and for anyone who cannot reach the proxy.' echo echo '```' cat "release/${GITHUB_REF_NAME}/SHA256SUMS" echo '```' } > "${RUNNER_TEMP}/notes.md" echo "path=${RUNNER_TEMP}/notes.md" >> "$GITHUB_OUTPUT" - name: Keep the artefacts as a run artifact # Downloadable from the run page even if the publish step below fails # (an old CI node that does not forward /gh answers 403 there). uses: actions/upload-artifact@v4 with: name: turbo-core-${{ github.ref_name }} path: release/${{ github.ref_name }}/ if-no-files-found: error retention-days: 14 - name: Publish the release uses: softprops/action-gh-release@v2 with: tag_name: ${{ github.ref_name }} name: ${{ github.ref_name }} body_path: ${{ steps.notes.outputs.path }} draft: false prerelease: ${{ contains(github.ref_name, '-') }} files: | release/${{ github.ref_name }}/turbo-core-*.tar.gz release/${{ github.ref_name }}/SHA256SUMS release/${{ github.ref_name }}/README.md fail_on_unmatched_files: true