Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions .github/workflows/pre-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
name: Pre-release

on:
pull_request:
branches:
- "main"
types: [opened,labeled,edited,synchronize]

jobs:
test-artifacts:
if: contains(github.event.pull_request.labels.*.name, 'release')

env:
RUST_BACKTRACE: 1
RUST_LIB_BACKTRACE: 1
TOKIO_WORKER_THREADS: 1

strategy:
matrix:
include:
- target: x86_64-unknown-linux-gnu
os: ubuntu-22.04
command: test
- target: aarch64-unknown-linux-gnu
os: ubuntu-24.04-arm
command: test
- target: x86_64-apple-darwin
os: macos-latest
command: build
- target: aarch64-apple-darwin
os: macos-latest
command: test
# disabling windows tests for now bc of a bunch of biome issues
- target: x86_64-pc-windows-msvc
os: windows-latest
command: build
- target: aarch64-pc-windows-msvc
os: windows-11-arm
command: build

runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Add target
run: rustup target add ${{ matrix.target }}
- name: Setup
uses: ./.github/workflows/setup
- name: Compile binary
run: cargo ${{ matrix.command }} --locked --target ${{ matrix.target }}
- name: Compress artifacts (Windows)
if: runner.os == 'Windows'
run: |
cd target/${{ matrix.target }}/debug
Compress-Archive -Path ${{ github.event.repository.name }}.exe -Destination ${{ matrix.target }}.zip
- name: Compress artifacts (Non-Windows)
if: runner.os != 'Windows'
run: |
cd target/${{ matrix.target }}/debug
zip -9 ${{ matrix.target }}.zip ${{ github.event.repository.name }}

publish-dry-run:
if: contains(github.event.pull_request.labels.*.name, 'release')
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Login to crates.io
run: cargo login ${{ secrets.CRATES_IO_TOKEN }}
- name: Dry run of crate publish
run: cargo publish --workspace --dry-run

check-pr-name:
if: contains(github.event.pull_request.labels.*.name, 'release')
runs-on: ubuntu-latest
steps:
- name: Check that PR name is a release number
run: echo "${{ github.event.pull_request.title }}" | grep -q -E "^v[0-9]+\.[0-9]+\.[0-9]+$"

134 changes: 56 additions & 78 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,107 +5,85 @@ on:
branches: [main]
types: [labeled,closed]

permissions:
contents: write
pull-requests: read

jobs:
create-release:
build-artifacts:
if: github.event.pull_request.merged == true && contains(github.event.pull_request.labels.*.name, 'release')
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.version }}
tag: ${{ steps.version.outputs.tag }}
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Extract version from Cargo.toml
id: version
run: |
VERSION=$(grep '^version = ' Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "tag=v$VERSION" >> $GITHUB_OUTPUT
echo "Extracted version: $VERSION"

- name: Create GitHub Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release create ${{ steps.version.outputs.tag }} \
--title "Release ${{ steps.version.outputs.version }}" \
--notes "Release ${{ steps.version.outputs.version }}" \
--draft=false \
--prerelease=false

build-artifacts:
needs: create-release
strategy:
matrix:
include:
- target: x86_64-unknown-linux-gnu
os: ubuntu-latest
os: ubuntu-22.04
- 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
- target: aarch64-pc-windows-msvc
os: windows-11-arm

runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Install Rust toolchain for target
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}

- name: Build for target
run: cargo build --release --target ${{ matrix.target }} --verbose

- name: Package artifacts (Unix)
if: runner.os != 'Windows'
run: |
cd target/${{ matrix.target }}/release
tar czf rheo-${{ needs.create-release.outputs.version }}-${{ matrix.target }}.tar.gz rheo
shasum -a 256 rheo-${{ needs.create-release.outputs.version }}-${{ matrix.target }}.tar.gz > rheo-${{ needs.create-release.outputs.version }}-${{ matrix.target }}.tar.gz.sha256

- name: Package artifacts (Windows)
- name: Add target
run: rustup target add ${{ matrix.target }}
- name: Setup
uses: ./.github/workflows/setup
- name: Compile binary
run: cargo build --locked --release --target ${{ matrix.target }}
- name: Compress artifacts (Windows)
if: runner.os == 'Windows'
run: |
cd target/${{ matrix.target }}/release
7z a rheo-${{ needs.create-release.outputs.version }}-${{ matrix.target }}.zip rheo.exe
certutil -hashfile rheo-${{ needs.create-release.outputs.version }}-${{ matrix.target }}.zip SHA256 > rheo-${{ needs.create-release.outputs.version }}-${{ matrix.target }}.zip.sha256

