Skip to content

Commit d47263b

Browse files
authored
Merge pull request #1668 from EliahKagan/run-ci/gha-permissions
Improve CI `permissions`, auto-merge maintainability, and clarity
2 parents ccd6525 + 132696d commit d47263b

11 files changed

+1191
-735
lines changed

.github/dependabot.yml

+10-7
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
version: 2
22
updates:
3-
- package-ecosystem: github-actions
4-
directory: "/"
5-
schedule:
6-
interval: weekly
7-
groups:
8-
github-actions:
9-
patterns: ["*"]
3+
# We only use Dependabot *version* updates for GitHub Actions. Rust dependencies are checked via
4+
# `cargo deny` and manually updated (see https://github.com/GitoxideLabs/gitoxide/issues/144), or
5+
# by Dependabot *security* updates (which don't need the `cargo` ecosystem to be listed here).
6+
- package-ecosystem: github-actions
7+
directory: '/'
8+
schedule:
9+
interval: weekly
10+
groups:
11+
github-actions:
12+
patterns: ['*']

.github/dependabot.yml.disabled-see-issue-144

-8
This file was deleted.

.github/pull_request_template.md

Whitespace-only changes.

.github/workflows/ci.yml

+124-42
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
name: ci
22

3-
env:
4-
CARGO_TERM_COLOR: always
5-
CLICOLOR: 1
6-
73
on:
84
push:
95
branches:
@@ -17,10 +13,19 @@ on:
1713
- main
1814
workflow_dispatch:
1915

16+
permissions:
17+
contents: read
18+
19+
env:
20+
CARGO_TERM_COLOR: always
21+
CLICOLOR: '1'
22+
2023
jobs:
2124
pure-rust-build:
2225
runs-on: ubuntu-latest
26+
2327
container: debian:stable-slim
28+
2429
steps:
2530
- uses: actions/checkout@v4
2631
- name: Prerequisites
@@ -31,14 +36,14 @@ jobs:
3136
run: |
3237
set -x
3338
for pattern in cmake g++ libssl-dev make pkgconf pkg-config; do
34-
if dpkg-query --status -- "$pattern"; then
35-
exit 1
36-
fi
39+
if dpkg-query --status -- "$pattern"; then
40+
exit 1
41+
fi
3742
done
3843
for cmd in cmake g++ make pkgconf pkg-config; do
39-
if command -v -- "$cmd"; then
40-
exit 1
41-
fi
44+
if command -v -- "$cmd"; then
45+
exit 1
46+
fi
4247
done
4348
- name: Install Rust via Rustup
4449
run: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal
@@ -47,21 +52,20 @@ jobs:
4752

4853
test:
4954
runs-on: ubuntu-latest
55+
5056
steps:
5157
- uses: actions/checkout@v4
5258
- uses: dtolnay/rust-toolchain@stable
5359
- uses: Swatinem/rust-cache@v2
5460
- name: Setup dependencies
55-
run:
56-
sudo apt-get install -y --no-install-recommends liblzma-dev tree
61+
run: sudo apt-get install -y --no-install-recommends liblzma-dev tree
5762
- uses: extractions/setup-just@v2
5863
- uses: taiki-e/install-action@v2
5964
with:
6065
tool: nextest
6166
- name: test
6267
env:
63-
CI: true
64-
GIX_TEST_IGNORE_ARCHIVES: 1
68+
GIX_TEST_IGNORE_ARCHIVES: '1'
6569
run: just ci-test
6670

6771
test-fast:
@@ -71,7 +75,9 @@ jobs:
7175
- windows-latest
7276
- macos-latest
7377
- ubuntu-latest
78+
7479
runs-on: ${{ matrix.os }}
80+
7581
steps:
7682
- uses: actions/checkout@v4
7783
- uses: dtolnay/rust-toolchain@stable
@@ -88,7 +94,7 @@ jobs:
8894
tool: nextest
8995
- name: "Test (nextest)"
9096
env:
91-
GIX_TEST_CREATE_ARCHIVES_EVEN_ON_CI: 1
97+
GIX_TEST_CREATE_ARCHIVES_EVEN_ON_CI: '1'
9298
run: cargo nextest run --workspace --no-fail-fast
9399
- name: Doctest
94100
run: cargo test --workspace --doc --no-fail-fast
@@ -97,6 +103,7 @@ jobs:
97103

