name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read
env:
CARGO_TERM_COLOR: always
jobs:
msrv:
name: MSRV
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 - name: Install libdbus-1-dev
run: sudo apt-get update && sudo apt-get install -y libdbus-1-dev pkg-config
- uses: dtolnay/rust-toolchain@193d6aa1dbbc28bd2c0a6b0e327cfdce68baaf6e - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 with:
key: msrv-1.89.0
- run: cargo test --locked --features test-helpers
fmt:
name: Format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 - uses: dtolnay/rust-toolchain@193d6aa1dbbc28bd2c0a6b0e327cfdce68baaf6e with:
components: rustfmt
- run: cargo fmt --check
test-layout:
name: Test Layout
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 - name: Install ripgrep
run: sudo apt-get update && sudo apt-get install -y ripgrep
- run: make check-test-layout
- run: make check-no-spawn
clippy:
name: Clippy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 - name: Install libdbus-1-dev
run: sudo apt-get update && sudo apt-get install -y libdbus-1-dev pkg-config
- uses: dtolnay/rust-toolchain@193d6aa1dbbc28bd2c0a6b0e327cfdce68baaf6e with:
components: clippy
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 - run: cargo clippy --locked --features test-helpers -- -D warnings
test:
name: Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 - name: Install libdbus-1-dev
run: sudo apt-get update && sudo apt-get install -y libdbus-1-dev pkg-config
- uses: dtolnay/rust-toolchain@193d6aa1dbbc28bd2c0a6b0e327cfdce68baaf6e - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 - run: cargo test --locked --features test-helpers
build:
name: Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 - name: Install libdbus-1-dev
run: sudo apt-get update && sudo apt-get install -y libdbus-1-dev pkg-config
- uses: dtolnay/rust-toolchain@193d6aa1dbbc28bd2c0a6b0e327cfdce68baaf6e - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 - run: cargo build --release --locked
- name: Verify vendored-keyring drops the libdbus dependency
run: |
set -euo pipefail
# The release workflow builds the x86_64/aarch64 Linux artifacts with
# --features vendored-keyring so the Homebrew bottle binary is
# self-contained. Prove here, on native Linux, that the feature both
# builds and statically links libdbus (no NEEDED libdbus-1.so entry).
cargo build --release --locked --features vendored-keyring
if readelf -d target/release/bzr | grep -i 'NEEDED.*dbus'; then
echo "::error::vendored-keyring binary still links libdbus dynamically; vendoring did not take effect"
exit 1
fi
echo "vendored-keyring: no libdbus NEEDED entry — OK"
manpages:
name: Manpages
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 - uses: dtolnay/rust-toolchain@193d6aa1dbbc28bd2c0a6b0e327cfdce68baaf6e - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 with:
key: manpages
- name: Generate manpages
run: cargo run -p xtask --no-default-features --release --locked -- man --out man/man1
- name: Verify expected pages exist
run: |
set -euo pipefail
test -s man/man1/bzr.1
test -s man/man1/bzr-bug.1
test -s man/man1/bzr-bug-list.1
test -s man/man1/bzr-config-set-server.1
- name: Render with groff (catches malformed roff)
run: |
set -euo pipefail
sudo apt-get update && sudo apt-get install -y groff
for page in man/man1/*.1; do
groff -man -Tutf8 "$page" > /dev/null
done
cross-check:
name: Cross-check ${{ matrix.target }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
target:
- aarch64-unknown-linux-gnu
- powerpc64le-unknown-linux-gnu
- s390x-unknown-linux-gnu
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 - uses: dtolnay/rust-toolchain@193d6aa1dbbc28bd2c0a6b0e327cfdce68baaf6e with:
targets: ${{ matrix.target }}
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 with:
key: ${{ matrix.target }}
- name: Install cross
run: cargo install cross --locked
- name: Check
env:
PKG_CONFIG_ALLOW_CROSS: "1"
run: |
# aarch64 ships its release binary with vendored libdbus (it feeds a
# Homebrew bottle), so check that target the same way -- this also
# exercises the vendored libdbus C cross-compile that only otherwise
# runs at release time.
FEATURES=()
if [ "${{ matrix.target }}" = "aarch64-unknown-linux-gnu" ]; then
FEATURES=(--features vendored-keyring)
fi
cross check --locked --target ${{ matrix.target }} "${FEATURES[@]}"
windows-cross-check:
name: Cross-check aarch64-pc-windows-msvc
runs-on: windows-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 - uses: dtolnay/rust-toolchain@193d6aa1dbbc28bd2c0a6b0e327cfdce68baaf6e with:
targets: aarch64-pc-windows-msvc
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 with:
key: aarch64-pc-windows-msvc
- name: Check
run: cargo check --locked --target aarch64-pc-windows-msvc
sonarqube:
name: SonarQube
if: |
(github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false)
&& github.actor != 'dependabot[bot]'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 with:
fetch-depth: 0 - name: Install libdbus-1-dev
run: sudo apt-get update && sudo apt-get install -y libdbus-1-dev pkg-config
- uses: dtolnay/rust-toolchain@193d6aa1dbbc28bd2c0a6b0e327cfdce68baaf6e with:
components: llvm-tools-preview
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 with:
key: sonarqube
- uses: taiki-e/install-action@0631aa6515c7d545823c67cfae7ef4fc7f490154 with:
tool: cargo-llvm-cov
- name: Generate coverage report
run: cargo llvm-cov --locked --workspace --all-features --lcov --output-path lcov.info
- name: SonarQube Scan
uses: SonarSource/sonarqube-scan-action@7006c4492b2e0ee0f816d36501671557c97f5995 env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
installer-lint:
name: Lint installer scripts
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10
- name: Install shellcheck and shfmt
run: |
sudo apt-get update
sudo apt-get install -y shellcheck
curl -fsSL https://github.com/mvdan/sh/releases/download/v3.7.0/shfmt_v3.7.0_linux_amd64 -o /tmp/shfmt
sudo install -m 0755 /tmp/shfmt /usr/local/bin/shfmt
- name: Run shellcheck
run: shellcheck -s sh install.sh tests/installer/smoke.sh
- name: Run shfmt (check only)
run: shfmt -d -ln posix -i 2 install.sh tests/installer/smoke.sh
- name: Run PSScriptAnalyzer
shell: pwsh
run: |
Install-Module -Name PSScriptAnalyzer -Force -Scope CurrentUser
$diagnostics = @()
$diagnostics += Invoke-ScriptAnalyzer -Path install.ps1 -Severity Warning
$diagnostics += Invoke-ScriptAnalyzer -Path tests/installer/smoke.ps1 -Severity Warning
if ($diagnostics) {
$diagnostics | Format-Table
exit 1
}
installer-test:
name: Smoke ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-14, windows-latest]
runs-on: ${{ matrix.os }}
permissions:
contents: read
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10
- name: Smoke (bash)
if: matrix.os != 'windows-latest'
run: sh tests/installer/smoke.sh
- name: Smoke (powershell)
if: matrix.os == 'windows-latest'
shell: pwsh
run: ./tests/installer/smoke.ps1