- name: Upload Release Assets
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Compress-Archive -Path ${{ github.event.repository.name }}.exe -Destination ${{ matrix.target }}.zip
- name: Compress artifacts (Non-Windows)
if: runner.os != 'Windows'
run: |
gh release upload ${{ needs.create-release.outputs.tag }} target/${{ matrix.target }}/release/rheo-${{ needs.create-release.outputs.version }}-${{ matrix.target }}.* --clobber
cd target/${{ matrix.target }}/release
zip -9 ${{ matrix.target }}.zip ${{ github.event.repository.name }}
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.target }}
path: target/${{ matrix.target }}/release/${{ matrix.target }}.zip

publish-crate:
needs: [create-release, build-artifacts]
publish-crates:
needs: build-artifacts
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Login to crates.io
run: cargo login ${{ secrets.CRATES_IO_TOKEN }}
- name: Publish crates
run: cargo publish --workspace
- name: Add a tag for the merged commit
uses: christophebedard/tag-version-commit@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
version_regex: 'v([0-9]+\.[0-9]+\.[0-9]+)'
version_tag_prefix: 'v'

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable

- name: Check version has been bumped
run: |
VERSION="${{ needs.create-release.outputs.version }}"
echo "Releasing version: $VERSION"

# Check if version exists on crates.io
if cargo search rheo --limit 1 | grep -q "rheo = \"$VERSION\""; then
echo "Error: Version $VERSION already exists on crates.io"
echo "Please bump the version in Cargo.toml before releasing"
exit 1
fi

echo "Version check passed: $VERSION is new"

- name: Publish to crates.io
run: cargo publish --token ${{ secrets.CRATES_IO_TOKEN }}
publish-artifacts:
needs: publish-crates
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Download artifacts
uses: actions/download-artifact@v4
- name: Publish artifacts
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ github.event.pull_request.title }}
files: |
x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu.zip
aarch64-unknown-linux-gnu/aarch64-unknown-linux-gnu.zip
x86_64-apple-darwin/x86_64-apple-darwin.zip
aarch64-apple-darwin/aarch64-apple-darwin.zip
x86_64-pc-windows-msvc/x86_64-pc-windows-msvc.zip
aarch64-pc-windows-msvc/aarch64-pc-windows-msvc.zip
39 changes: 39 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,45 @@ cargo test test_warning_formatting -- --nocapture
- Typst libraries are pulled from git main branch
- Keep dependencies minimal and well-justified

### Branching and Release Workflow

**Development Model:**
- All development happens via pull requests to `main`
- The `main` branch is the primary development branch
- No long-lived feature branches; PRs are merged directly to main

**Release Process:**

When ready to cut a new release:

1. **Update version in Cargo.toml** to the new version number

2. **Create a release PR:**
- PR title MUST be the version tag (e.g., `v0.2.0`)
- Add the `release` label to the PR

3. **Pre-release validation** (automated via `.github/workflows/pre-release.yml`):
- Builds and tests on all supported platforms (Linux x86_64/ARM, macOS x86_64/ARM, Windows x86_64/ARM)
- Validates PR title matches `vX.Y.Z` format
- Runs `cargo publish --dry-run` to verify crates.io readiness

4. **Merge the PR** - triggers release automation (`.github/workflows/release.yml`):
- Builds release binaries for all platforms
- Publishes to crates.io
- Creates a git tag matching the PR title
- Creates a GitHub Release with platform-specific zip files

**Supported Platforms:**
- `x86_64-unknown-linux-gnu` (Linux x86_64)
- `aarch64-unknown-linux-gnu` (Linux ARM64)
- `x86_64-apple-darwin` (macOS Intel)
- `aarch64-apple-darwin` (macOS Apple Silicon)
- `x86_64-pc-windows-msvc` (Windows x86_64)
- `aarch64-pc-windows-msvc` (Windows ARM64)

**Release Artifacts:**
Each release includes zip files for each platform containing the `rheo` binary, available on the GitHub Releases page.

---

## Version Control with Jujutsu
Expand Down
Loading