98104
test-fixtures-windows:
99105
runs-on: windows-latest
106+
100107
steps:
101108
- uses: actions/checkout@v4
102109
- uses: dtolnay/rust-toolchain@stable
@@ -119,8 +126,8 @@ jobs:
119126
[xml]$junit_xml = Get-Content -Path 'target/nextest/with-xml/junit.xml'
120127
121128
$actual_failures = $junit_xml.SelectNodes("//testcase[failure]") |
122-
ForEach-Object { "$($_.classname) $($_.name)" } |
123-
Sort-Object
129+
ForEach-Object { "$($_.classname) $($_.name)" } |
130+
Sort-Object
124131
125132
Write-Output $actual_failures
126133
Set-Content -Path 'actual-failures.txt' -Value $actual_failures
@@ -129,13 +136,15 @@ jobs:
129136
# Fail on any differences, even unexpectedly passing tests, so they can be investigated.
130137
# (If the job is made blocking for PRs, it may make sense to make this less stringent.)
131138
git --no-pager diff --no-index --exit-code --unified=1000000 --color=always -- `
132-
etc/test-fixtures-windows-expected-failures-see-issue-1358.txt actual-failures.txt
139+
etc/test-fixtures-windows-expected-failures-see-issue-1358.txt actual-failures.txt
133140
134141
test-32bit:
135142
runs-on: ubuntu-latest
143+
136144
strategy:
137145
matrix:
138146
target: [ armv7-linux-androideabi ]
147+
139148
steps:
140149
- uses: actions/checkout@v4
141150
- uses: dtolnay/rust-toolchain@stable
@@ -157,6 +166,7 @@ jobs:
157166

158167
lint:
159168
runs-on: ubuntu-latest
169+
160170
steps:
161171
- uses: actions/checkout@v4
162172
- uses: dtolnay/rust-toolchain@master
@@ -170,17 +180,21 @@ jobs:
170180
run: just doc
171181
- name: Run cargo fmt
172182
run: cargo fmt --all -- --check
173-
- name: Run cargo diet
183+
- name: Install cargo diet
184+
env:
185+
CARGO_DIET_TAG: v1.2.7
174186
run: |
175-
curl -LSfs https://raw.githubusercontent.com/the-lean-crate/cargo-diet/master/ci/install.sh | \
176-
sh -s -- --git the-lean-crate/cargo-diet --target x86_64-unknown-linux-musl --tag v1.2.4
177-
178-
# Let's not fail CI for this, it will fail locally often enough, and a crate a little bigger
179-
# than allows is no problem either if it comes to that.
180-
just check-size || true
187+
curl -LSfs "https://raw.githubusercontent.com/the-lean-crate/cargo-diet/refs/tags/$CARGO_DIET_TAG/ci/install.sh" |
188+
sh -s -- --git the-lean-crate/cargo-diet --target x86_64-unknown-linux-musl --tag "$CARGO_DIET_TAG"
189+
- name: Run cargo diet
190+
run: just check-size
191+
# Let's not fail CI for this, it will fail locally often enough, and a crate a little bigger
192+
# than allows is no problem either if it comes to that.
193+
continue-on-error: true
181194

182195
cargo-deny:
183196
runs-on: ubuntu-latest
197+
184198
strategy:
185199
matrix:
186200
checks:
@@ -198,27 +212,51 @@ jobs:
198212

199213
wasm:
200214
name: WebAssembly
215+
201216
runs-on: ubuntu-latest
202-
continue-on-error: true
217+
203218
strategy:
204219
matrix:
205220
target: [ wasm32-unknown-unknown, wasm32-wasi ]
221+
222+
env:
223+
TARGET: ${{ matrix.target }}
224+
206225
steps:
207-
- uses: actions/checkout@master
226+
- uses: actions/checkout@v4
208227
- name: Install Rust
209-
run: rustup update stable && rustup default stable && rustup target add ${{ matrix.target }}
228+
run: |
229+
rustup update stable
230+
rustup default stable
231+
rustup target add "$TARGET"
210232
- uses: Swatinem/rust-cache@v2
211-
- run: set +x; for name in gix-sec; do (cd $name && cargo build --target ${{ matrix.target }}); done
212-
name: "WASI only: crates without feature toggle"
233+
- name: 'WASI only: crates without feature toggle'
213234
if: endsWith(matrix.target, '-wasi')
214-
- run: set +x; for name in gix-actor gix-attributes gix-bitmap gix-chunk gix-command gix-commitgraph gix-config-value gix-date gix-glob gix-hash gix-hashtable gix-mailmap gix-object gix-packetline gix-path gix-pathspec gix-prompt gix-quote gix-refspec gix-revision gix-traverse gix-url gix-validate; do (cd $name && cargo build --target ${{ matrix.target }}); done
215-
name: crates without feature toggles
216-
- run: set +x; for feature in progress fs-walkdir-parallel parallel io-pipe crc32 zlib zlib-rust-backend fast-sha1 rustsha1 cache-efficiency-debug; do (cd gix-features && cargo build --features $feature --target ${{ matrix.target }}); done
217-
name: features of gix-features
218-
- run: set +x; for name in gix-pack; do (cd $name && cargo build --features wasm --target ${{ matrix.target }}); done
219-
name: crates with 'wasm' feature
220-
- run: cd gix-pack && cargo build --all-features --target ${{ matrix.target }}
221-
name: gix-pack with all features (including wasm)
235+
run: |
236+
set +x
237+
for name in gix-sec; do
238+
(cd -- "$name" && cargo build --target "$TARGET")
239+
done
240+
- name: crates without feature toggles
241+
run: |
242+
set +x
243+
for name in gix-actor gix-attributes gix-bitmap gix-chunk gix-command gix-commitgraph gix-config-value gix-date gix-glob gix-hash gix-hashtable gix-mailmap gix-object gix-packetline gix-path gix-pathspec gix-prompt gix-quote gix-refspec gix-revision gix-traverse gix-url gix-validate; do
244+
(cd -- "$name" && cargo build --target "$TARGET")
245+
done
246+
- name: features of gix-features
247+
run: |
248+
set +x
249+
for feature in progress fs-walkdir-parallel parallel io-pipe crc32 zlib zlib-rust-backend fast-sha1 rustsha1 cache-efficiency-debug; do
250+
(cd gix-features && cargo build --features "$feature" --target "$TARGET")
251+
done
252+
- name: crates with 'wasm' feature
253+
run: |
254+
set +x
255+
for name in gix-pack; do
256+
(cd -- "$name" && cargo build --features wasm --target "$TARGET")
257+
done
258+
- name: gix-pack with all features (including wasm)
259+
run: cd gix-pack && cargo build --all-features --target "$TARGET"
222260

223261
check-packetline:
224262
strategy:
@@ -230,10 +268,13 @@ jobs:
230268
# However, when changes are made to `etc/copy-packetline.sh`, re-enable the other platforms for testing.
231269
# - macos-latest
232270
# - windows-latest
271+
233272
runs-on: ${{ matrix.os }}
273+
234274
defaults:
235275
run:
236276
shell: bash
277+
237278
steps:
238279
- uses: actions/checkout@v4
239280
- name: Check that working tree is initially clean
@@ -249,22 +290,63 @@ jobs:
249290
git status
250291
git diff --exit-code
251292
293+
# Check that only jobs intended not to block PR auto-merge are omitted as
294+
# dependencies of the `tests-pass` job below, so that whenever a job is
295+
# added, a decision is made about whether it must pass for PRs to merge.
296+
check-blocking:
297+
runs-on: ubuntu-latest
298+
299+
env:
300+
# List all jobs that are intended NOT to block PR auto-merge here.
301+
EXPECTED_NONBLOCKING_JOBS: |-
302+
test-fixtures-windows
303+
wasm
304+
tests-pass
305+
306+
defaults:
307+
run:
308+
shell: bash # Without specifying this, we don't get `-o pipefail`.
309+
310+
steps:
311+
- name: Find this workflow
312+
run: |
313+
relative_workflow_with_ref="${GITHUB_WORKFLOW_REF#"$GITHUB_REPOSITORY/"}"
314+
echo "WORKFLOW_PATH=${relative_workflow_with_ref%@*}" >> "$GITHUB_ENV"
315+
- uses: actions/checkout@v4
316+
with:
317+
sparse-checkout: ${{ env.WORKFLOW_PATH }}
318+
- name: Get all jobs
319+
run: yq '.jobs | keys.[]' -- "$WORKFLOW_PATH" | sort | tee all-jobs.txt
320+
- name: Get blocking jobs
321+
run: yq '.jobs.tests-pass.needs.[]' -- "$WORKFLOW_PATH" | sort | tee blocking-jobs.txt
322+
- name: Get jobs we intend do not block
323+
run: sort <<<"$EXPECTED_NONBLOCKING_JOBS" | tee expected-nonblocking-jobs.txt
324+
- name: Each job must block PRs or be declared not to
325+
run: |
326+
sort -m blocking-jobs.txt expected-nonblocking-jobs.txt |
327+
diff --color=always -U1000 -- - all-jobs.txt
328+
252329
# Dummy job to have a stable name for the "all tests pass" requirement
253330
tests-pass:
254331
name: Tests pass
332+
255333
needs:
256334
- pure-rust-build
257335
- test
258336
- test-fast
259337
- test-32bit
260338
- lint
261339
- cargo-deny
262-
- wasm
263340
- check-packetline
341+
- check-blocking
342+
264343
if: always() # always run even if dependencies fail
344+
265345
runs-on: ubuntu-latest
346+
266347
steps:
267-
# fail if ANY dependency has failed or cancelled
268-
- if: "contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')"
348+
- name: Fail if ANY dependency has failed or cancelled
349+
if: "contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')"
269350
run: exit 1
270-
- run: exit 0
351+
- name: OK
352+
run: exit 0

0 commit comments

Comments
 (0)