Skip to content

Commit 68b8647

Browse files
committed
Upload empty SARIF for skipped languages to satisfy code scanning
Code scanning branch protection expects results for every category previously uploaded on main. When the dynamic matrix excludes a language (no paths changed), the missing category blocks PR merge. Add a skip-analysis job that uploads an empty SARIF file for each language not included in the analysis matrix, so all 7 categories always have results.
1 parent 347e76f commit 68b8647

1 file changed

Lines changed: 66 additions & 13 deletions

File tree

.github/workflows/codeql.yml

Lines changed: 66 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ jobs:
2121
pull-requests: read
2222
outputs:
2323
matrix: ${{ steps.build-matrix.outputs.matrix }}
24+
skipped-matrix: ${{ steps.build-matrix.outputs.skipped-matrix }}
2425
steps:
2526
- uses: actions/checkout@v4
2627

@@ -50,28 +51,47 @@ jobs:
5051
- name: Build language matrix
5152
id: build-matrix
5253
run: |
53-
# On push/schedule, analyse ALL languages.
54-
# On pull_request, only those whose paths changed.
54+
ALL_LANGUAGES=("java-kotlin" "javascript-typescript" "python" "go" "rust" "csharp" "actions")
55+
ALL_GATES=("java" "js" "python" "go" "rust" "csharp" "actions")
56+
57+
# On push/schedule, analyse ALL languages; skip none.
5558
if [[ "${{ github.event_name }}" != "pull_request" ]]; then
56-
matrix='{"include":[{"language":"java-kotlin"},{"language":"javascript-typescript"},{"language":"python"},{"language":"go"},{"language":"rust"},{"language":"csharp"},{"language":"actions"}]}'
59+
entries=()
60+
for lang in "${ALL_LANGUAGES[@]}"; do
61+
entries+=("{\"language\":\"${lang}\"}")
62+
done
63+
joined=$(IFS=,; echo "${entries[*]}")
64+
echo "matrix={\"include\":[${joined}]}" >> "$GITHUB_OUTPUT"
65+
echo 'skipped-matrix={"include":[]}' >> "$GITHUB_OUTPUT"
5766
else
5867
entries=()
59-
[[ "${{ steps.filter.outputs.java }}" == "true" ]] && entries+=('{"language":"java-kotlin"}')
60-
[[ "${{ steps.filter.outputs.js }}" == "true" ]] && entries+=('{"language":"javascript-typescript"}')
61-
[[ "${{ steps.filter.outputs.python }}" == "true" ]] && entries+=('{"language":"python"}')
62-
[[ "${{ steps.filter.outputs.go }}" == "true" ]] && entries+=('{"language":"go"}')
63-
[[ "${{ steps.filter.outputs.rust }}" == "true" ]] && entries+=('{"language":"rust"}')
64-
[[ "${{ steps.filter.outputs.csharp }}" == "true" ]] && entries+=('{"language":"csharp"}')
65-
[[ "${{ steps.filter.outputs.actions }}" == "true" ]] && entries+=('{"language":"actions"}')
68+
skipped=()
69+
filter_outputs=("${{ steps.filter.outputs.java }}" "${{ steps.filter.outputs.js }}" "${{ steps.filter.outputs.python }}" "${{ steps.filter.outputs.go }}" "${{ steps.filter.outputs.rust }}" "${{ steps.filter.outputs.csharp }}" "${{ steps.filter.outputs.actions }}")
70+
71+
for i in "${!ALL_LANGUAGES[@]}"; do
72+
lang="${ALL_LANGUAGES[$i]}"
73+
changed="${filter_outputs[$i]}"
74+
if [[ "$changed" == "true" ]]; then
75+
entries+=("{\"language\":\"${lang}\"}")
76+
else
77+
skipped+=("{\"language\":\"${lang}\"}")
78+
fi
79+
done
6680
6781
if [[ ${#entries[@]} -eq 0 ]]; then
68-
matrix='{"include":[]}'
82+
echo 'matrix={"include":[]}' >> "$GITHUB_OUTPUT"
6983
else
7084
joined=$(IFS=,; echo "${entries[*]}")
71-
matrix="{\"include\":[${joined}]}"
85+
echo "matrix={\"include\":[${joined}]}" >> "$GITHUB_OUTPUT"
86+
fi
87+
88+
if [[ ${#skipped[@]} -eq 0 ]]; then
89+
echo 'skipped-matrix={"include":[]}' >> "$GITHUB_OUTPUT"
90+
else
91+
joined=$(IFS=,; echo "${skipped[*]}")
92+
echo "skipped-matrix={\"include\":[${joined}]}" >> "$GITHUB_OUTPUT"
7293
fi
7394
fi
74-
echo "matrix=${matrix}" >> "$GITHUB_OUTPUT"
7595
7696
analyze:
7797
name: Analyze (${{ matrix.language }})
@@ -100,3 +120,36 @@ jobs:
100120
uses: github/codeql-action/analyze@v3
101121
with:
102122
category: "/language:${{ matrix.language }}"
123+
124+
# Upload empty SARIF for languages that were NOT analysed in this PR.
125+
# Code scanning branch protection expects results for every category that
126+
# has ever been uploaded on the default branch; missing categories block merge.
127+
skip-analysis:
128+
name: Skip (${{ matrix.language }})
129+
needs: changes
130+
if: ${{ github.event_name == 'pull_request' && fromJson(needs.changes.outputs.skipped-matrix).include[0] != null }}
131+
runs-on: ubuntu-latest
132+
permissions:
133+
security-events: write
134+
strategy:
135+
fail-fast: false
136+
matrix: ${{ fromJson(needs.changes.outputs.skipped-matrix) }}
137+
steps:
138+
- name: Create empty SARIF
139+
run: |
140+
cat > "$RUNNER_TEMP/empty.sarif" <<'EOF'
141+
{
142+
"version": "2.1.0",
143+
"$schema": "https://json.schemastore.org/sarif-2.1.0.json",
144+
"runs": [{
145+
"tool": { "driver": { "name": "CodeQL", "version": "0.0.0" } },
146+
"results": []
147+
}]
148+
}
149+
EOF
150+
151+
- name: Upload empty SARIF
152+
uses: github/codeql-action/upload-sarif@v3
153+
with:
154+
sarif_file: ${{ runner.temp }}/empty.sarif
155+
category: "/language:${{ matrix.language }}"

0 commit comments

Comments
 (0)