name: Release SDK to crates.io
on:
workflow_dispatch: workflow_call: inputs:
version:
description: "Version to release (without v prefix)"
required: false
type: string
outputs:
version:
description: "The published version"
value: ${{ jobs.publish.outputs.version }}
env:
CARGO_TERM_COLOR: always
permissions:
contents: write
issues: write
jobs:
version-check:
name: Version Check
uses: ./.github/workflows/version-check.yml
publish:
name: Publish to crates.io
needs: version-check
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.version }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 token: ${{ secrets.GITHUB_TOKEN }}
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-${{ hashFiles('Cargo.toml') }}
restore-keys: |
${{ runner.os }}-cargo-
- name: Get version
id: version
env:
INPUT_VERSION: ${{ inputs.version }}
VERIFIED_VERSION: ${{ needs.version-check.outputs.version }}
run: |
if [ -n "$INPUT_VERSION" ]; then
VERSION="$INPUT_VERSION"
elif [ -n "$VERIFIED_VERSION" ]; then
VERSION="$VERIFIED_VERSION"
else
VERSION=$(grep -A 10 '^\[package\]' Cargo.toml | grep '^version = ' | head -1 | sed 's/version = "\(.*\)"/\1/')
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Version: $VERSION"
- name: Check if tag already exists
id: check-tag
run: |
TAG_NAME="v${{ steps.version.outputs.version }}"
if git rev-parse "$TAG_NAME" >/dev/null 2>&1; then
echo "exists=true" >> $GITHUB_OUTPUT
echo "Tag $TAG_NAME already exists"
else
echo "exists=false" >> $GITHUB_OUTPUT
echo "Tag $TAG_NAME does not exist"
fi
- name: Create git tag
if: steps.check-tag.outputs.exists == 'false'
run: |
TAG_NAME="v${{ steps.version.outputs.version }}"
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git tag -a "$TAG_NAME" -m "Release $TAG_NAME"
git push origin "$TAG_NAME"
echo "Created and pushed tag: $TAG_NAME"
- name: Extract referenced issues from commits
id: extract-issues
run: |
# Get commits since last tag (or all commits if no tag exists)
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
if [ -z "$LAST_TAG" ]; then
COMMITS=$(git log --pretty=format:"%s %b" --no-merges)
else
COMMITS=$(git log ${LAST_TAG}..HEAD --pretty=format:"%s %b" --no-merges)
fi
# Extract issue numbers from commit messages
ISSUES=$(echo "$COMMITS" | grep -oE '(closes|fixes|resolves|implements|addresses)?\s*#?[0-9]+' | grep -oE '[0-9]+' | sort -u | tr '\n' ' ' || echo "")
if [ -z "$ISSUES" ]; then
echo "No referenced issues found in commits"
echo "issues=" >> $GITHUB_OUTPUT
else
echo "Found referenced issues: $ISSUES"
echo "issues=$ISSUES" >> $GITHUB_OUTPUT
fi
- name: Close referenced issues
if: steps.extract-issues.outputs.issues != ''
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
VERSION="${{ steps.version.outputs.version }}"
ISSUES="${{ steps.extract-issues.outputs.issues }}"
for issue in $ISSUES; do
echo "Checking issue #$issue..."
ISSUE_STATE=$(gh issue view $issue --repo ${{ github.repository }} --json state -q .state 2>/dev/null || echo "notfound")
if [ "$ISSUE_STATE" = "notfound" ]; then
echo " Issue #$issue not found, skipping"
continue
elif [ "$ISSUE_STATE" = "closed" ]; then
echo " Issue #$issue is already closed, skipping"
continue
elif [ "$ISSUE_STATE" = "open" ]; then
echo " Closing issue #$issue..."
gh issue close $issue --repo ${{ github.repository }} --comment "Closed automatically as part of release v$VERSION." || echo " Failed to close issue #$issue"
fi
done
- name: Login to crates.io
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: |
echo "$CARGO_REGISTRY_TOKEN" | cargo login
- name: Publish data-modelling-core to crates.io
run: |
cd crates/core
cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }}
echo "Waiting for crates.io to index the package..."
sleep 60
- name: Publish data-modelling-sdk to crates.io
run: |
cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }}