Skip to content

Commit e76f456

Browse files
committed
ci: supply chain hardening for .github/workflows/**
- Add `--ignore-scripts` to all CI `npm ci`/`npm install` invocations and set `ignore-scripts=true` in `.npmrc` so install-time scripts from transitive dependencies cannot run during PR builds. - Pin `@types/vscode` in Dependabot config and in the root `upgrade:node` script's `--reject` list so it cannot be auto-upgraded past the `engines.vscode` floor. - Add a two-workflow handoff to rebuild `server/dist/**` for Dependabot PRs without granting write tokens to untrusted PR code: * `build-server.yml` (pull_request, read-only) uploads the built `server/dist` artifact and skips the drift check for Dependabot. * `dependabot-commit-dist.yml` (workflow_run, trusted, contents:write) downloads the artifact, verifies the head SHA, and commits the rebuilt files back to the PR branch as `dependabot[bot]`. - Remove unused `workflow_dispatch:` triggers from workflows that have no inputs (lint-and-format, client-integration-tests, query-unit-tests, query-unit-tests-swift, copilot-setup-steps); keep it on `release.yml` and `update-codeql.yml` (the latter has a meaningful `target_version` input). - Update the add-language skill's `SKILL.md` and `workflow-template.yml` to match: drop `workflow_dispatch:`, pin actions to SHAs, and use `npm ci --ignore-scripts`.
1 parent 50f63f3 commit e76f456

16 files changed

+163
-31
lines changed

.github/skills/add-mcp-support-for-new-language/SKILL.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,6 @@ on:
273273
branches: ['main']
274274
paths:
275275
# Same as above
276-
workflow_dispatch:
277276
278277
permissions:
279278
contents: read
@@ -284,12 +283,12 @@ jobs:
284283
runs-on: {os}-latest # e.g., macos-latest, windows-latest
285284
286285
steps:
287-
- uses: actions/checkout@v6
288-
- uses: actions/setup-node@v6
286+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
287+
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
289288
with:
290289
cache: 'npm'
291290
node-version-file: '.node-version'
292-
- run: npm ci --workspaces
291+
- run: npm ci --workspaces --ignore-scripts
293292
- uses: ./.github/actions/setup-codeql-environment
294293
with:
295294
install-language-runtimes: false

.github/skills/add-mcp-support-for-new-language/workflow-template.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ on:
2828
- 'server/scripts/extract-test-databases.sh'
2929
- 'server/scripts/install-packs.sh'
3030
- 'server/scripts/run-query-unit-tests.sh'
31-
workflow_dispatch:
3231

3332
# Prevent duplicate runs from push + PR on the same branch
3433
concurrency:

.github/workflows/build-and-test-extension.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ on:
1919
- 'server/dist/**'
2020
- 'server/ql/*/tools/src/**'
2121
- 'server/src/**'
22-
workflow_dispatch:
2322

2423
permissions:
2524
contents: read
@@ -40,7 +39,7 @@ jobs:
4039
node-version-file: '.node-version'
4140

4241
- name: Install dependencies
43-
run: npm ci --include=optional
42+
run: npm ci --include=optional --ignore-scripts
4443

4544
- name: Build server (dependency)
4645
run: npm run build -w server

.github/workflows/build-server.yml

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ on:
1313
- '.github/workflows/build-server.yml'
1414
- '.node-version'
1515
- 'server/**'
16-
workflow_dispatch:
1716

1817
permissions:
1918
contents: read
@@ -38,7 +37,7 @@ jobs:
3837
node-version-file: '.node-version'
3938

4039
- name: Build Server - Install dependencies
41-
run: npm ci --include=optional
40+
run: npm ci --include=optional --ignore-scripts
4241
working-directory: .
4342

4443
- name: Build Server - Clean previous build
@@ -50,7 +49,21 @@ jobs:
5049
- name: Build Server - Bundle application
5150
run: npm run bundle
5251

52+
## Consumed by dependabot-commit-dist.yml via workflow_run.
53+
- name: Build Server - Upload server/dist artifact
54+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
55+
with:
56+
name: server-dist
57+
path: |
58+
server/dist/codeql-development-mcp-server.js
59+
server/dist/codeql-development-mcp-server.js.map
60+
if-no-files-found: error
61+
retention-days: 7
62+
63+
## Skipped for Dependabot PRs: dependabot-commit-dist.yml will push the
64+
## rebuilt 'server/dist' back to the PR branch.
5365
- name: Build Server - Check for uncommitted changes
66+
if: github.actor != 'dependabot[bot]'
5467
run: |
5568
if [ -n "$(git status --porcelain)" ]; then
5669
echo "❌ Uncommitted changes detected after build:"

.github/workflows/client-integration-tests.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ on:
1919
- '.node-version'
2020
- 'client/**'
2121
- 'server/**'
22-
workflow_dispatch:
2322

2423
permissions:
2524
contents: read
@@ -61,7 +60,7 @@ jobs:
6160
run: choco install jq -y
6261

6362
- name: MCP Integration Tests - Install node dependencies for client and server workspaces
64-
run: npm ci --workspace=client && npm ci --workspace=server
63+
run: npm ci --workspace=client --ignore-scripts && npm ci --workspace=server --ignore-scripts
6564

6665
- name: MCP Integration Tests - Setup CodeQL environment
6766
uses: ./.github/actions/setup-codeql-environment
@@ -168,7 +167,7 @@ jobs:
168167
node-version-file: '.node-version'
169168

170169
- name: CODEQL_PATH Tests - Install server dependencies
171-
run: npm ci --workspace=server
170+
run: npm ci --workspace=server --ignore-scripts
172171

173172
- name: CODEQL_PATH Tests - Build server bundle
174173
run: npm run bundle -w server

.github/workflows/copilot-setup-steps.yml

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,26 @@
11
name: 'Copilot Setup Steps'
22

33
on:
4-
# Allow manual testing through the repository's "Actions" tab
5-
workflow_dispatch: {}
6-
# Automatically run the setup steps when an associated workflow is changed.
74
push:
85
paths:
96
- '.codeql-version'
7+
- '.github/actions/setup-codeql-environment/action.yml'
108
- '.github/workflows/copilot-setup-steps.yml'
119
- '.node-version'
12-
- '.github/actions/setup-codeql-environment/action.yml'
1310
- '**/codeql-pack.yml'
1411
- '**/codeql-pack.lock.yml'
1512
- '**/package.json'
1613
- '**/package-lock.json'
17-
- '**/qlpack.yml'
1814
pull_request:
1915
paths:
2016
- '.codeql-version'
17+
- '.github/actions/setup-codeql-environment/action.yml'
2118
- '.github/workflows/copilot-setup-steps.yml'
2219
- '.node-version'
23-
- '.github/actions/setup-codeql-environment/action.yml'
2420
- '**/codeql-pack.yml'
2521
- '**/codeql-pack.lock.yml'
2622
- '**/package.json'
2723
- '**/package-lock.json'
28-
- '**/qlpack.yml'
2924

