Skip to content

Release Process

Release Process #61

Workflow file for this run

name: Release Process
on:
push:
tags:
- "v*"
- "[0-9]+.[0-9]+.[0-9]+"
workflow_dispatch:
permissions:
contents: write
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
HOMEBREW_TOKEN: ${{ secrets.HOMEBREW_TOKEN }}
jobs:
validate:
name: Pre-Release Validation
runs-on: ubuntu-22.04
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- name: Cache dependencies
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
- name: Extract version from tag
id: version
run: |
VERSION=${GITHUB_REF#refs/tags/}
VERSION=${VERSION#v}
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Extracted version: $VERSION"
- name: Validate version format
run: |
VERSION="${{ steps.version.outputs.version }}"
if ! [[ $VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "❌ Invalid version format: $VERSION"
echo "Expected format: X.Y.Z (e.g., 1.6.5)"
exit 1
fi
echo "✅ Version format valid: $VERSION"
- name: Check CHANGELOG
run: |
VERSION="${{ steps.version.outputs.version }}"
if ! grep -q "^$VERSION (" CHANGELOG.md; then
echo "❌ Version $VERSION not found in CHANGELOG.md"
echo "Please add an entry for version $VERSION"
exit 1
fi
echo "✅ CHANGELOG entry found for version $VERSION"
- name: Check for uncommitted changes
run: |
if ! git diff-index --quiet HEAD --; then
echo "❌ Uncommitted changes detected"
git status
exit 1
fi
echo "✅ No uncommitted changes"
- name: Run tests
run: cargo test
- name: Run clippy
run: cargo clippy -- -D warnings
- name: Build release
run: cargo build --release
- name: Validate documentation
run: |
# Check if README exists and has content
if [ ! -f README.md ] || [ ! -s README.md ]; then
echo "❌ README.md is missing or empty"
exit 1
fi
echo "✅ Documentation validation passed"
publish:
name: Publish to Cargo
needs: validate
runs-on: ubuntu-22.04
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: Publish to crates.io
run: |
cd tidy-viewer-cli
cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }}
build-packages:
name: Build Distribution Packages
needs: validate
runs-on: ubuntu-22.04
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: Install cargo-deb
run: cargo install cargo-deb
- name: Install alien
run: |
sudo apt-get update
sudo apt-get install -y alien
- name: Build Debian package
run: cargo deb --package tidy-viewer --manifest-path tidy-viewer-cli/Cargo.toml
- name: Build RPM package
run: |
alien --verbose --to-rpm ./target/debian/tidy-viewer_*_amd64.deb
mv *.rpm ./target/
- name: Upload Debian package
uses: actions/upload-artifact@v4
with:
name: debian-package
path: ./target/debian/*.deb
- name: Upload RPM package
uses: actions/upload-artifact@v4
with:
name: rpm-package
path: ./target/*.rpm
build-binaries-windows:
name: Build Windows Binaries
needs: validate
runs-on: windows-2022
strategy:
matrix:
target: [i686-pc-windows-msvc, x86_64-pc-windows-msvc]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Extract version from tag
id: version
shell: bash
run: |
VERSION=${GITHUB_REF#refs/tags/}
VERSION=${VERSION#v}
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Build (release)
shell: bash
run: |
cargo build --package tidy-viewer --release --target ${{ matrix.target }}
- name: Package zip
shell: pwsh
run: |
$version = "${{ steps.version.outputs.version }}"
$target = "${{ matrix.target }}"
$out = "tidy-viewer-$version-$target.zip"
Compress-Archive -Path "target/$target/release/tidy-viewer.exe" -DestinationPath $out
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: windows-${{ matrix.target }}
path: tidy-viewer-${{ steps.version.outputs.version }}-${{ matrix.target }}.zip
build-binaries-macos:
name: Build macOS (x86_64) Binary
needs: validate
runs-on: macos-13
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Extract version from tag
id: version
run: |
VERSION=${GITHUB_REF#refs/tags/}
VERSION=${VERSION#v}
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: Build (release)
run: cargo build --package tidy-viewer --release
- name: Package tar.gz
run: |
VERSION=${{ steps.version.outputs.version }}
tar -C target/release -czf tidy-viewer-$VERSION-x86_64-apple-darwin.tar.gz tidy-viewer
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: macos-x86_64-apple-darwin
path: tidy-viewer-${{ steps.version.outputs.version }}-x86_64-apple-darwin.tar.gz
build-binaries-linux:
name: Build Linux (tgz) Binary
needs: validate
runs-on: ubuntu-22.04
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Extract version from tag
id: version
run: |
VERSION=${GITHUB_REF#refs/tags/}
VERSION=${VERSION#v}
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: Build (release)
run: cargo build --package tidy-viewer --release
- name: Package tgz
run: |
VERSION=${{ steps.version.outputs.version }}
tar -C target/release -czf tidy-viewer-$VERSION.tgz tidy-viewer
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: linux-tgz
path: tidy-viewer-${{ steps.version.outputs.version }}.tgz
homebrew-update:
name: Update Homebrew Formulas
needs: [validate, publish]
runs-on: ubuntu-22.04
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Extract version
id: version
run: |
VERSION=${GITHUB_REF#refs/tags/}
VERSION=${VERSION#v}
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Get SHA256 of release tarball
id: sha256
run: |
VERSION="${{ steps.version.outputs.version }}"
wget https://github.com/alexhallam/tv/archive/refs/tags/v$VERSION.tar.gz
SHA256=$(sha256sum v$VERSION.tar.gz | cut -d' ' -f1)
echo "sha256=$SHA256" >> $GITHUB_OUTPUT
echo "Version: $VERSION"
echo "SHA256: $SHA256"
- name: Update personal homebrew tap
if: env.HOMEBREW_TOKEN != ''
run: |
VERSION="${{ steps.version.outputs.version }}"
SHA256="${{ steps.sha256.outputs.sha256 }}"
# Clone personal homebrew tap with token
git clone https://x-access-token:${{ env.HOMEBREW_TOKEN }}@github.com/alexhallam/homebrew-tidy-viewer.git
cd homebrew-tidy-viewer
# Update formula
sed -i "s/version \"[^\"]*\"/version \"$VERSION\"/" tidy-viewer.rb
sed -i "s/sha256 \"[^\"]*\"/sha256 \"$SHA256\"/" tidy-viewer.rb
# Commit and push
git config user.name "GitHub Actions"
git config user.email "[email protected]"
git add tidy-viewer.rb
git commit -m "Update tidy-viewer to version $VERSION"
git push origin main
- name: Create Homebrew Core PR
if: env.HOMEBREW_TOKEN != ''
env:
GH_TOKEN: ${{ env.HOMEBREW_TOKEN }}
run: |
VERSION="${{ steps.version.outputs.version }}"
SHA256="${{ steps.sha256.outputs.sha256 }}"
# Install gh if missing
if ! command -v gh >/dev/null 2>&1; then
sudo apt-get update
sudo apt-get install -y gh
fi
# Clone personal homebrew-core fork with token
git clone https://x-access-token:${{ env.HOMEBREW_TOKEN }}@github.com/alexhallam/homebrew-core.git
cd homebrew-core
# Fetch upstream
git remote add upstream https://github.com/Homebrew/homebrew-core.git
git fetch upstream
git checkout main
git merge upstream/main
# Update formula
sed -i "s/version \"[^\"]*\"/version \"$VERSION\"/" Formula/t/tidy-viewer.rb
sed -i "s/sha256 \"[^\"]*\"/sha256 \"$SHA256\"/" Formula/t/tidy-viewer.rb
# Create branch and push
git checkout -b tidy-viewer-$VERSION
git add Formula/t/tidy-viewer.rb
git commit -m "tidy-viewer: update $VERSION bottle"
git push origin tidy-viewer-$VERSION
# Create PR using gh
gh pr create --title "tidy-viewer: update $VERSION bottle" --body "Update tidy-viewer to version $VERSION"
post-release:
name: Post-Release Verification
needs:
[
publish,
build-packages,
homebrew-update,
build-binaries-windows,
build-binaries-macos,
build-binaries-linux,
]
runs-on: ubuntu-22.04
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Extract version
id: version
run: |
VERSION=${GITHUB_REF#refs/tags/}
VERSION=${VERSION#v}
echo "version=$VERSION" >> $GITHUB_OUTPUT
- name: Verify crates.io publication
run: |
VERSION="${{ steps.version.outputs.version }}"
sleep 30 # Wait for crates.io to update
# Check if version is available on crates.io
if ! curl -s "https://crates.io/api/v1/crates/tidy-viewer" | grep -q "\"version\":\"$VERSION\""; then
echo "❌ Version $VERSION not yet available on crates.io"
exit 1
fi
echo "✅ Version $VERSION published to crates.io"
- name: Download Debian artifact
uses: actions/download-artifact@v4
with:
name: debian-package
path: ./artifacts/deb
- name: Download RPM artifact
uses: actions/download-artifact@v4
with:
name: rpm-package
path: ./artifacts/rpm
- name: Download Windows x86 (i686) artifact
uses: actions/download-artifact@v4
with:
name: windows-i686-pc-windows-msvc
path: ./artifacts/windows/i686
- name: Download Windows x64 (x86_64) artifact
uses: actions/download-artifact@v4
with:
name: windows-x86_64-pc-windows-msvc
path: ./artifacts/windows/x86_64
- name: Download macOS (x86_64) artifact
uses: actions/download-artifact@v4
with:
name: macos-x86_64-apple-darwin
path: ./artifacts/macos
- name: Download Linux tgz artifact
uses: actions/download-artifact@v4
with:
name: linux-tgz
path: ./artifacts/linux
- name: Create GitHub Release and upload assets
uses: softprops/action-gh-release@v1
with:
tag_name: ${{ github.ref }}
name: Release ${{ github.ref }}
body: |
## What's New in Version ${{ steps.version.outputs.version }}
See [CHANGELOG.md](https://github.com/alexhallam/tv/blob/main/CHANGELOG.md) for detailed changes.
## Installation
```bash
cargo install tidy-viewer
```
## Downloads
Debian, RPM, and platform-specific archives are attached as release assets below.
draft: false
prerelease: false
files: |
./artifacts/deb/*.deb
./artifacts/rpm/*.rpm
./artifacts/windows/i686/*.zip
./artifacts/windows/x86_64/*.zip
./artifacts/macos/*.tar.gz
./artifacts/linux/*.tgz
env:
GITHUB_TOKEN: ${{ env.GITHUB_TOKEN }}
- name: Success Summary
run: |
VERSION="${{ steps.version.outputs.version }}"
echo "🎉 Release $VERSION completed successfully!"
echo ""
echo "✅ Published to crates.io"
echo "✅ Built Debian and RPM packages"
echo "✅ Built Windows, macOS, and Linux binary archives"
echo "✅ Updated Homebrew formulas"
echo "✅ Created GitHub release"
echo ""
echo "📦 Installation:"
echo " cargo install tidy-viewer"
echo " brew install tidy-viewer"