name: Release
on:
push:
tags:
- 'v*'
permissions:
contents: write
env:
AXONFLOW_TELEMETRY: 'off'
CARGO_TERM_COLOR: always
jobs:
preflight:
name: Preflight (CHANGELOG)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Extract CHANGELOG section for tag
run: |
VERSION="${GITHUB_REF#refs/tags/v}"
awk -v ver="$VERSION" '$0 ~ "^## \\["ver"\\]" {p=1; next} p && /^## \[/ {exit} p {print}' CHANGELOG.md > /tmp/release-body.md
if [ ! -s /tmp/release-body.md ]; then
echo "::error::No CHANGELOG.md section found for version $VERSION — refusing to publish."
echo "::error::Add a '## [$VERSION] - YYYY-MM-DD' section to CHANGELOG.md and re-tag."
exit 1
fi
{
echo "## AxonFlow Rust SDK v${VERSION}"
echo ""
echo "### Installation"
echo ""
echo '```toml'
echo "[dependencies]"
echo "axonflow-sdk-rust = \"${VERSION}\""
echo '```'
echo ""
echo "### Documentation"
echo ""
echo "- [docs.rs](https://docs.rs/axonflow-sdk-rust/${VERSION})"
echo "- [README](https://github.com/getaxonflow/axonflow-sdk-rust#readme)"
echo "- [Examples](https://github.com/getaxonflow/axonflow-sdk-rust/tree/main/examples)"
echo ""
cat /tmp/release-body.md
} > /tmp/release-body-final.md
echo "Release body: $(wc -l < /tmp/release-body-final.md) lines"
- name: Verify Cargo.toml version matches tag
run: |
VERSION="${GITHUB_REF#refs/tags/v}"
CARGO_VERSION=$(awk -F'"' '/^version *=/ {print $2; exit}' Cargo.toml)
if [ "$VERSION" != "$CARGO_VERSION" ]; then
echo "::error::Tag v${VERSION} does not match Cargo.toml version ${CARGO_VERSION}."
echo "::error::Bump Cargo.toml to ${VERSION} and re-tag."
exit 1
fi
- uses: actions/upload-artifact@v7
with:
name: release-body
path: /tmp/release-body-final.md
retention-days: 1
test:
name: Test (release)
needs: preflight
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- run: cargo test --all-features
- run: cargo build --examples
release:
name: Create GitHub Release
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/download-artifact@v8
with:
name: release-body
path: /tmp/release-body
- name: Create Release
uses: softprops/action-gh-release@v3
with:
name: Release ${{ github.ref_name }}
body_path: /tmp/release-body/release-body-final.md
generate_release_notes: false
draft: false
prerelease: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
publish-cratesio:
name: Publish to crates.io
needs: release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Verify CARGO_REGISTRY_TOKEN secret is configured
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: |
if [ -z "$CARGO_REGISTRY_TOKEN" ]; then
echo "::error::CARGO_REGISTRY_TOKEN secret is not set."
echo "::error::Generate a publish token at https://crates.io/me and add it as a repo secret."
exit 1
fi
- name: cargo publish
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: cargo publish
- name: Wait for crates.io propagation
run: sleep 30
- name: Verify version is live on crates.io
run: |
VERSION="${GITHUB_REF#refs/tags/v}"
curl -sf "https://crates.io/api/v1/crates/axonflow-sdk-rust/${VERSION}" > /dev/null \
|| { echo "::error::axonflow-sdk-rust@${VERSION} not found on crates.io after publish."; exit 1; }
echo "✅ axonflow-sdk-rust@${VERSION} is live on crates.io"