name: Version
on:
workflow_dispatch:
push:
branches: [main]
permissions:
contents: write
actions: write
jobs:
version:
name: Bump version and tag
runs-on: ubuntu-latest
if: "!startsWith(github.event.head_commit.message, 'chore(release):')"
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Get latest tag
id: latest_tag
run: |
tag=$(git tag -l 'v*' --sort=-v:refname | head -n1)
if [ -z "$tag" ]; then
echo "tag=" >> "$GITHUB_OUTPUT"
echo "No existing tags found"
else
echo "tag=$tag" >> "$GITHUB_OUTPUT"
echo "Latest tag: $tag"
fi
- name: Determine version bump from commits
id: bump
run: |
latest_tag="${{ steps.latest_tag.outputs.tag }}"
# First release: publish 0.0.0 without bumping
if [ -z "$latest_tag" ]; then
echo "version=0.0.0" >> "$GITHUB_OUTPUT"
echo "skip=false" >> "$GITHUB_OUTPUT"
echo "First release: v0.0.0"
exit 0
fi
current="${latest_tag#v}"
IFS='.' read -r major minor patch <<< "$current"
commits=$(git log "$latest_tag"..HEAD --pretty=format:"%s")
if [ -z "$commits" ]; then
echo "skip=true" >> "$GITHUB_OUTPUT"
exit 0
fi
bump="none"
while IFS= read -r msg; do
if echo "$msg" | grep -qiE '^feat(\(.+\))?!:|^[a-z]+(\(.+\))?!:|BREAKING CHANGE'; then
bump="major"
break
elif echo "$msg" | grep -qiE '^feat(\(.+\))?:'; then
if [ "$bump" != "major" ]; then
bump="minor"
fi
elif echo "$msg" | grep -qiE '^fix(\(.+\))?:'; then
if [ "$bump" = "none" ]; then
bump="patch"
fi
fi
done <<< "$commits"
if [ "$bump" = "none" ]; then
echo "skip=true" >> "$GITHUB_OUTPUT"
exit 0
fi
case "$bump" in
major) major=$((major + 1)); minor=0; patch=0 ;;
minor) minor=$((minor + 1)); patch=0 ;;
patch) patch=$((patch + 1)) ;;
esac
new_version="${major}.${minor}.${patch}"
echo "version=$new_version" >> "$GITHUB_OUTPUT"
echo "skip=false" >> "$GITHUB_OUTPUT"
echo "Bump: $bump -> v$new_version"
- name: Update Cargo.toml version
if: steps.bump.outputs.skip != 'true'
run: |
new_version="${{ steps.bump.outputs.version }}"
sed -i "s/^version = \".*\"/version = \"$new_version\"/" Cargo.toml
echo "Updated Cargo.toml to version $new_version"
- name: Commit and tag
if: steps.bump.outputs.skip != 'true'
run: |
new_version="${{ steps.bump.outputs.version }}"
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add Cargo.toml
if git diff --cached --quiet; then
echo "Cargo.toml already at v${new_version}, skipping commit"
else
git commit -m "chore(release): v${new_version}"
fi
git tag "v${new_version}"
git push origin main --tags
- name: Trigger release workflow
if: steps.bump.outputs.skip != 'true'
run: gh workflow run release.yml --ref "v${{ steps.bump.outputs.version }}"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}