Skip to content

Commit b303509

Browse files
committed
ci: align shared security and release tooling
- Run CI through pinned uv and cached Cargo tooling across all supported platforms. - Add repository Semgrep rules, action allowlist coverage, CodeQL, zizmor, and SARIF workflows. - Raise the Rust and Python tooling floors to Rust 1.96 and Python 3.12. - Add archive-aware changelog generation, post-processing, and tag-release tooling. - Preserve exact arithmetic overflow reporting without non-finite sentinel defaults. Closes #117
1 parent 9359256 commit b303509

43 files changed

Lines changed: 5808 additions & 716 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/dependabot.yml‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ updates:
55
directory: "/"
66
schedule:
77
interval: "weekly"
8+
cooldown:
9+
default-days: 7
810
open-pull-requests-limit: 10
911
labels:
1012
- "dependencies"
@@ -15,6 +17,8 @@ updates:
1517
directory: "/"
1618
schedule:
1719
interval: "weekly"
20+
cooldown:
21+
default-days: 7
1822
open-pull-requests-limit: 10
1923
labels:
2024
- "dependencies"

‎.github/workflows/audit.yml‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,12 @@ permissions:
2020
jobs:
2121
audit:
2222
runs-on: ubuntu-latest
23+
env:
24+
CARGO_AUDIT_VERSION: "0.22.1"
2325
steps:
2426
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
27+
with:
28+
persist-credentials: false
2529

2630
- name: Install Rust toolchain
2731
uses: actions-rust-lang/setup-rust-toolchain@46268bd060767258de96ed93c1251119784f2ab6 # v1.16.1
@@ -36,7 +40,9 @@ jobs:
3640
restore-keys: advisory-db-
3741

3842
- name: Install cargo-audit
39-
run: cargo install --locked cargo-audit
43+
uses: taiki-e/cache-cargo-install-action@417450f3c33ee20393705369577571770643d4c7 # v3.0.7
44+
with:
45+
tool: cargo-audit@${{ env.CARGO_AUDIT_VERSION }}
4046

4147
- name: Run cargo audit
4248
run: |

‎.github/workflows/benchmarks.yml‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ jobs:
4848

4949
steps:
5050
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
51+
with:
52+
persist-credentials: false
5153

5254
- name: Install Rust toolchain
5355
uses: actions-rust-lang/setup-rust-toolchain@46268bd060767258de96ed93c1251119784f2ab6 # v1.16.1

‎.github/workflows/ci.yml‎

