I have identified two potential improvements for how we perform static analysis on our code in our CI pipeline: - The `giraffate/clippy-action` we currently use has not been updated to Node 20, and GitHub has repeatedly indicated that they will phase out actions that do not support the latest Node versions. Despite my efforts to help with the update by submitting a pull request upstream, it has been ignored for months despite its perceived ease of review, raising concerns about the ongoing maintenance of the action. This situation suggests we should explore alternative methods for integrating Clippy with GitHub's UI. - As evidenced by PR 632, thoroughly testing Rust crates for every possible feature combination is often overlooked due to the tedious nature of the task. Our current CI setup only checks two feature combinations, which is far from comprehensive. To address the first improvement, these changes drop `clippy-action` entirely in favor of utilizing GitHub's native CodeQL SARIF (Static Analysis Results Interchange Format) file integration. Since Clippy cannot directly output lints in SARIF, `clippy-sarif` is used to convert Clippy's JSON output to SARIF. Additionally, `sarif-fmt` is added to turn SARIF into a human-friendly display format in the workflow run logs. For the second improvement, let's use `cargo hack` with the `--feature-powerset` flag to run Clippy for every possible feature combination. This approach strikes a good balance between CI runtime and thoroughness, as the number of feature combinations grows superlinearly with the number of features: running `cargo nextest` for every powerset element would lead to excessively long CI times.
190 lines
6 KiB
YAML
190 lines
6 KiB
YAML
name: oxipng
|
|
|
|
on:
|
|
push:
|
|
pull_request:
|
|
types:
|
|
- opened
|
|
- synchronize
|
|
workflow_dispatch:
|
|
|
|
jobs:
|
|
ci:
|
|
name: CI
|
|
|
|
runs-on: ${{ matrix.os }}
|
|
timeout-minutes: 60
|
|
|
|
# Prevent tags and in-repo PRs from triggering this workflow more than once for a commit
|
|
if: github.ref_type != 'tag' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork)
|
|
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
target:
|
|
- x86_64-unknown-linux-gnu
|
|
- x86_64-unknown-linux-musl
|
|
- aarch64-unknown-linux-gnu
|
|
- aarch64-unknown-linux-musl
|
|
- x86_64-pc-windows-msvc
|
|
- i686-pc-windows-msvc
|
|
- x86_64-apple-darwin
|
|
- aarch64-apple-darwin
|
|
|
|
include:
|
|
- target: x86_64-unknown-linux-gnu
|
|
os: ubuntu-22.04
|
|
target-apt-arch: amd64
|
|
- target: x86_64-unknown-linux-musl
|
|
os: ubuntu-22.04
|
|
target-apt-arch: amd64
|
|
- target: aarch64-unknown-linux-gnu
|
|
os: ubuntu-22.04
|
|
target-apt-arch: arm64
|
|
- target: aarch64-unknown-linux-musl
|
|
os: ubuntu-22.04
|
|
target-apt-arch: arm64
|
|
- target: x86_64-pc-windows-msvc
|
|
os: windows-latest
|
|
- target: i686-pc-windows-msvc
|
|
os: windows-latest
|
|
- target: x86_64-apple-darwin
|
|
os: macos-12
|
|
- target: aarch64-apple-darwin
|
|
os: macos-14 # ARM64 runner
|
|
|
|
env:
|
|
CARGO_BUILD_TARGET: ${{ matrix.target }}
|
|
RUSTFLAGS: -Zlocation-detail=none
|
|
|
|
steps:
|
|
- name: Checkout source
|
|
uses: actions/checkout@v4
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Set up Ubuntu multiarch
|
|
if: startsWith(matrix.os, 'ubuntu') && matrix.target-apt-arch != 'amd64'
|
|
run: |
|
|
readonly DISTRO_CODENAME=jammy
|
|
sudo dpkg --add-architecture "${{ matrix.target-apt-arch }}"
|
|
sudo sed -i "s/^deb http/deb [arch=$(dpkg-architecture -q DEB_HOST_ARCH)] http/" /etc/apt/sources.list
|
|
sudo sed -i "s/^deb mirror/deb [arch=$(dpkg-architecture -q DEB_HOST_ARCH)] mirror/" /etc/apt/sources.list
|
|
for suite in '' '-updates' '-backports' '-security'; do
|
|
echo "deb [arch=${{ matrix.target-apt-arch }}] http://ports.ubuntu.com/ $DISTRO_CODENAME$suite main universe multiverse" | \
|
|
sudo tee -a /etc/apt/sources.list >/dev/null
|
|
done
|
|
|
|
- name: Install musl development files
|
|
if: endsWith(matrix.target, '-musl')
|
|
run: |
|
|
sudo apt-get -yq update
|
|
sudo apt-get -yq install musl-tools musl-dev:${{ matrix.target-apt-arch }}
|
|
|
|
- name: Install QEMU and AArch64 cross compiler
|
|
if: startsWith(matrix.target, 'aarch64-unknown-linux')
|
|
run: |
|
|
sudo apt-get -yq update
|
|
# libc6 must be present to run executables dynamically linked
|
|
# against glibc for the target architecture
|
|
sudo apt-get -yq install qemu-user gcc-aarch64-linux-gnu libc6:arm64
|
|
|
|
- name: Cache Cargo artifacts
|
|
uses: Swatinem/rust-cache@v2
|
|
|
|
- name: Install Rust toolchain
|
|
uses: dtolnay/rust-toolchain@v1
|
|
with:
|
|
toolchain: nightly
|
|
targets: ${{ env.CARGO_BUILD_TARGET }}
|
|
components: clippy, rustfmt
|
|
|
|
- name: Install nextest
|
|
uses: taiki-e/install-action@nextest
|
|
|
|
- name: Install cargo-hack
|
|
if: matrix.target == 'x86_64-unknown-linux-gnu'
|
|
uses: taiki-e/install-action@cargo-hack
|
|
|
|
- name: Install clippy-sarif
|
|
if: matrix.target == 'x86_64-unknown-linux-gnu'
|
|
uses: taiki-e/install-action@v2
|
|
with:
|
|
tool: clippy-sarif
|
|
|
|
- name: Install sarif-fmt
|
|
if: matrix.target == 'x86_64-unknown-linux-gnu'
|
|
uses: taiki-e/install-action@v2
|
|
with:
|
|
tool: sarif-fmt
|
|
|
|
- name: Run rustfmt
|
|
if: matrix.target == 'x86_64-unknown-linux-gnu'
|
|
run: cargo fmt --check
|
|
|
|
- name: Run Clippy for all feature combinations
|
|
if: matrix.target == 'x86_64-unknown-linux-gnu'
|
|
run: >
|
|
cargo hack clippy --no-deps --all-targets --feature-powerset --exclude-features sanity-checks --message-format=json -- -D warnings
|
|
| clippy-sarif
|
|
| tee clippy-results.sarif
|
|
| sarif-fmt
|
|
|
|
- name: Run tests
|
|
run: |
|
|
cargo nextest run --release --features sanity-checks
|
|
cargo test --doc --release --features sanity-checks
|
|
|
|
- name: Build benchmarks
|
|
run: cargo bench --no-run
|
|
|
|
- name: Build docs
|
|
if: matrix.target == 'x86_64-unknown-linux-gnu'
|
|
run: cargo doc --release --no-deps
|
|
|
|
- name: Build CLI binary
|
|
run: cargo build --release
|
|
|
|
- name: Upload CLI binary as artifact
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: Oxipng binary (${{ matrix.target }})
|
|
path: |
|
|
target/${{ env.CARGO_BUILD_TARGET }}/release/oxipng
|
|
target/${{ env.CARGO_BUILD_TARGET }}/release/oxipng.exe
|
|
|
|
- name: Upload analysis results to GitHub
|
|
uses: github/codeql-action/upload-sarif@v3
|
|
if: always() && matrix.target == 'x86_64-unknown-linux-gnu'
|
|
with:
|
|
sarif_file: clippy-results.sarif
|
|
category: clippy
|
|
|
|
msrv-check:
|
|
name: MSRV check
|
|
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 30
|
|
|
|
# Prevent tags and in-repo PRs from triggering this workflow more than once for a commit
|
|
if: github.ref_type != 'tag' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork)
|
|
|
|
steps:
|
|
- name: Checkout source
|
|
uses: actions/checkout@v4
|
|
with:
|
|
persist-credentials: false
|
|
|
|
- name: Cache Cargo artifacts
|
|
uses: Swatinem/rust-cache@v2
|
|
|
|
- name: Install MSRV Rust toolchain
|
|
uses: dtolnay/rust-toolchain@1.74.0
|
|
|
|
- name: Install nextest
|
|
uses: taiki-e/install-action@nextest
|
|
|
|
- name: Run tests
|
|
run: |
|
|
cargo nextest run --release --features sanity-checks
|
|
cargo test --doc --release --features sanity-checks
|