name: Release
on:
push:
tags:
- 'v*'
release:
types: [published] workflow_dispatch:
permissions:
contents: write
jobs:
validate:
name: Validate Release
if: startsWith(github.ref, 'refs/tags/v')
uses: ./.github/workflows/validate-release.yml
secrets: inherit
publish-crate:
name: Publish to crates.io
runs-on: ubuntu-latest
if: github.event_name == 'release' && github.event.action == 'published'
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Check version matches tag
run: |
TAG_VERSION=${GITHUB_REF#refs/tags/v}
CARGO_VERSION=$(grep "^version" Cargo.toml | sed 's/.*"\(.*\)".*/\1/')
if [ "$TAG_VERSION" != "$CARGO_VERSION" ]; then
echo "Error: Tag version ($TAG_VERSION) does not match Cargo.toml version ($CARGO_VERSION)"
exit 1
fi
- name: Run tests
run: cargo test --all-features
- name: Publish to crates.io
run: cargo publish --token ${CARGO_REGISTRY_TOKEN}
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
build-deb:
name: Build Debian Package
runs-on: ubuntu-latest
needs: validate
if: startsWith(github.ref, 'refs/tags/v')
strategy:
matrix:
target:
- x86_64-unknown-linux-gnu
- aarch64-unknown-linux-gnu
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Setup Rust cache
uses: Swatinem/rust-cache@v2
with:
key: ${{ matrix.target }}
- name: Cache cargo-deb
id: cache-cargo-deb
uses: actions/cache@v4
with:
path: ~/.cargo/bin/cargo-deb
key: ${{ runner.os }}-cargo-deb-2.7.0
- name: Install cargo-deb
if: steps.cache-cargo-deb.outputs.cache-hit != 'true'
run: cargo install cargo-deb --version 2.7.0
- name: Install cross-compilation tools for ARM64
if: matrix.target == 'aarch64-unknown-linux-gnu'
run: |
sudo apt-get update
sudo apt-get install -y gcc-aarch64-linux-gnu pkg-config libssl-dev
- name: Build release binary
run: |
if [ "${{ matrix.target }}" = "aarch64-unknown-linux-gnu" ]; then
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc
export CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc
export CXX_aarch64_unknown_linux_gnu=aarch64-linux-gnu-g++
fi
cargo build --release --target ${{ matrix.target }}
- name: Build .deb package
run: |
if [ "${{ matrix.target }}" = "aarch64-unknown-linux-gnu" ]; then
# For cross-compilation, disable stripping to avoid strip format errors
cargo deb --target ${{ matrix.target }} --no-build --no-strip
else
cargo deb --target ${{ matrix.target }} --no-build
fi
- name: Upload .deb artifact
uses: actions/upload-artifact@v4
with:
name: ftr-deb-${{ matrix.target }}
path: target/${{ matrix.target }}/debian/*.deb
build-windows:
name: Build Windows Binary
runs-on: windows-latest
needs: validate
if: startsWith(github.ref, 'refs/tags/v')
strategy:
matrix:
target:
- x86_64-pc-windows-msvc
- aarch64-pc-windows-msvc
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Setup Rust cache
uses: Swatinem/rust-cache@v2
with:
key: ${{ matrix.target }}
- name: Build release binary
run: cargo build --release --target ${{ matrix.target }}
- name: Create archive
shell: pwsh
run: |
$target = "${{ matrix.target }}"
$version = "${env:GITHUB_REF}" -replace "refs/tags/v", ""
$archiveName = "ftr-${version}-${target}.zip"
# Create a directory for the archive contents
New-Item -ItemType Directory -Force -Path "archive"
# Copy the binary
Copy-Item "target\${target}\release\ftr.exe" "archive\"
# Copy README and LICENSE
Copy-Item "README.md" "archive\"
Copy-Item "LICENSE" "archive\"
# Create the zip archive
Compress-Archive -Path "archive\*" -DestinationPath $archiveName
# Output the archive name for the upload step
echo "ARCHIVE_NAME=$archiveName" >> $env:GITHUB_ENV
- name: Upload Windows artifact
uses: actions/upload-artifact@v4
with:
name: ftr-windows-${{ matrix.target }}
path: ${{ env.ARCHIVE_NAME }}
create-release:
name: Create Release
needs: [build-deb, build-windows]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
pattern: ftr-*
merge-multiple: true
- name: Create Release
uses: softprops/action-gh-release@v1
with:
files: |
*.deb
*.zip
draft: true prerelease: false
body: |
## Installation
### Windows
Download the appropriate .zip file below for your architecture:
- `ftr-*-x86_64-pc-windows-msvc.zip` for 64-bit Intel/AMD
- `ftr-*-aarch64-pc-windows-msvc.zip` for ARM64
Extract the archive and add the directory to your PATH, or run `ftr.exe` directly.
### Debian/Ubuntu packages
Download the appropriate .deb file below for your architecture:
- `ftr_*_amd64.deb` for 64-bit Intel/AMD
- `ftr_*_arm64.deb` for ARM64
### Other platforms
- macOS: `brew tap dweekly/ftr && brew install ftr`
- Cargo: `cargo install ftr` (available after this release is published)
## Release Notes
Please see [CHANGELOG.md](https://github.com/${{ github.repository }}/blob/${{ github.ref_name }}/CHANGELOG.md) for detailed changes.
---
*Note: This is a draft release. Please edit with proper release notes before publishing.*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}