Lines changed: 65 additions & 170 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
name: CI
2+
23
permissions:
34
contents: read
5+
46
concurrency:
57
group: >
68
ci-${{ github.workflow }}-${{
@@ -17,21 +19,25 @@ on:
1719
pull_request:
1820
branches:
1921
- main
22+
workflow_dispatch:
2023

2124
env:
2225
CARGO_TERM_COLOR: always
2326
RUST_BACKTRACE: 1
24-
ACTIONLINT_VERSION: "1.7.10"
25-
MARKDOWNLINT_VERSION: "0.47.0"
26-
SHFMT_VERSION: "3.12.0"
27-
TYPOS_VERSION: "1.43.4"
28-
UV_VERSION: "0.9.28"
27+
CARGO_NEXTEST_VERSION: "0.9.137"
28+
DPRINT_VERSION: "0.54.0"
29+
JUST_VERSION: "1.51.0"
30+
RUMDL_VERSION: "0.2.4"
31+
TAPLO_VERSION: "0.10.0"
32+
TYPOS_VERSION: "1.47.0"
33+
UV_VERSION: "0.11.16"
34+
ZIZMOR_VERSION: "1.25.2"
2935

3036
jobs:
3137
build:
3238
runs-on: ${{ matrix.os }}
3339
strategy:
34-
fail-fast: false # Continue other jobs if one fails
40+
fail-fast: false
3541
matrix:
3642
os:
3743
- ubuntu-latest
@@ -46,190 +52,79 @@ jobs:
4652
target: x86_64-pc-windows-msvc
4753

4854
steps:
55+
- name: Disable Git autocrlf on Windows
56+
if: matrix.os == 'windows-latest'
57+
shell: pwsh
58+
run: |
59+
git config --global core.autocrlf false
60+
git config --global core.eol lf
61+
4962
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
63+
with:
64+
persist-credentials: false
5065

5166
- name: Install Rust toolchain
5267
uses: actions-rust-lang/setup-rust-toolchain@46268bd060767258de96ed93c1251119784f2ab6 # v1.16.1
5368
with:
5469
target: ${{ matrix.target }}
55-
cache: true # Built-in caching
70+
cache: true
5671
# toolchain, components, etc. are specified in rust-toolchain.toml
5772

58-
- name: Install just
59-
if: matrix.os != 'windows-latest'
60-
uses: taiki-e/install-action@50b4a718b59c718df4ef27a3b445f86cd57b9f00 # v2.80.0
73+
- name: Set up Python
74+
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
6175
with:
62-
tool: just
76+
python-version: "3.12"
6377

64-
- name: Install uv (for Python scripts and pytest)
65-
if: matrix.os != 'windows-latest'
78+
- name: Install uv
6679
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
6780
with:
6881
version: ${{ env.UV_VERSION }}
82+
enable-cache: true
83+
84+
- name: Sync Python tooling
85+
run: uv sync --locked --group dev
86+
87+
- name: Install just
88+
uses: taiki-e/cache-cargo-install-action@417450f3c33ee20393705369577571770643d4c7 # v3.0.7
89+
with:
90+
tool: just@${{ env.JUST_VERSION }}
6991

70-
- name: Install Node.js (for markdownlint)
71-
if: matrix.os != 'windows-latest'
72-
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
92+
- name: Install dprint
93+
uses: taiki-e/cache-cargo-install-action@417450f3c33ee20393705369577571770643d4c7 # v3.0.7
7394
with:
74-
node-version: "20"
95+
tool: dprint@${{ env.DPRINT_VERSION }}
7596

76-
- name: Install Node.js packages
77-
if: matrix.os != 'windows-latest'
78-
run: |
79-
npm install -g markdownlint-cli@${{ env.MARKDOWNLINT_VERSION }}
97+
- name: Install rumdl
98+
uses: taiki-e/cache-cargo-install-action@417450f3c33ee20393705369577571770643d4c7 # v3.0.7
99+
with:
100+
tool: rumdl@${{ env.RUMDL_VERSION }}
101+
102+
- name: Install taplo
103+
id: install-taplo
104+
continue-on-error: ${{ matrix.os == 'windows-latest' }}
105+
uses: taiki-e/cache-cargo-install-action@417450f3c33ee20393705369577571770643d4c7 # v3.0.7
106+
with:
107+
tool: taplo-cli@${{ env.TAPLO_VERSION }}
80108

81-
- name: Install typos-cli
82-
if: matrix.os != 'windows-latest'
83-
uses: taiki-e/install-action@50b4a718b59c718df4ef27a3b445f86cd57b9f00 # v2.80.0
109+
- name: Install taplo on Windows after cached install failure
110+
if: matrix.os == 'windows-latest' && steps.install-taplo.outcome == 'failure'
111+
shell: pwsh
112+
run: cargo install --locked taplo-cli --version $env:TAPLO_VERSION
113+
114+
- name: Install typos
115+
uses: taiki-e/cache-cargo-install-action@417450f3c33ee20393705369577571770643d4c7 # v3.0.7
84116
with:
85117
tool: typos-cli@${{ env.TYPOS_VERSION }}
86118

87-
- name: Install taplo (for TOML formatting and linting)
88-
if: matrix.os != 'windows-latest'
89-
uses: taiki-e/install-action@50b4a718b59c718df4ef27a3b445f86cd57b9f00 # v2.80.0
119+
- name: Install zizmor
120+
uses: taiki-e/cache-cargo-install-action@417450f3c33ee20393705369577571770643d4c7 # v3.0.7
90121
with:
91-
tool: taplo-cli
122+
tool: zizmor@${{ env.ZIZMOR_VERSION }}
92123

93-
- name: Install actionlint (Linux/macOS)
94-
if: matrix.os != 'windows-latest'
95-
run: |
96-
set -euo pipefail
97-
98-
# actionlint is published as prebuilt binaries (Go), not a Rust crate.
99-
# Install directly from rhysd/actionlint releases to avoid cargo-binstall fallback failures.
100-
# Verify SHA256 checksums from the upstream release for supply-chain hardening.
101-
OS="$(uname -s)"
102-
ARCH="$(uname -m)"
103-
104-
case "$OS" in
105-
Linux) ACTIONLINT_OS="linux" ;;
106-
Darwin) ACTIONLINT_OS="darwin" ;;
107-
*)
108-
echo "Unsupported OS for actionlint: $OS" >&2
109-
exit 1
110-
;;
111-
esac
112-
113-
case "$ARCH" in
114-
x86_64|amd64) ACTIONLINT_ARCH="amd64" ;;
115-
arm64|aarch64) ACTIONLINT_ARCH="arm64" ;;
116-
*)
117-
echo "Unsupported architecture for actionlint: $ARCH" >&2
118-
exit 1
119-
;;
120-
esac
121-
122-
verify_sha256() {
123-
local checksum_file="$1"
124-
if command -v sha256sum >/dev/null 2>&1; then
125-
sha256sum -c "$checksum_file"
126-
else
127-
shasum -a 256 -c "$checksum_file"
128-
fi
129-
}
130-
131-
VERSION="${ACTIONLINT_VERSION}"
132-
TARBALL="actionlint_${VERSION}_${ACTIONLINT_OS}_${ACTIONLINT_ARCH}.tar.gz"
133-
CHECKSUMS_FILE="actionlint_${VERSION}_checksums.txt"
134-
BASE_URL="https://github.com/rhysd/actionlint/releases/download/v${VERSION}"
135-
136-
tmpdir="$(mktemp -d)"
137-
trap 'rm -rf "$tmpdir"' EXIT
138-
139-
curl -fsSL "${BASE_URL}/${TARBALL}" -o "$tmpdir/$TARBALL"
140-
curl -fsSL "${BASE_URL}/${CHECKSUMS_FILE}" -o "$tmpdir/$CHECKSUMS_FILE"
141-
142-
orig_dir="$PWD"
143-
cd "$tmpdir"
144-
awk -v f="$TARBALL" '$NF==f {print; found=1} END {exit found?0:1}' "$CHECKSUMS_FILE" > checksum.txt
145-
verify_sha256 checksum.txt
146-
cd "$orig_dir"
147-
148-
tar -xzf "$tmpdir/$TARBALL" -C "$tmpdir"
149-
150-
actionlint_path="$(find "$tmpdir" -type f -name actionlint | head -n 1)"
151-
if [[ -z "$actionlint_path" ]]; then
152-
echo "actionlint binary not found in $TARBALL" >&2
153-
exit 1
154-
fi
155-
156-
sudo install -m 0755 "$actionlint_path" /usr/local/bin/actionlint
157-
158-
- name: actionlint -version
159-
if: matrix.os != 'windows-latest'
160-
run: actionlint -version
161-
162-
- name: Install additional tools (Linux)
163-
if: matrix.os == 'ubuntu-latest'
164-
run: |
165-
# Install shellcheck, jq, and yamllint
166-
sudo apt-get update
167-
sudo apt-get install -y shellcheck jq yamllint
168-
169-
# Install shfmt (pinned for CI consistency)
170-
SHFMT_ASSET="shfmt_v${SHFMT_VERSION}_linux_amd64"
171-
SHFMT_BASE_URL="https://github.com/mvdan/sh/releases/download/v${SHFMT_VERSION}"
172-
173-
tmpdir="$(mktemp -d)"
174-
trap 'rm -rf "$tmpdir"' EXIT
175-
176-
curl -fsSL \
177-
"${SHFMT_BASE_URL}/${SHFMT_ASSET}" \
178-
-o "$tmpdir/${SHFMT_ASSET}"
179-
curl -fsSL \
180-
"${SHFMT_BASE_URL}/sha256sums.txt" \
181-
-o "$tmpdir/sha256sums.txt"
182-
183-
(
184-
cd "$tmpdir"
185-
awk -v f="${SHFMT_ASSET}" '$NF==f {print; found=1} END {exit found?0:1}' sha256sums.txt > checksum.txt
186-
sha256sum -c checksum.txt
187-
)
188-
189-
sudo install -m 0755 "$tmpdir/${SHFMT_ASSET}" /usr/local/bin/shfmt
190-
191-
- name: Install additional tools (macOS)
192-
if: matrix.os == 'macos-latest'
193-
run: |
194-
# Install shellcheck, jq, and yamllint via Homebrew
195-
brew install shellcheck jq yamllint
196-
197-
# Install shfmt (pinned for CI consistency with Linux)
198-
SHFMT_ARCH="amd64"
199-
if [[ "$(uname -m)" == "arm64" ]]; then
200-
SHFMT_ARCH="arm64"
201-
fi
202-
203-
SHFMT_ASSET="shfmt_v${SHFMT_VERSION}_darwin_${SHFMT_ARCH}"
204-
SHFMT_BASE_URL="https://github.com/mvdan/sh/releases/download/v${SHFMT_VERSION}"
205-
206-
tmpdir="$(mktemp -d)"
207-
trap 'rm -rf "$tmpdir"' EXIT
208-
209-
curl -fsSL \
210-
"${SHFMT_BASE_URL}/${SHFMT_ASSET}" \
211-
-o "$tmpdir/${SHFMT_ASSET}"
212-
curl -fsSL \
213-
"${SHFMT_BASE_URL}/sha256sums.txt" \
214-
-o "$tmpdir/sha256sums.txt"
215-
216-
(
217-
cd "$tmpdir"
218-
awk -v f="${SHFMT_ASSET}" '$NF==f {print; found=1} END {exit found?0:1}' sha256sums.txt > checksum.txt
219-
shasum -a 256 -c checksum.txt
220-
)
221-
222-
sudo install -m 0755 "$tmpdir/${SHFMT_ASSET}" /usr/local/bin/shfmt
223-
224-
- name: Run CI checks (Linux/macOS)
225-
if: matrix.os != 'windows-latest'
226-
run: just ci
124+
- name: Install cargo-nextest
125+
uses: taiki-e/cache-cargo-install-action@417450f3c33ee20393705369577571770643d4c7 # v3.0.7
126+
with:
127+
tool: cargo-nextest@${{ env.CARGO_NEXTEST_VERSION }}
227128