3025
jobs:
3126
# The job MUST be called `copilot-setup-steps` or it will not be picked up by Copilot.
@@ -51,7 +46,7 @@ jobs:
5146
node-version-file: '.node-version'
5247

5348
- name: Copilot Setup - Install dependencies
54-
run: npm ci --include=optional
49+
run: npm ci --include=optional --ignore-scripts
5550

5651
- name: Copilot Setup - Setup CodeQL environment
5752
uses: ./.github/actions/setup-codeql-environment
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
name: Dependabot Commit Dist - CodeQL Development MCP Server
2+
3+
## Auto-rebuild and commit 'server/dist/**' on Dependabot PRs.
4+
##
5+
## Two-workflow handoff: 'build-server.yml' rebuilds with no write token
6+
## (npm ci --ignore-scripts), uploads the 'server-dist' artifact. This
7+
## workflow runs in the trusted default-branch context, downloads the
8+
## artifact, and pushes it to the PR branch. No PR-supplied code executes
9+
## here.
10+
11+
on:
12+
workflow_run:
13+
workflows: ['Build Server - CodeQL Development MCP Server']
14+
types: [completed]
15+
16+
permissions:
17+
contents: read
18+
19+
jobs:
20+
commit-dist:
21+
name: Commit Rebuilt server/dist to Dependabot PR Branch
22+
runs-on: ubuntu-latest
23+
24+
if: >-
25+
github.event.workflow_run.event == 'pull_request' &&
26+
github.event.workflow_run.conclusion == 'success' &&
27+
github.event.workflow_run.actor.login == 'dependabot[bot]'
28+
29+
permissions:
30+
contents: write
31+
actions: read
32+
33+
steps:
34+
- name: Commit Dist - Validate workflow_run head
35+
id: pr
36+
env:
37+
HEAD_REPO: ${{ github.event.workflow_run.head_repository.full_name }}
38+
HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }}
39+
HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
40+
REPO: ${{ github.repository }}
41+
run: |
42+
set -euo pipefail
43+
if [ "${HEAD_REPO}" != "${REPO}" ]; then
44+
echo "::error::Refusing to push: head repo '${HEAD_REPO}' != '${REPO}'"
45+
exit 1
46+
fi
47+
if [ -z "${HEAD_BRANCH}" ] || [ -z "${HEAD_SHA}" ]; then
48+
echo "::error::Missing head_branch or head_sha"
49+
exit 1
50+
fi
51+
echo "branch=${HEAD_BRANCH}" >> "${GITHUB_OUTPUT}"
52+
echo "sha=${HEAD_SHA}" >> "${GITHUB_OUTPUT}"
53+
54+
- name: Commit Dist - Checkout PR branch
55+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
56+
with:
57+
ref: ${{ steps.pr.outputs.branch }}
58+
persist-credentials: true
59+
fetch-depth: 1
60+
61+
## Abort if the branch advanced since the build started; the next
62+
## build-server run will re-trigger this workflow.
63+
- name: Commit Dist - Verify checkout matches build SHA
64+
id: verify
65+
env:
66+
EXPECTED_SHA: ${{ steps.pr.outputs.sha }}
67+
run: |
68+
set -euo pipefail
69+
ACTUAL_SHA="$(git rev-parse HEAD)"
70+
if [ "${ACTUAL_SHA}" != "${EXPECTED_SHA}" ]; then
71+
echo "::warning::Branch advanced from ${EXPECTED_SHA} to ${ACTUAL_SHA}; skipping."
72+
echo "skip=true" >> "${GITHUB_OUTPUT}"
73+
else
74+
echo "skip=false" >> "${GITHUB_OUTPUT}"
75+
fi
76+
77+
- name: Commit Dist - Download server-dist artifact
78+
if: steps.verify.outputs.skip == 'false'
79+
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
80+
with:
81+
name: server-dist
82+
path: artifact/
83+
run-id: ${{ github.event.workflow_run.id }}
84+
github-token: ${{ secrets.GITHUB_TOKEN }}
85+
86+
## Defence in depth: confirm the artifact contains exactly the two
87+
## expected bundle files before copying into the repo.
88+
- name: Commit Dist - Verify artifact contents
89+
if: steps.verify.outputs.skip == 'false'
90+
run: |
91+
set -euo pipefail
92+
for f in codeql-development-mcp-server.js codeql-development-mcp-server.js.map; do
93+
if [ ! -f "artifact/${f}" ]; then
94+
echo "::error::Missing expected artifact file: ${f}"
95+
exit 1
96+
fi
97+
done
98+
UNEXPECTED="$(find artifact -type f \
99+
! -name 'codeql-development-mcp-server.js' \
100+
! -name 'codeql-development-mcp-server.js.map' \
101+
-print)"
102+
if [ -n "${UNEXPECTED}" ]; then
103+
echo "::error::Unexpected files in artifact:"
104+
echo "${UNEXPECTED}"
105+
exit 1
106+
fi
107+
108+
- name: Commit Dist - Commit and push (if changed)
109+
if: steps.verify.outputs.skip == 'false'
110+
env:
111+
BRANCH: ${{ steps.pr.outputs.branch }}
112+
run: |
113+
set -euo pipefail
114+
cp artifact/codeql-development-mcp-server.js server/dist/
115+
cp artifact/codeql-development-mcp-server.js.map server/dist/
116+
117+
git config user.name 'dependabot[bot]'
118+
git config user.email '49699333+dependabot[bot]@users.noreply.github.com'
119+
git add server/dist/codeql-development-mcp-server.js \
120+
server/dist/codeql-development-mcp-server.js.map
121+
122+
if git diff --cached --quiet; then
123+
echo "::notice::server/dist already up to date."
124+
exit 0
125+
fi
126+
127+
git commit -m "chore(deps): rebuild server/dist after dependency update
128+
129+
[dependabot skip]"
130+
git push origin "HEAD:${BRANCH}"

