name: Release
on:
push:
tags: ["v*"]
permissions:
contents: read
jobs:
ci:
uses: ./.github/workflows/ci.yml
version:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: The tag matches the crate version
run: |
version=$(sed -n '/^\[package\]/,/^\[/ s/^version = "\(.*\)"/\1/p' Cargo.toml)
[[ $GITHUB_REF_NAME == "v$version" ]] ||
{ echo "::error::tag $GITHUB_REF_NAME, but Cargo.toml is at $version"; exit 1; }
- name: CHANGELOG.md has a section for the tag
run: |
grep -qF "## [${GITHUB_REF_NAME#v}]" CHANGELOG.md ||
{ echo "::error::CHANGELOG.md has no section for ${GITHUB_REF_NAME#v}"; exit 1; }
crates:
needs: [ci, version]
runs-on: ubuntu-latest
environment: release
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
- name: Skip a version already on crates.io
id: published
run: |
version=$(sed -n '/^\[package\]/,/^\[/ s/^version = "\(.*\)"/\1/p' Cargo.toml)
if curl -sf https://index.crates.io/gs/ic/gsichtl |
jq -e --arg v "$version" 'select(.vers == $v)' >/dev/null; then
echo "::notice::gsichtl@$version is already on crates.io"
echo "skip=true" >>"$GITHUB_OUTPUT"
fi
- uses: rust-lang/crates-io-auth-action@v1
if: steps.published.outputs.skip != 'true'
id: auth
- run: cargo publish --locked
if: steps.published.outputs.skip != 'true'
env:
CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
github:
needs: crates
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v7
- name: Release notes from CHANGELOG.md
run: |
awk -v head="## [${GITHUB_REF_NAME#v}]" '
index($0, head) == 1 { inside = 1; next }
inside && /^## \[/ { exit }
inside { print }
' CHANGELOG.md >notes.md
cat notes.md
- name: Publish the GitHub release
env:
GH_TOKEN: ${{ github.token }}
run: |
if gh release view "$GITHUB_REF_NAME" >/dev/null 2>&1; then
echo "::notice::the GitHub release $GITHUB_REF_NAME already exists"
else
gh release create "$GITHUB_REF_NAME" --verify-tag \
--title "gsichtl ${GITHUB_REF_NAME#v}" --notes-file notes.md
fi