Repository navigation
193 lines (182 loc) · 8.65 KB
/
Copy pathcodeql.yml
File metadata and controls
193 lines (182 loc) · 8.65 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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
name: CodeQL
# This workflow replaces GitHub's CodeQL "default setup" (disabled via the
# code-scanning/default-setup API) with an in-repo "advanced setup" so the
# analysis is disciplined the same way ci.yml is (ADR-0019 spirit).
#
# NOTE on the zombie sidebar entry: the old GitHub default-setup CodeQL
# workflow is disabled (`code-scanning/default-setup` API → `not-configured`)
# and dormant — it has no trigger source and fires nothing. GitHub never
# deletes the registration, so it still *appears* in the Actions sidebar as
# "CodeQL (default setup)"; that entry is purely cosmetic. This advanced
# workflow supersedes it and carries every scan. Nothing to fix in YAML
# (audit finding 1) — documented here so it isn't mistaken for a live
# duplicate scanner.
#
# Default setup ran on every push:main *and* every PR with NO concurrency
# group: rapid squash-merges spun up N parallel main analyses, and even
# docs-only commits got fully scanned. That is pure waste — the PR head is
# the source we care about and it is already analyzed on `pull_request`;
# the post-merge push:main re-run only re-scans the exact same source under
# a new SHA (same rationale ci.yml states for skipping push:main, lines
# ~3-7). So: PR + a weekly baseline only, paths-ignore for non-code, and
# concurrency cancel-in-progress — mirrors ci.yml. (ADR-0036 later added a
# narrow `push:main` trigger scoped to the fast `actions`-only scan purely
# to populate the default-branch Security tab — see the `on:` block; that
# does NOT reinstate the wasteful full per-push re-scan described here.)
#
# paths-ignore also excludes non-code `.github/` config (issue templates,
# CODEOWNERS, dependabot) — same rationale as above: these files cannot
# affect CodeQL findings, so scanning them is pure waste. NOTE: this is
# deliberately NOT a blanket `.github/**` ignore — CodeQL's `actions`
# language legitimately analyzes workflow files, so workflow changes must
# still trigger analysis.
#
# PR-vs-scheduled scope split: CodeQL is advisory/non-required (only the
# ci.yml `build` job gates merges). The heavy java-kotlin scan compiles the
# app (generateApolloSources + assembleDebug) — that was a redundant 3rd
# full compile on every PR, on top of ci.yml's build-debug + build-release
# (ADR-0019). So on `pull_request` we analyze ONLY the `actions` language
# (build-mode none, no Gradle/Android build — fast). The full code scan
# (`actions` + `java-kotlin` with the manual compile) still runs on the
# weekly `schedule` baseline and on-demand via `workflow_dispatch`. Net:
# PRs are back to 2 builds (ci.yml debug ‖ release), full security coverage
# preserved weekly + on demand. The language list is event-driven via the
# `config` job below (a static matrix `include` cannot compose with a
# dynamically-sized language list, so build-mode is derived inline in init).
#
# Default-branch baseline (ADR-0036): a `push:main` trigger is required so
# the Security tab is populated with code-scanning alerts FOR THE DEFAULT
# BRANCH (GitHub only surfaces alerts there from analyses run on `main`;
# `pull_request` analyses do not establish that baseline). To stay within
# PR #130's deliberate cost design (the heavy `java-kotlin` compile is
# weekly/dispatch only, NOT per-PR/per-push), `push:main` is treated
# exactly like `pull_request` by the `config` job — it analyzes ONLY the
# fast `actions` language (build-mode none, no Gradle/Android build). The
# full `actions` + `java-kotlin` scan remains on the weekly `schedule`
# baseline and `workflow_dispatch`, unchanged. Same paths-ignore as
# `pull_request` so non-code default-branch pushes don't scan.
on:
pull_request:
paths-ignore:
- '**/*.md'
- 'docs/**'
- '.claude/**'
- 'LICENSE'
- '.github/ISSUE_TEMPLATE/**'
- '.github/CODEOWNERS'
- '.github/dependabot.yml'
- '.gitignore'
push:
branches: [main]
paths-ignore:
- '**/*.md'
- 'docs/**'
- '.claude/**'
- 'LICENSE'
- '.github/ISSUE_TEMPLATE/**'
- '.github/CODEOWNERS'
- '.github/dependabot.yml'
- '.gitignore'
schedule:
- cron: '27 4 * * 1' # weekly baseline scan (Mondays 04:27 UTC)
workflow_dispatch:
# Least-privilege GITHUB_TOKEN: CodeQL needs to upload SARIF results
# (security-events) and read the repo + Actions metadata; nothing else.
permissions:
contents: read
security-events: write
actions: read
concurrency:
group: codeql-${{ github.ref }}
cancel-in-progress: true
jobs:
# Event-driven language list: PRs scan only `actions` (fast, no build);
# the weekly schedule and manual dispatch scan both languages (the
# java-kotlin entry triggers the manual Gradle/Android compile below).
config:
name: Resolve scan scope
runs-on: ubuntu-latest
outputs:
langs: ${{ steps.scope.outputs.langs }}
steps:
- name: Determine languages for this event
id: scope
run: |
# pull_request AND push:main → fast `actions` only (no Gradle/
# Android build). The push:main run exists solely to populate the
# default-branch Security-tab baseline (ADR-0036); making it
# compile java-kotlin would re-introduce the per-push heavy build
# that PR #130 deliberately moved to weekly/dispatch. Only the
# weekly `schedule` and on-demand `workflow_dispatch` scan BOTH
# languages (java-kotlin → the manual compile below).
if [ "${{ github.event_name }}" = "pull_request" ] || [ "${{ github.event_name }}" = "push" ]; then
echo 'langs=["actions"]' >> "$GITHUB_OUTPUT"
else
echo 'langs=["actions","java-kotlin"]' >> "$GITHUB_OUTPUT"
fi
analyze:
name: Analyze (${{ matrix.language }})
needs: config
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# Dynamic language list from the `config` job (event-driven). A
# static matrix `include` cannot carry per-language `build-mode`
# here because the language set is sized at runtime, so build-mode
# is derived inline in the init step (java-kotlin → manual, else
# none).
#
# History of this file's two bugs:
# 1. It originally passed `language:` (singular) to init. That is
# NOT a valid codeql-action input (valid key: `languages:`).
# init ignored it, autodetected repo languages, and ran
# autobuild for java-kotlin regardless of `build-mode: none`.
# 2. After fixing the key, `build-mode: none` for java-kotlin on
# the pinned CodeQL bundle (2.25.4) STILL invoked the Gradle
# autobuild and produced an empty Java DB → `database finalize`
# aborted with "could not process any code" / exit 32. So
# no-build is not viable for this Android project here.
#
# Fix: `actions` stays build-mode none (no build needed).
# java-kotlin uses build-mode manual with an explicit compile that
# mirrors how this repo builds (ci.yml build-debug / local-ci.sh:
# JDK 21 temurin, setup-gradle, Android SDK, generateApolloSources
# then assembleDebug) so CodeQL traces a real compilation.
language: ${{ fromJSON(needs.config.outputs.langs) }}
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Set up JDK 21
if: matrix.language == 'java-kotlin'
uses: actions/setup-java@v5.6.0
with:
distribution: temurin
java-version: '21'
- name: Set up Gradle (build cache)
if: matrix.language == 'java-kotlin'
uses: gradle/actions/setup-gradle@v6
with:
cache-read-only: true
cache-provider: basic
- name: Set up Android SDK
if: matrix.language == 'java-kotlin'
uses: android-actions/setup-android@v4
with:
log-accepted-android-sdk-licenses: false
- name: Initialize CodeQL
uses: github/codeql-action/init@v4.37.3
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.language == 'java-kotlin' && 'manual' || 'none' }}
# build-mode: manual — CodeQL traces this compilation for java-kotlin.
# Same tasks as ci.yml build-debug / local-ci.sh (generateApolloSources
# first so Apollo codegen failures surface crisply, then assembleDebug
# which compiles all app Kotlin/Java sources).
- name: Build (manual, for CodeQL trace)
if: matrix.language == 'java-kotlin'
run: ./gradlew :app:generateApolloSources :app:assembleDebug --stacktrace
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4.37.3
with:
category: "/language:${{ matrix.language }}"