.github/workflows/lint-and-format.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ on:
55
branches: ['main', 'next']
66
push:
77
branches: ['main', 'next']
8-
workflow_dispatch:
98

109
permissions:
1110
contents: read
@@ -26,7 +25,7 @@ jobs:
2625
node-version-file: '.node-version'
2726

2827
- name: Lint and Format - Install node dependencies for all workspaces
29-
run: npm ci
28+
run: npm ci --ignore-scripts
3029

3130
- name: Lint and Format - Run eslint
3231
run: npm run lint

.github/workflows/query-unit-tests-swift.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ on:
2121
- 'server/ql/swift/**'
2222
- 'server/scripts/install-packs.sh'
2323
- 'server/scripts/run-query-unit-tests.sh'
24-
workflow_dispatch:
2524

2625
permissions:
2726
contents: read
@@ -42,7 +41,7 @@ jobs:
4241
node-version-file: '.node-version'
4342

4443
- name: Query Unit Tests - swift - Install node dependencies for all workspaces
45-
run: npm ci --workspaces
44+
run: npm ci --workspaces --ignore-scripts
4645

4746
- name: Query Unit Tests - swift - Setup CodeQL environment
4847
uses: ./.github/actions/setup-codeql-environment

.github/workflows/query-unit-tests.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ on:
2929
- 'server/ql/**'
3030
- 'server/scripts/install-packs.sh'
3131
- 'server/scripts/run-query-unit-tests.sh'
32-
workflow_dispatch:
3332

3433
permissions:
3534
contents: read
@@ -58,7 +57,7 @@ jobs:
5857
run: sudo apt-get install -y jq
5958

6059
- name: Query Unit Tests - ${{ matrix.language }} - Install node dependencies for all workspaces
61-
run: npm ci --workspaces
60+
run: npm ci --workspaces --ignore-scripts
6261

6362
- name: Query Unit Tests - ${{ matrix.language }} - Setup CodeQL environment
6463
uses: ./.github/actions/setup-codeql-environment

0 commit comments

Comments
 (0)