name: Release
on:
push:
tags:
- "v*"
workflow_dispatch:
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false
permissions:
contents: read
jobs:
publish:
name: publish to crates.io
runs-on: ubuntu-latest
environment: release
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: dtolnay/rust-toolchain@1.88
- uses: Swatinem/rust-cache@v2
- name: Verify release ref
shell: bash
run: |
set -euo pipefail
version="$(cargo metadata --locked --no-deps --format-version 1 | python3 -c \
'import json,sys; print(json.load(sys.stdin)["packages"][0]["version"])')"
test "$GITHUB_REF_NAME" = "v$version"
git fetch --no-tags origin main
git merge-base --is-ancestor "$GITHUB_SHA" origin/main
- name: Test release package
run: cargo test --locked --all-features
- name: Verify package
run: cargo publish --locked --dry-run
- name: Authenticate with crates.io
id: crates_io
uses: rust-lang/crates-io-auth-action@v1
- name: Publish to crates.io
run: cargo publish --locked
env:
CARGO_REGISTRY_TOKEN: ${{ steps.crates_io.outputs.token }}
github_release:
name: create GitHub release
needs: publish
if: >-
${{ !cancelled() && startsWith(github.ref, 'refs/tags/v')
&& (needs.publish.result == 'success' || github.event_name == 'workflow_dispatch') }}
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Create release if the tag has none
env:
GH_TOKEN: ${{ github.token }}
TAG: ${{ github.ref_name }}
run: |
set -euo pipefail
if gh release view "$TAG" -R "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
echo "$TAG already has a release page; leaving it as published."
exit 0
fi
gh release create "$TAG" -R "$GITHUB_REPOSITORY" \
--verify-tag \
--title "relswap ${TAG#v}" \
--generate-notes