name: Release
on:
workflow_dispatch:
inputs:
version:
description: 'Version to release (e.g., 0.3.0)'
required: true
type: string
dry_run:
description: 'Dry run (skip publish and tag)'
required: false
type: boolean
default: false
env:
RUST_VERSION: 1.90.0
jobs:
release:
name: Release weavegraph
runs-on: ubuntu-latest
permissions:
actions: read
contents: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Ensure release runs from main
if: ${{ !inputs.dry_run }}
run: |
if [ "${{ github.ref }}" != "refs/heads/main" ]; then
echo "Error: Releases must be run from main"
echo "Current ref: ${{ github.ref }}"
exit 1
fi
- name: Ensure main commit has green CI
if: ${{ !inputs.dry_run }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
RESPONSE=$(curl -fsSL \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${GITHUB_TOKEN}" \
"https://api.github.com/repos/${{ github.repository }}/actions/workflows/ci.yml/runs?branch=main&event=push&status=success&per_page=1")
LATEST_GREEN_SHA=$(echo "$RESPONSE" | jq -r '.workflow_runs[0].head_sha // empty')
if [ -z "$LATEST_GREEN_SHA" ]; then
echo "Error: No successful ci.yml run found on main"
exit 1
fi
if [ "$LATEST_GREEN_SHA" != "${{ github.sha }}" ]; then
echo "Error: Current commit does not match latest green ci.yml run on main"
echo "Current SHA: ${{ github.sha }}"
echo "Latest green CI SHA: $LATEST_GREEN_SHA"
exit 1
fi
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ env.RUST_VERSION }}
- name: Install nightly toolchain (doc parity)
uses: dtolnay/rust-toolchain@stable
with:
toolchain: nightly
- name: Validate version format
run: |
if ! [[ "${{ inputs.version }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Error: Version must be in format X.Y.Z (e.g., 0.3.0)"
exit 1
fi
- name: Check version in Cargo.toml
run: |
CARGO_VERSION=$(grep '^version = ' Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
if [ "$CARGO_VERSION" != "${{ inputs.version }}" ]; then
echo "Error: Cargo.toml version ($CARGO_VERSION) doesn't match input version (${{ inputs.version }})"
echo "Please update Cargo.toml version field first"
exit 1
fi
- name: Check CHANGELOG.md updated
run: |
if ! grep -q "## \[${{ inputs.version }}\]" CHANGELOG.md; then
echo "Error: CHANGELOG.md doesn't contain release notes for v${{ inputs.version }}"
echo "Please update CHANGELOG.md before releasing"
exit 1
fi
- name: Run docs check
run: |
RUSTDOCFLAGS='--cfg docsrs -D warnings' cargo +nightly doc --workspace --all-features --no-deps
- name: Dry run cargo publish
run: cargo publish --dry-run
- name: Publish to crates.io
if: ${{ !inputs.dry_run }}
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: cargo publish
- name: Create git tag
if: ${{ !inputs.dry_run }}
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git tag -a "weavegraph-v${{ inputs.version }}" -m "Release weavegraph v${{ inputs.version }}"
git push origin "weavegraph-v${{ inputs.version }}"
- name: Create GitHub release
if: ${{ !inputs.dry_run }}
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: weavegraph-v${{ inputs.version }}
release_name: Weavegraph v${{ inputs.version }}
body: |
See [CHANGELOG.md](https://github.com/${{ github.repository }}/blob/main/CHANGELOG.md#${{ inputs.version }}) for details.
draft: false
prerelease: false
- name: Dry run summary
if: ${{ inputs.dry_run }}
run: |
echo "✓ Dry run complete - no changes published"
echo "Version validated: ${{ inputs.version }}"
echo "Tag would be created: weavegraph-v${{ inputs.version }}"