Skip to content

Commit cb63a01

Browse files
committed
ci: aligner l'automatisation GitHub Actions sur grob
- ci.yml: merge-queue (merge_group) + push.paths-ignore (docs/md/license...) - nouveaux workflows adaptes au workspace (crates/**): codeql, semgrep, shellcheck, nightly, audit-cron, auto-update-branch, auto-merge-release - release-plz.yml: corrige le filtre de chemins src/** -> crates/** (le workflow ne se declenchait jamais sur les sources du workspace) - cla.yml volontairement non porte (CLA contributeurs externes, secret/stockage dedies) ; cleanup-branches.yml reste a porter - etapes dependant d'un secret optionnel rendues resilientes (pas de CI rouge si secret absent)
1 parent 274a4c3 commit cb63a01

9 files changed

Lines changed: 397 additions & 1 deletion

File tree

.github/workflows/audit-cron.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: Security Audit (daily)
2+
3+
# Runs `cargo audit` and `cargo deny` on a fixed cron so newly-published CVEs
4+
# and dependency policy regressions are caught even if the repository has not
5+
# been modified.
6+
7+
on:
8+
schedule:
9+
# 04:17 UTC daily - off-peak for GitHub Actions scheduler.
10+
- cron: "17 4 * * *"
11+
workflow_dispatch:
12+
13+
permissions:
14+
contents: read
15+
issues: write
16+
17+
concurrency:
18+
group: audit-cron-${{ github.ref }}
19+
cancel-in-progress: true
20+
21+
jobs:
22+
audit:
23+
name: cargo audit (scheduled)
24+
runs-on: ubuntu-latest
25+
timeout-minutes: 10
26+
steps:
27+
- uses: step-security/harden-runner@v2
28+
with:
29+
egress-policy: audit
30+
- uses: actions/checkout@v6
31+
- uses: rustsec/audit-check@v2.0.0
32+
with:
33+
token: ${{ secrets.GITHUB_TOKEN }}
34+
35+
deny:
36+
name: cargo deny (scheduled)
37+
runs-on: ubuntu-latest
38+
timeout-minutes: 10
39+
steps:
40+
- uses: step-security/harden-runner@v2
41+
with:
42+
egress-policy: audit
43+
- uses: actions/checkout@v6
44+
- uses: EmbarkStudios/cargo-deny-action@v2
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: Auto-merge release PRs
2+
3+
on:
4+
pull_request:
5+
types: [opened, reopened, labeled, synchronize, ready_for_review]
6+
7+
permissions:
8+
contents: write
9+
pull-requests: write
10+
11+
jobs:
12+
auto-merge:
13+
if: >-
14+
contains(github.event.pull_request.labels.*.name, 'release')
15+
&& startsWith(github.event.pull_request.head.ref, 'release-plz-')
16+
&& github.event.pull_request.head.repo.full_name == github.repository
17+
runs-on: ubuntu-latest
18+
env:
19+
HAS_RELEASE_PLZ_TOKEN: ${{ secrets.RELEASE_PLZ_TOKEN != '' }}
20+
steps:
21+
- name: Skip when RELEASE_PLZ_TOKEN is missing
22+
if: env.HAS_RELEASE_PLZ_TOKEN != 'true'
23+
run: echo "::notice::RELEASE_PLZ_TOKEN is not configured; release PR auto-merge skipped."
24+
25+
- name: Enable auto-merge
26+
if: env.HAS_RELEASE_PLZ_TOKEN == 'true'
27+
run: gh pr merge --auto --squash "$PR_URL"
28+
env:
29+
PR_URL: ${{ github.event.pull_request.html_url }}
30+
GH_TOKEN: ${{ secrets.RELEASE_PLZ_TOKEN }}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: Auto-update PR branches on main push
2+
3+
on:
4+
push:
5+
branches: [main]
6+
7+
permissions:
8+
contents: write
9+
pull-requests: write
10+
11+
jobs:
12+
update-prs:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: Update BEHIND PRs with auto-merge
16+
run: |
17+
gh pr list --base main --state open --json number,autoMergeRequest,mergeStateStatus \
18+
--jq '.[] | select(.autoMergeRequest != null) | select(.mergeStateStatus=="BEHIND") | .number' \
19+
| while read -r pr; do
20+
echo "Updating PR #${pr}"
21+
gh pr update-branch "${pr}" || echo "Skip PR #${pr}"
22+
done
23+
env:
24+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/ci.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,21 @@
11
name: CI
22

33
on:
4+
merge_group:
45
push:
56
branches: [main]
67
tags:
78
- "v*"
9+
paths-ignore:
10+
- "docs/**"
11+
- "**.md"
12+
- "LICENSE*"
13+
- ".editorconfig"
14+
- ".gitignore"
15+
- ".gitattributes"
16+
- "**.txt"
17+
- "CODEOWNERS"
18+
- ".vscode/**"
819
pull_request:
920
workflow_dispatch:
1021
inputs:

.github/workflows/codeql.yml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name: "CodeQL Security Analysis"
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths:
7+
- "crates/**"
8+
- "Cargo.toml"
9+
- "Cargo.lock"
10+
- ".github/workflows/codeql.yml"
11+
pull_request:
12+
branches: [main]
13+
paths:
14+
- "crates/**"
15+
- "Cargo.toml"
16+
- "Cargo.lock"
17+
- ".github/workflows/codeql.yml"
18+
schedule:
19+
# Weekly scan (Mondays 06:00 UTC)
20+
- cron: "0 6 * * 1"
21+
22+
permissions:
23+
security-events: write
24+
contents: read
25+
26+
jobs:
27+
analyze:
28+
name: CodeQL Rust Analysis
29+
runs-on: macos-latest
30+
timeout-minutes: 30
31+
32+
steps:
33+
- name: Checkout
34+
uses: actions/checkout@v6
35+
36+
- name: Install Rust toolchain
37+
uses: dtolnay/rust-toolchain@stable
38+
39+
- name: Rust cache
40+
uses: Swatinem/rust-cache@v2
41+
with:
42+
shared-key: codeql
43+
save-if: ${{ github.ref == 'refs/heads/main' }}
44+
45+
- name: Initialize CodeQL
46+
uses: github/codeql-action/init@v3
47+
with:
48+
languages: rust
49+
50+
- name: Build for CodeQL
51+
run: cargo build --workspace --release --locked
52+
53+
- name: Perform CodeQL Analysis
54+
uses: github/codeql-action/analyze@v3
55+
with:
56+
category: "/language:rust"

.github/workflows/nightly.yml

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
name: Nightly Toolchain Check
2+
3+
on:
4+
schedule:
5+
# Every day at 03:00 UTC.
6+
- cron: "0 3 * * *"
7+
workflow_dispatch:
8+
9+
permissions:
10+
contents: read
11+
issues: write # Used by the failure alert step below
12+
13+
env:
14+
CARGO_INCREMENTAL: 0
15+
CARGO_NET_RETRY: 10
16+
RUST_BACKTRACE: short
17+
18+
jobs:
19+
check:
20+
name: ${{ matrix.toolchain }} / ${{ matrix.scope }} / ${{ matrix.os }}
21+
runs-on: ${{ matrix.os }}
22+
# Nightly may break - allow failure. Beta must pass.
23+
continue-on-error: ${{ matrix.toolchain == 'nightly' }}
24+
timeout-minutes: 30
25+
strategy:
26+
fail-fast: false
27+
matrix:
28+
include:
29+
- toolchain: beta
30+
os: macos-latest
31+
scope: workspace
32+
cargo_args: "--workspace --all-features"
33+
- toolchain: nightly
34+
os: macos-latest
35+
scope: workspace
36+
cargo_args: "--workspace --all-features"
37+
- toolchain: beta
38+
os: ubuntu-latest
39+
scope: pure-crates
40+
cargo_args: "-p dunst-core -p dunst-graph -p dunst-vision"
41+
- toolchain: nightly
42+
os: ubuntu-latest
43+
scope: pure-crates
44+
cargo_args: "-p dunst-core -p dunst-graph -p dunst-vision"
45+
steps:
46+
- uses: step-security/harden-runner@v2
47+
with:
48+
egress-policy: audit
49+
- uses: actions/checkout@v6
50+
with:
51+
ref: main
52+
- uses: dtolnay/rust-toolchain@master
53+
with:
54+
toolchain: ${{ matrix.toolchain }}
55+
components: clippy
56+
- uses: Swatinem/rust-cache@v2
57+
with:
58+
shared-key: nightly-${{ matrix.toolchain }}-${{ matrix.scope }}-${{ matrix.os }}
59+
save-if: true
60+
- name: Clippy
61+
run: cargo clippy ${{ matrix.cargo_args }} --all-targets --locked -- -D warnings
62+
- name: Tests
63+
run: cargo test ${{ matrix.cargo_args }} --all-targets --locked
64+
- name: Doc tests
65+
run: cargo test ${{ matrix.cargo_args }} --doc --locked
66+
67+
# Open (or reuse) a tracking issue when the BETA matrix fails. Nightly
68+
# failures stay silent (they are allowed to break). Avoids spamming: the
69+
# step searches for an open "nightly-toolchain" labeled issue and comments
70+
# on it instead of creating duplicates.
71+
alert:
72+
name: Alert on beta regression
73+
needs: [check]
74+
if: always() && contains(needs.check.result, 'failure') && github.event_name == 'schedule'
75+
runs-on: ubuntu-latest
76+
timeout-minutes: 5
77+
steps:
78+
- uses: step-security/harden-runner@v2
79+
with:
80+
egress-policy: audit
81+
- name: Open or update tracking issue
82+
uses: actions/github-script@v7
83+
with:
84+
script: |
85+
const label = 'nightly-toolchain';
86+
const title = `Beta/nightly toolchain regression (${new Date().toISOString().slice(0,10)})`;
87+
const body = [
88+
`Nightly run ${context.runId} observed a failure on the \`beta\` or \`nightly\` toolchain.`,
89+
``,
90+
`Run: ${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`,
91+
``,
92+
`If this is a nightly-only soft failure, close the issue. If beta is broken, this is a release blocker.`,
93+
].join('\n');
94+
const { data: issues } = await github.rest.issues.listForRepo({
95+
owner: context.repo.owner,
96+
repo: context.repo.repo,
97+
state: 'open',
98+
labels: label,
99+
per_page: 1,
100+
});
101+
if (issues.length > 0) {
102+
await github.rest.issues.createComment({
103+
owner: context.repo.owner,
104+
repo: context.repo.repo,
105+
issue_number: issues[0].number,
106+
body,
107+
});
108+
} else {
109+
await github.rest.issues.create({
110+
owner: context.repo.owner,
111+
repo: context.repo.repo,
112+
title,
113+
body,
114+
labels: [label],
115+
});
116+
}

.github/workflows/release-plz.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ on:
99
branches:
1010
- main
1111
paths:
12-
- "src/**"
12+
- "crates/**"
1313
- "Cargo.toml"
1414
- "Cargo.lock"
1515
pull_request:

.github/workflows/semgrep.yml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
name: "Semgrep SAST"
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths:
7+
- "crates/**"
8+
- ".github/workflows/semgrep.yml"
9+
pull_request:
10+
branches: [main]
11+
paths:
12+
- "crates/**"
13+
- ".github/workflows/semgrep.yml"
14+
schedule:
15+
# Weekly scan (Wednesdays 06:00 UTC)
16+
- cron: "0 6 * * 3"
17+
18+
permissions:
19+
security-events: write
20+
contents: read
21+
22+
jobs:
23+
semgrep:
24+
name: Semgrep Rust SAST
25+
runs-on: ubuntu-latest
26+
timeout-minutes: 15
27+
container:
28+
image: semgrep/semgrep:1.144.0
29+
30+
steps:
31+
- uses: actions/checkout@v6
32+
33+
- name: Run Semgrep
34+
run: semgrep scan --config auto --sarif --output semgrep-results.sarif crates/
35+
env:
36+
SEMGREP_RULES: >-
37+
p/rust
38+
p/secrets
39+
p/owasp-top-ten
40+
41+
- name: Upload SARIF
42+
if: always()
43+
uses: github/codeql-action/upload-sarif@v3
44+
with:
45+
sarif_file: semgrep-results.sarif
46+
category: semgrep

0 commit comments

Comments
 (0)