name: Release
on:
workflow_dispatch:
inputs:
action:
description: 'Action to perform'
required: true
type: choice
options:
- bump-patch
- bump-minor
- bump-major
- build-binaries
version:
description: 'Version to build (only for build-binaries, e.g., 0.1.1)'
required: false
type: string
pull_request:
types: [closed]
branches: [main]
env:
CARGO_TERM_COLOR: always
jobs:
create-release-pr:
name: Create Release PR
if: github.event_name == 'workflow_dispatch' && startsWith(github.event.inputs.action, 'bump-')
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install git-cliff
uses: taiki-e/install-action@git-cliff
- name: Get current version
id: current
run: |
VERSION=$(grep '^version = ' Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Calculate new version
id: new
run: |
IFS='.' read -r major minor patch <<< "${{ steps.current.outputs.version }}"
case "${{ inputs.action }}" in
bump-major)
major=$((major + 1))
minor=0
patch=0
;;
bump-minor)
minor=$((minor + 1))
patch=0
;;
bump-patch)
patch=$((patch + 1))
;;
esac
NEW_VERSION="${major}.${minor}.${patch}"
echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT
echo "Bumping ${{ steps.current.outputs.version }} -> $NEW_VERSION"
- name: Update Cargo.toml version
run: |
sed -i 's/^version = ".*"/version = "${{ steps.new.outputs.version }}"/' Cargo.toml
- name: Update Cargo.lock
run: cargo generate-lockfile
- name: Generate changelog
run: git cliff --tag "v${{ steps.new.outputs.version }}" -o CHANGELOG.md
- name: Create Pull Request
uses: peter-evans/create-pull-request@v7
with:
commit-message: "chore(release): prepare v${{ steps.new.outputs.version }}"
branch: release/v${{ steps.new.outputs.version }}
title: "release: v${{ steps.new.outputs.version }}"
body: |
Bumps version from ${{ steps.current.outputs.version }} to ${{ steps.new.outputs.version }}.
**Changes included:**
- Version bump in `Cargo.toml`
- Updated `CHANGELOG.md` (auto-generated from commits)
Once merged, this will automatically:
- Create git tag `v${{ steps.new.outputs.version }}`
- Build binaries for Linux, macOS, Windows
- Publish to crates.io
- Create GitHub Release with binaries
publish:
name: Publish Release
if: github.event.pull_request.merged == true && startsWith(github.event.pull_request.head.ref, 'release/v')
runs-on: ubuntu-latest
permissions:
contents: write
outputs:
version: ${{ steps.version.outputs.version }}
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: Get version from Cargo.toml
id: version
run: |
VERSION=$(grep '^version = ' Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Create and push tag
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git tag "v${{ steps.version.outputs.version }}"
git push origin "v${{ steps.version.outputs.version }}"
- name: Publish to crates.io
run: cargo publish
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ steps.version.outputs.version }}
name: v${{ steps.version.outputs.version }}
generate_release_notes: true
draft: false
build-binaries:
name: Build ${{ matrix.target }}
needs: [publish]
if: |
always() &&
(needs.publish.result == 'success' ||
(github.event_name == 'workflow_dispatch' && github.event.inputs.action == 'build-binaries' && github.event.inputs.version != ''))
runs-on: ${{ matrix.os }}
permissions:
contents: write
strategy:
matrix:
include:
- target: x86_64-unknown-linux-gnu
os: ubuntu-latest
- target: aarch64-unknown-linux-gnu
os: ubuntu-24.04-arm
- target: x86_64-apple-darwin
os: macos-latest
- target: aarch64-apple-darwin
os: macos-latest
- target: x86_64-pc-windows-msvc
os: windows-latest
steps:
- uses: actions/checkout@v4
with:
ref: v${{ needs.publish.outputs.version || github.event.inputs.version }}
- name: Set version
id: version
shell: bash
run: echo "version=${{ needs.publish.outputs.version || github.event.inputs.version }}" >> $GITHUB_OUTPUT
- name: Install dependencies (Linux)
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y libssl-dev pkg-config
- uses: dtolnay/rust-toolchain@stable
- name: Build
run: cargo build --release
- name: Package binary (unix)
if: runner.os != 'Windows'
run: |
cd target/release
tar -czvf ../../tuicr-${{ steps.version.outputs.version }}-${{ matrix.target }}.tar.gz tuicr
- name: Package binary (windows)
if: runner.os == 'Windows'
run: |
cd target/release
7z a ../../tuicr-${{ steps.version.outputs.version }}-${{ matrix.target }}.zip tuicr.exe
- name: Upload to release
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ steps.version.outputs.version }}
files: |
tuicr-*.tar.gz
tuicr-*.zip