name: release
on:
push:
branches:
- main
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: dtolnay/rust-toolchain@stable
- name: Check bump commit
id: check
run: |
if [ "${{ github.actor }}" = "github-actions[bot]" ]; then
echo "run=false" >> "$GITHUB_OUTPUT"
exit 0
fi
msg_git=$(git log -1 --pretty=%B)
echo "commit message:"
echo "$msg_git"
if echo "$msg_git" | grep -E -i -q 'bump\((patch|minor|major)\)'; then
kind=$(echo "$msg_git" | sed -E 's/.*bump\((patch|minor|major)\).*/\1/I')
echo "run=true" >> "$GITHUB_OUTPUT"
echo "kind=$kind" >> "$GITHUB_OUTPUT"
exit 0
fi
python - <<'PY' > /tmp/bump_output
import json
import os
import re
with open(os.environ["GITHUB_EVENT_PATH"], "r", encoding="utf-8") as f:
event = json.load(f)
messages = []
for commit in event.get("commits", []):
msg = commit.get("message", "")
if msg:
messages.append(msg)
head = event.get("head_commit")
if head and head.get("message"):
messages.append(head["message"])
text = "\n".join(messages)
match = re.search(r"bump\((patch|minor|major)\)", text, re.IGNORECASE)
if match:
print("run=true")
print(f"kind={match.group(1).lower()}")
else:
print("run=false")
PY
cat /tmp/bump_output >> "$GITHUB_OUTPUT"
cat /tmp/bump_output
- name: Bump version
if: steps.check.outputs.run == 'true'
id: bump
run: |
BUMP_KIND="${{ steps.check.outputs.kind }}" python - <<'PY' > /tmp/bump_output
import os
import re
kind = os.environ["BUMP_KIND"]
with open("Cargo.toml", "r", encoding="utf-8") as f:
data = f.read()
match = re.search(r'^version\s*=\s*"([^"]+)"', data, re.M)
if not match:
raise SystemExit("version not found in Cargo.toml")
version = match.group(1)
major, minor, patch = [int(part) for part in version.split(".")]
if kind == "patch":
patch += 1
elif kind == "minor":
minor += 1
patch = 0
elif kind == "major":
major += 1
minor = 0
patch = 0
else:
raise SystemExit(f"unsupported bump kind: {kind}")
new_version = f"{major}.{minor}.{patch}"
data = re.sub(
r'^version\s*=\s*"[^"]+"',
f'version = "{new_version}"',
data,
count=1,
flags=re.M,
)
with open("Cargo.toml", "w", encoding="utf-8") as f:
f.write(data)
print(f"new_version={new_version}")
PY
cargo generate-lockfile
cat /tmp/bump_output >> "$GITHUB_OUTPUT"
- name: Commit version bump
if: steps.check.outputs.run == 'true'
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add Cargo.toml Cargo.lock
git commit -m "chore: bump version to ${{ steps.bump.outputs.new_version }}"
git push origin HEAD:${{ github.ref_name }}
- name: Create tag
if: steps.check.outputs.run == 'true'
run: |
git tag "v${{ steps.bump.outputs.new_version }}"
git push origin "v${{ steps.bump.outputs.new_version }}"
- name: Test
if: steps.check.outputs.run == 'true'
run: cargo test --locked
- name: Publish
if: steps.check.outputs.run == 'true'
run: cargo publish --locked
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}