name: Rust
on:
push:
branches: [ "main" ]
tags:
- 'v*'
pull_request:
branches: [ "main" ]
paths:
- '**/*.rs'
- '**/Cargo.toml'
- 'Cargo.lock'
- 'build.rs'
- '.github/workflows/rust.yml'
workflow_dispatch:
inputs:
ref:
description: 'Branch, tag, or SHA to build'
required: false
default: ''
env:
CARGO_TERM_COLOR: always
permissions:
contents: read
jobs:
build:
runs-on: ${{ matrix.os }}
container: ${{ matrix.container }}
if: github.ref_type != 'tag'
strategy:
matrix:
platform: [ubuntu-x64, ubuntu-arm, fedora-x64, fedora-arm, macos, windows-x64, windows-arm]
include:
- platform: ubuntu-x64
os: ubuntu-latest
- platform: ubuntu-arm
os: ubuntu-24.04-arm
- platform: fedora-x64
os: ubuntu-latest
container: fedora:latest
- platform: fedora-arm
os: ubuntu-24.04-arm
container: fedora:latest
- platform: macos
os: macos-latest
- platform: windows-x64
os: windows-latest
- platform: windows-arm
os: windows-11-arm
steps:
- name: Install dependencies (Fedora)
if: startsWith(matrix.platform, 'fedora')
run: |
dnf install -y git curl gcc make sqlite-devel
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
- name: Install Rust toolchain (Host)
if: ${{ !matrix.container }}
uses: dtolnay/rust-toolchain@stable
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
- name: Format check
run: cargo fmt -- --check
- name: Clippy
run: cargo clippy --workspace -- -D warnings
- name: Build
run: cargo build --verbose
- name: Run tests
run: cargo test --workspace --verbose
- name: Run fetcher (dry run)
run: cargo run -- --long
- name: Print system_profiler SPDisplaysDataType (macOS)
if: runner.os == 'macOS'
run: system_profiler SPDisplaysDataType
full-test:
runs-on: ${{ matrix.os }}
container: ${{ matrix.container }}
if: (github.ref_type == 'tag' && startsWith(github.ref, 'refs/tags/v')) || github.event_name == 'workflow_dispatch'
strategy:
matrix:
platform: [ubuntu-x64, ubuntu-arm, fedora-x64, fedora-arm, macos, windows-x64, windows-arm]
include:
- platform: ubuntu-x64
os: ubuntu-latest
container: ubuntu:latest
- platform: ubuntu-arm
os: ubuntu-24.04-arm
container: ubuntu:latest
- platform: fedora-x64
os: ubuntu-latest
container: fedora:latest
- platform: fedora-arm
os: ubuntu-24.04-arm
container: fedora:latest
- platform: macos
os: macos-latest
- platform: windows-x64
os: windows-latest
- platform: windows-arm
os: windows-11-arm
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
- name: Install Rust toolchain (Ubuntu Container)
if: startsWith(matrix.platform, 'ubuntu')
run: |
apt-get update
apt-get install -y curl build-essential sqlite3 libsqlite3-dev
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
$HOME/.cargo/bin/cargo install mandown
- name: Install Rust toolchain (Fedora Container)
if: startsWith(matrix.platform, 'fedora')
run: |
dnf install -y curl gcc make sqlite-devel
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
$HOME/.cargo/bin/cargo install mandown
- name: Install Rust toolchain (Host)
if: ${{ !matrix.container }}
uses: dtolnay/rust-toolchain@stable
- name: Build (release)
run: cargo build --release --verbose
- name: Run tests (all features)
run: cargo test --workspace --all-features --verbose
- name: Clippy
run: cargo clippy --workspace -- -D warnings
- name: Format check
run: cargo fmt -- --check
- name: Run fetcher (dry run)
run: cargo run --release -- --long
- name: Print system_profiler SPDisplaysDataType (macOS)
if: runner.os == 'macOS'
run: system_profiler SPDisplaysDataType
- name: Generate man page
shell: bash
run: just man || echo "Man page generation skipped (just may not be installed)"
build-release:
needs: full-test
runs-on: ${{ matrix.os }}
container: ${{ matrix.container }}
if: (github.ref_type == 'tag' && startsWith(github.ref, 'refs/tags/v')) || github.event_name == 'workflow_dispatch'
strategy:
matrix:
platform: [fedora-x64, fedora-arm, macos, windows-x64, windows-arm]
include:
- platform: fedora-x64
os: ubuntu-latest
container: fedora:latest
artifact_name: release-assets-linux-x86_64
- platform: fedora-arm
os: ubuntu-24.04-arm
container: fedora:latest
artifact_name: release-assets-linux-arm64
- platform: macos
os: macos-latest
artifact_name: release-assets-macos-arm64
- platform: windows-x64
os: windows-latest
artifact_name: release-assets-windows-x86_64
- platform: windows-arm
os: windows-11-arm
artifact_name: release-assets-windows-arm64
steps:
- name: Install system dependencies (Fedora)
if: startsWith(matrix.platform, 'fedora')
run: |
dnf install -y git curl gcc make sqlite-devel
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
- name: Install Rust toolchain (Fedora)
if: startsWith(matrix.platform, 'fedora')
run: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
- name: Install Rust toolchain (Host)
if: ${{ !matrix.container }}
uses: dtolnay/rust-toolchain@stable
- name: Build release binary (Fedora)
if: startsWith(matrix.platform, 'fedora')
run: |
$HOME/.cargo/bin/cargo build --release --verbose
- name: Build release binary (Non-Fedora)
if: ${{ !startsWith(matrix.platform, 'fedora') }}
run: |
cargo build --release --verbose
- name: Prepare release assets
shell: bash
run: |
mkdir -p release
if [ "${{ matrix.platform }}" = "fedora-x64" ]; then
cp target/release/retch release/retch-linux-x86_64
cp docs/retch.1 release/ || true
elif [ "${{ matrix.platform }}" = "fedora-arm" ]; then
cp target/release/retch release/retch-linux-arm64
cp docs/retch.1 release/ || true
elif [ "${{ matrix.platform }}" = "macos" ]; then
cp target/release/retch release/retch-macos-arm64
elif [ "${{ matrix.platform }}" = "windows-x64" ]; then
cp target/release/retch.exe release/retch-windows-x86_64.exe
elif [ "${{ matrix.platform }}" = "windows-arm" ]; then
cp target/release/retch.exe release/retch-windows-arm64.exe
fi
- name: Upload release assets
uses: actions/upload-artifact@v7
with:
name: ${{ matrix.artifact_name }}
path: release/
release:
needs: build-release
runs-on: ubuntu-latest
if: github.ref_type == 'tag' && startsWith(github.ref, 'refs/tags/v') && !contains(github.ref_name, '-')
permissions:
contents: write
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
- name: Download release assets
uses: actions/download-artifact@v8
with:
path: release
pattern: release-assets-*
merge-multiple: true
- name: Install Nix
uses: cachix/install-nix-action@v31
with:
nix_path: nixpkgs=channel:nixos-unstable
- name: Calculate Nixpkgs Hashes
id: nix_hashes
run: python3 scripts/calculate_nix_hashes.py
- name: Create Release
uses: softprops/action-gh-release@718ea10b132b3b2eba29c1007bb80653f286566b
with:
tag_name: ${{ github.ref_name }}
name: retch ${{ github.ref_name }}
draft: false
prerelease: false
body: |
### Nixpkgs Submission Info
To update the package in Nixpkgs, use the following settings in `package.nix`:
```nix
version = "${{ steps.nix_hashes.outputs.version }}";
hash = "${{ steps.nix_hashes.outputs.src_hash }}";
cargoHash = "${{ steps.nix_hashes.outputs.cargo_hash }}";
```
files: |
release/retch-linux-x86_64
release/retch-linux-arm64
release/retch-macos-arm64
release/retch-windows-x86_64.exe
release/retch-windows-arm64.exe
release/retch.1
generate_release_notes: true
- name: Clean up rc pre-releases and prune old releases (keep 10)
env:
GH_TOKEN: ${{ github.token }}
run: |
VERSION="${{ github.ref_name }}"
# Delete all rc pre-releases for this version
gh release list --repo "$GITHUB_REPOSITORY" --limit 100 --json tagName \
--jq ".[] | select(.tagName | startswith(\"${VERSION}-rc.\")) | .tagName" \
| xargs -r -I{} gh release delete {} --repo "$GITHUB_REPOSITORY" --yes --cleanup-tag
# Keep only the 10 most recent stable releases
gh release list --repo "$GITHUB_REPOSITORY" --limit 100 --json tagName,isPrerelease \
--jq '[.[] | select(.isPrerelease | not)][10:][].tagName' \
| xargs -r -I{} gh release delete {} --repo "$GITHUB_REPOSITORY" --yes --cleanup-tag