name: Publish Release
on:
workflow_dispatch: {}
permissions:
contents: write
jobs:
publish:
name: Tag, publish to crates.io, and create GitHub Release
runs-on: ubuntu-latest
environment: release
permissions:
contents: write
id-token: write env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CRATES_IO_UA: "serde_json_bytes-release (github.com/apollographql/serde_json_bytes)"
steps:
- uses: actions/checkout@v4
with:
ref: main
fetch-depth: 0
- name: Read version from Cargo.toml
id: version
run: |
version=$(grep -m1 '^version = ' Cargo.toml | sed -E 's/^version = "(.*)"$/\1/')
echo "version=$version" >> "$GITHUB_OUTPUT"
echo "Publishing version: $version"
- name: Reject if this version is already published on crates.io
env:
VERSION: ${{ steps.version.outputs.version }}
run: |
# Check the status code explicitly rather than relying on curl's exit
# status: anything other than a clean 404 must block the release, so
# that a transient error or a rejected request can't read as "not
# published yet" and let the publish proceed.
code=$(curl -sS -o /dev/null -w '%{http_code}' \
-H "User-Agent: $CRATES_IO_UA" \
"https://crates.io/api/v1/crates/serde_json_bytes/$VERSION")
case "$code" in
404)
echo "$VERSION is not yet published on crates.io — proceeding."
;;
200)
echo "::error::serde_json_bytes $VERSION is already published on crates.io."
exit 1
;;
*)
echo "::error::Unexpected status $code from crates.io while checking whether $VERSION is published."
exit 1
;;
esac
- name: Create and push tag
run: |
# Force-create/push: a previous run may have already tagged this commit
# before failing at a later step (e.g. cargo publish). That's fine as
# long as the version above isn't actually live on crates.io yet.
# (Lightweight tag, so no git identity/config needed here.)
git tag -f "${{ steps.version.outputs.version }}"
git push --force origin "refs/tags/${{ steps.version.outputs.version }}"
- name: Authenticate with crates.io (Trusted Publishing)
uses: rust-lang/crates-io-auth-action@v1
id: auth
- name: Publish to crates.io
run: cargo publish -p serde_json_bytes
env:
CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
- name: Create GitHub Release
run: |
gh release create "${{ steps.version.outputs.version }}" \
--title "${{ steps.version.outputs.version }}" \
--generate-notes