228-
- name: Build and test (Windows)
229-
if: matrix.os == 'windows-latest'
230-
run: |
231-
cargo build --verbose --all-targets
232-
cargo test --lib --verbose
233-
cargo test --doc --verbose
234-
cargo test --tests --verbose
235-
cargo test --features exact --verbose
129+
- name: Run CI checks
130+
run: just ci

‎.github/workflows/codacy.yml‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ jobs:
5050
# Checkout the repository to the GitHub Actions runner
5151
- name: Checkout code
5252
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
53+
with:
54+
persist-credentials: false
5355

5456
- name: Set Codacy paths
5557
run: |
@@ -81,7 +83,7 @@ jobs:
8183
- name: Run Codacy Analysis CLI
8284
if: ${{ env.CODACY_PROJECT_TOKEN != '' }}
8385
id: codacy_analysis
84-
uses: codacy/codacy-analysis-cli-action@562ee3e92b8e92df8b67e0a5ff8aa8e261919c08
86+
uses: codacy/codacy-analysis-cli-action@562ee3e92b8e92df8b67e0a5ff8aa8e261919c08 # pinned
8587
with:
8688
# Check https://github.com/codacy/codacy-analysis-cli#project-token
8789
# to get your project token from your Codacy repository.
@@ -162,7 +164,7 @@ jobs:
162164
# Upload the identified SARIF file
163165
- name: Upload identified SARIF file
164166
if: always() && env.SARIF_FILE != ''
165-
uses: github/codeql-action/upload-sarif@b36bf259c813715f76eafece573914b94412cd13 # v3
167+
uses: github/codeql-action/upload-sarif@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0
166168
with:
167169
sarif_file: ${{ env.SARIF_FILE }}
168170
continue-on-error: true

0 commit comments

Comments
 (0)