Repository navigation
165 lines (154 loc) · 6.9 KB
/
Copy pathdry-run.yml
File metadata and controls
165 lines (154 loc) · 6.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# Manual trigger: test everything before pushing a release.
# Each step can be skipped for faster iteration.
#
# Pipeline: lint → test → build + candidate scan/select → smoke/soak
# Security: security-static + license-gate (independent island)
# CodeQL: codeql.yml full scan of this commit + alert check (independent island)
#
# Security and CodeQL do NOT block lint/test/build/smoke/soak. All jobs must pass
# for the overall workflow to be green.
#
# Candidate VirusTotal scanning and tuple-local selection are part of the
# reusable build boundary. Smoke and soak therefore start only after all 16
# stripped/unstripped candidates have completed and the selected exact bytes
# have been packaged under the canonical artifact names.
#
# The skips are independent because they answer different questions:
# skip_builds no artifacts at all "do lint and tests pass?"
# skip_smoke build + scan/select, no smoke "does this diff scan red?"
# skip_virustotal default-stripped + smoke, no scan "do the archives pass CI?"
#
# skip_virustotal is a conspicuous dry-run-only bypass for API-quota-sensitive
# iteration. It records unscanned-dry-run and deterministically chooses stripped
# within each tuple. release.yml has no corresponding bypass.
name: Dry Run
on:
workflow_dispatch:
inputs:
skip_lint:
description: 'Skip lint (cppcheck + clang-format)'
type: boolean
default: false
skip_tests:
description: 'Skip unit/integration tests'
type: boolean
default: false
skip_builds:
description: 'Skip build + smoke (also skips VirusTotal — nothing to scan)'
type: boolean
default: false
skip_smoke:
description: 'Skip smoke (candidate scan/select still runs inside build)'
type: boolean
default: false
skip_virustotal:
description: 'Skip candidate scan; mark unscanned and default to stripped'
type: boolean
default: false
skip_memwaste:
description: 'Skip the waste sanitizer (report-only) and the fuzz smoke'
type: boolean
default: false
soak_level:
description: 'Soak: full (quick+asan), quick (10min), none'
type: choice
options: ['full', 'quick', 'none']
default: 'quick'
permissions:
contents: read
jobs:
# ── Security (independent island — does not block main pipeline) ──
security:
uses: ./.github/workflows/_security.yml
permissions:
contents: read
security-events: read
actions: read
secrets: inherit
# ── CodeQL: full scan of this exact commit + the open-alert check ──
# Every language, vendored C included (PRs run the narrower PR scan).
# codeql.yml uploads results and reads the alerts: a called workflow
# cannot request more than its caller grants, so withholding either
# permission fails the whole run at startup.
codeql:
uses: ./.github/workflows/codeql.yml
permissions:
contents: read
security-events: write
actions: read
# ── Lint (cppcheck + clang-format) ────────────────────────────
lint:
if: ${{ inputs.skip_lint != true }}
uses: ./.github/workflows/_lint.yml
# ── Tests (all platforms, perf tests skipped on CI) ────────────
test:
needs: [lint]
if: ${{ inputs.skip_tests != true && !cancelled() && (needs.lint.result == 'success' || needs.lint.result == 'skipped') }}
uses: ./.github/workflows/_test.yml
with:
skip_perf: true
broad_platforms: true
shard_suites: true
# ── Build all platforms ────────────────────────────────────────
build:
if: ${{ inputs.skip_builds != true && !cancelled() && (needs.test.result == 'success' || needs.test.result == 'skipped') }}
needs: [test]
permissions:
contents: read
id-token: write
attestations: write
uses: ./.github/workflows/_build.yml
with:
attest: false
scan_candidates: ${{ !inputs.skip_virustotal }}
secrets: inherit
# ── Smoke test every binary ────────────────────────────────────
# Run unless builds were skipped or a build leg FAILED. Every build leg
# (including the macos-15-intel darwin-amd64 binary) is blocking now, so a
# failed/missing platform binary correctly stops smoke — see _build.yml.
smoke:
if: ${{ inputs.skip_builds != true && inputs.skip_smoke != true && !cancelled() && needs.build.result != 'failure' && needs.build.result != 'skipped' }}
needs: [build]
uses: ./.github/workflows/_smoke.yml
with:
broad_platforms: true
# ── Waste sanitizer, REPORT-ONLY (independent island) ─────────
# Event lane on Linux, macOS and Windows, access lane and the per-function
# scaling lane on Linux. Uploads reports; fails only when the measurement is
# unsound (a defect of the tool itself).
memwaste:
if: ${{ inputs.skip_memwaste != true }}
uses: ./.github/workflows/_memwaste.yml
with:
mode: full
# ── Fuzz smoke (independent island) ───────────────────────────
# A fixed number of executions from a fixed seed per target, so the verdict is
# a function of the commit (O9). A crash here is a real defect in a parser
# that reads untrusted input; its reproducer is uploaded.
fuzz:
if: ${{ inputs.skip_memwaste != true }}
runs-on: ubuntu-latest
timeout-minutes: 90
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install deps
timeout-minutes: 10
run: APT_RETRIES=3; [ -f /etc/apt/apt-mirrors.txt ] && APT_RETRIES=0; sudo apt-get -o Acquire::Retries=$APT_RETRIES -o Acquire::http::Timeout=30 -o Acquire::https::Timeout=30 --error-on=any update && sudo apt-get -o Acquire::Retries=$APT_RETRIES -o Acquire::http::Timeout=30 -o Acquire::https::Timeout=30 install -y zlib1g-dev clang llvm libclang-rt-dev
- name: Fuzz smoke (extract, cypher, config)
run: scripts/fuzz.sh all --runs 20000 --seed 1
- name: Upload reproducers
if: ${{ failure() }}
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: fuzz-artifacts
path: build/fuzz/artifacts-*/
if-no-files-found: ignore
# ── Soak tests (optional, parallel with smoke) ────────────────
soak:
if: ${{ inputs.soak_level != 'none' && !cancelled() && needs.build.result != 'failure' && needs.build.result != 'skipped' }}
needs: [build]
uses: ./.github/workflows/_soak.yml
with:
duration_minutes: 10
run_asan: ${{ inputs.soak_level == 'full' }}
use_release_artifacts: true