name: CI
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
env:
CARGO_TERM_COLOR: always
jobs:
generate-matrix:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.generate.outputs.matrix }}
steps:
- id: generate
uses: mmastrac/mmm-matrix@v1
with:
input: |
rust-toolchain: stable
job: [test]
feature_combo: [default, all-features, no-default-features]
cargo_args:
$match:
"this.feature_combo == 'default'": ""
"this.feature_combo == 'all-features'": "--all-features"
"this.feature_combo == 'no-default-features'": "--no-default-features"
label:
linux:
os: ubuntu-latest
macos:
os: macos-latest
windows:
os: windows-latest
config: |
github: ${{ toJSON(github) }}
test:
name: ${{ matrix.label }} / ${{ matrix.job }} / ${{ matrix.feature_combo }} (${{ matrix.rust-toolchain }})
runs-on: ${{ matrix.os }}
needs: generate-matrix
strategy:
fail-fast: false
matrix:
include: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
steps:
- uses: actions/checkout@v6
- name: Install Rust toolchain (${{ matrix.rust-toolchain }})
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: ${{ matrix.rust-toolchain }}
components: clippy
- name: Install wget (Windows)
if: ${{ runner.os == 'Windows' }}
shell: bash
run: |
choco install -y wget > /dev/null || echo "choco failed"
wget --version
- name: Install pwsh (Linux)
if: ${{ runner.os == 'Linux' }}
shell: bash
run: |
set -euxo pipefail
sudo apt-get update
sudo apt-get install -y powershell
command -v pwsh >/dev/null 2>&1 && pwsh -NoProfile -NonInteractive -Command '$PSVersionTable.PSVersion'
- name: Set up Python (httpbin on Windows or macOS)
if: ${{ runner.os == 'Windows' || runner.os == 'macOS' }}
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Start httpbin (Waitress, Windows)
if: ${{ runner.os == 'Windows' }}
shell: pwsh
run: |
$ErrorActionPreference = 'Stop'
python -m pip install -U pip
python -m pip install httpbin waitress
$port = 8080
$listen = "127.0.0.1:$port"
$proc = Start-Process -FilePath python -ArgumentList @(
'-m', 'waitress', "--listen=$listen", 'httpbin:app'
) -WindowStyle Hidden -PassThru
Add-Content -Path $env:GITHUB_ENV -Value "SHELL_DOWNLOAD_HTTPBIN=http://127.0.0.1:$port"
for ($i = 0; $i -lt 90; $i++) {
try {
Invoke-WebRequest -Uri "http://127.0.0.1:$port/get" -UseBasicParsing -TimeoutSec 3 | Out-Null
exit 0
} catch {
Start-Sleep -Seconds 1
}
}
throw "httpbin did not become ready in time (waitress pid=$($proc.Id))"
- name: Start httpbin (Waitress, macOS)
if: ${{ runner.os == 'macOS' }}
shell: bash
run: |
set -euo pipefail
python -m pip install -U pip
python -m pip install httpbin waitress
PORT=8080
python -m waitress --listen="127.0.0.1:${PORT}" httpbin:app &
echo "SHELL_DOWNLOAD_HTTPBIN=http://127.0.0.1:${PORT}" >> "$GITHUB_ENV"
for _ in {1..90}; do
if curl -sfS "http://127.0.0.1:${PORT}/get" >/dev/null; then
exit 0
fi
sleep 1
done
echo "httpbin did not become ready in time" >&2
exit 1
- name: Start httpbin (Docker)
if: ${{ runner.os == 'Linux' }}
shell: bash
run: |
set -euo pipefail
PORT=8080
IMAGE=kennethreitz/httpbin:latest
docker pull --platform linux/amd64 "$IMAGE"
docker rm -f shell-download-httpbin 2>/dev/null || true
docker run -d --name shell-download-httpbin --rm --platform linux/amd64 -p "127.0.0.1:${PORT}:80" "$IMAGE"
echo "SHELL_DOWNLOAD_HTTPBIN=http://127.0.0.1:${PORT}" >> "$GITHUB_ENV"
for _ in $(seq 1 60); do
if curl -sfS "http://127.0.0.1:${PORT}/get" >/dev/null; then
exit 0
fi
sleep .1
done
echo "httpbin did not become ready in time" >&2
docker logs shell-download-httpbin 2>&1 || true
exit 1
- name: Run clippy (${{ matrix.feature_combo }})
shell: bash
run: cargo clippy ${{ matrix.cargo_args }} -- -D warnings
- name: Run tests (${{ matrix.feature_combo }})
shell: bash
run: cargo test ${{ matrix.cargo_args }}