-
Notifications
You must be signed in to change notification settings - Fork 2
323 lines (278 loc) · 11.3 KB
/
build-and-test-client.yml
File metadata and controls
323 lines (278 loc) · 11.3 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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
name: Build and Test Client - CodeQL Development MCP Server
on:
pull_request:
branches: ['main', 'next']
paths:
- '.github/actions/setup-codeql-environment/action.yml'
- '.github/workflows/build-and-test-client.yml'
- '.codeql-version'
- '.node-version'
- 'client/**'
- 'server/**'
push:
branches: ['main', 'next']
paths:
- '.github/actions/setup-codeql-environment/action.yml'
- '.github/workflows/build-and-test-client.yml'
- '.codeql-version'
- '.node-version'
- 'client/**'
- 'server/**'
workflow_dispatch:
permissions:
contents: read
jobs:
build-and-test-client:
name: Build and Unit Test (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Setup Go environment
uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5
with:
cache-dependency-path: 'client/go.sum'
go-version-file: 'client/go.mod'
- name: Build client
shell: bash
run: make -C client build SHELL="$(which bash)"
- name: Run unit tests
shell: bash
run: make -C client test-unit SHELL="$(which bash)"
- name: Lint
shell: bash
run: make -C client lint SHELL="$(which bash)"
- name: Summary
shell: bash
run: |
echo "## Build and Unit Test Client (${{ matrix.os }})" >> $GITHUB_STEP_SUMMARY
echo "✅ Go build completed" >> $GITHUB_STEP_SUMMARY
echo "✅ Unit tests passed" >> $GITHUB_STEP_SUMMARY
echo "✅ Lint checks passed" >> $GITHUB_STEP_SUMMARY
integration-tests:
name: Integration Tests (${{ matrix.os }}, ${{ matrix.mcp-mode }})
needs: build-and-test-client
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
mcp-mode: [http, stdio]
os: [ubuntu-latest, windows-latest]
env:
HTTP_HOST: 'localhost'
HTTP_PORT: '3000'
MCP_MODE: ${{ matrix.mcp-mode }}
TIMEOUT_SECONDS: '30'
URL_SCHEME: 'http'
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Setup Go environment
uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5
with:
cache-dependency-path: 'client/go.sum'
go-version-file: 'client/go.mod'
- name: Setup Node.js environment
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
with:
cache: 'npm'
node-version-file: '.node-version'
- name: Install OS dependencies (Ubuntu)
if: runner.os == 'Linux'
run: sudo apt-get install -y jq
- name: Install OS dependencies (Windows)
if: runner.os == 'Windows'
run: choco install jq -y
- name: Install node dependencies for server workspace
run: npm ci --workspace=server
- name: Setup CodeQL environment
uses: ./.github/actions/setup-codeql-environment
with:
install-language-runtimes: false
## Verify that the CodeQL CLI is spawnable from Node.js, not just from
## bash. On Windows, Node.js spawn()/execFile() require a real .exe
## binary on PATH, not a bash stub or .cmd wrapper. Fail fast here
## instead of waiting for integration tests to time out.
- name: Verify CodeQL CLI is spawnable from Node.js
shell: bash
run: |
node -e "
const { execFile } = require('child_process');
execFile('codeql', ['version', '--format=terse'], (err, stdout) => {
if (err) {
console.error('❌ CodeQL CLI is not spawnable from Node.js:', err.message);
console.error('This typically means codeql.exe is not on PATH (Windows).');
process.exit(1);
}
console.log('✅ CodeQL CLI is spawnable from Node.js, version:', stdout.trim());
});
"
- name: Install CodeQL packs
shell: bash
run: ./server/scripts/install-packs.sh
## Extract test databases used in the integration tests.
## Defaults to integration scope (javascript/examples + specific tools
## databases referenced by integration test fixtures).
- name: Extract test databases
shell: bash
run: ./server/scripts/extract-test-databases.sh
## Configure npm to use bash for running scripts on Windows, since the
## integration test scripts are bash scripts that cmd.exe cannot execute.
- name: Configure npm script shell (Windows)
if: runner.os == 'Windows'
shell: bash
run: npm config set script-shell "$(which bash)"
## Run integration tests. This script builds the server bundle and runs tests.
## On Windows, GNU Make's SHELL := bash resolves to WSL's bash.exe
## instead of Git Bash. We override SHELL with the full Git Bash path.
- name: Run integration tests
shell: bash
run: make -C client test-integration SHELL="$(which bash)"
- name: Stop the background MCP server process
if: always() && matrix.mcp-mode == 'http'
shell: bash
run: |
if [ -f server.pid ]; then
PID=$(cat server.pid)
echo "Stopping server with PID $PID"
if kill -0 "$PID" 2>/dev/null; then
kill "$PID" || true
sleep 2
if kill -0 "$PID" 2>/dev/null; then
echo "Force killing server process"
kill -9 "$PID" || true
fi
else
echo "Server process was not running"
fi
rm -f server.pid
else
echo "No server.pid file found"
fi
if [ -f server.log ]; then
rm -f server.log
fi
- name: Summary
shell: bash
run: |
echo "## Integration Tests (${{ matrix.os }}, ${{ matrix.mcp-mode }})" >> $GITHUB_STEP_SUMMARY
echo "✅ MCP server integration tests passed on ${{ matrix.os }} with ${{ matrix.mcp-mode }} transport" >> $GITHUB_STEP_SUMMARY
codeql-path-tests:
name: CODEQL_PATH Tests (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest, ubuntu-latest, windows-latest]
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Setup Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
with:
cache: 'npm'
node-version-file: '.node-version'
- name: Install server dependencies
run: npm ci --workspace=server
- name: Build server bundle
run: npm run bundle -w server
- name: Setup CodeQL environment
uses: ./.github/actions/setup-codeql-environment
with:
add-to-path: false
install-language-runtimes: false
## Locate the real CodeQL binary (not the gh-codeql bash stub).
- name: Locate CodeQL binary
id: locate-codeql
shell: bash
run: |
if [[ "$RUNNER_OS" == "Windows" ]]; then
LOCALAPPDATA_DIR="${LOCALAPPDATA:-$HOME/AppData/Local}"
CODEQL_BINARY=""
for search_dir in \
"${LOCALAPPDATA_DIR}/GitHub/gh-codeql" \
"${LOCALAPPDATA_DIR}/GitHub CLI/extensions/gh-codeql" \
"${LOCALAPPDATA_DIR}"; do
if [[ -d "$search_dir" ]]; then
CODEQL_BINARY=$(find "$search_dir" -maxdepth 10 \
-name "codeql.exe" -type f 2>/dev/null | head -1)
if [[ -n "$CODEQL_BINARY" ]]; then
break
fi
fi
done
if [[ -n "$CODEQL_BINARY" ]]; then
CODEQL_BINARY=$(cygpath -m "$CODEQL_BINARY")
fi
else
for search_dir in "$HOME/.local" "$HOME/Library"; do
if [[ -d "$search_dir" ]]; then
CODEQL_BINARY=$(find "$search_dir" -path "*gh-codeql*release*" -name "codeql" -type f 2>/dev/null | head -1)
if [[ -n "$CODEQL_BINARY" ]]; then
break
fi
fi
done
fi
if [[ -z "$CODEQL_BINARY" ]]; then
echo "::error::Could not locate CodeQL binary in gh-codeql distribution"
exit 1
fi
ACTUAL=$("$CODEQL_BINARY" version --format=terse 2>/dev/null)
EXPECTED=$(gh codeql version --format=terse 2>/dev/null)
if [[ "$ACTUAL" != "$EXPECTED" ]]; then
echo "::error::Binary version mismatch: got '$ACTUAL', expected '$EXPECTED'"
exit 1
fi
echo "✅ CodeQL binary verified: $CODEQL_BINARY (version $ACTUAL)"
echo "codeql-version=$ACTUAL" >> "$GITHUB_OUTPUT"
echo "codeql-binary=$CODEQL_BINARY" >> "$GITHUB_OUTPUT"
## Build a PATH that excludes every directory containing 'codeql'.
- name: Build clean PATH without CodeQL
shell: bash
run: |
CLEAN_PATH=""
IFS=':' read -ra PARTS <<< "$PATH"
for part in "${PARTS[@]}"; do
case "$part" in
*codeql*|*gh-codeql*) ;;
*)
CLEAN_PATH="${CLEAN_PATH:+$CLEAN_PATH:}$part"
;;
esac
done
if PATH="$CLEAN_PATH" command -v codeql >/dev/null 2>&1; then
echo "::error::codeql is still discoverable after PATH cleanup"
exit 1
fi
echo "✅ codeql is not on the clean PATH"
echo "CLEAN_PATH=$CLEAN_PATH" >> "$GITHUB_ENV"
- name: Test 1 - Fail with invalid CODEQL_PATH
shell: bash
run: ./server/scripts/test-codeql-path-invalid.sh
- name: Test 2 - Fail when codeql not on PATH and CODEQL_PATH not set
shell: bash
run: ./server/scripts/test-codeql-path-missing.sh
- name: Test 3 - Start with valid CODEQL_PATH
shell: bash
run: ./server/scripts/test-codeql-path-valid.sh "${{ steps.locate-codeql.outputs.codeql-binary }}"
- name: Summary
shell: bash
run: |
echo "## CODEQL_PATH Tests (${{ matrix.os }})" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Test | Result |" >> $GITHUB_STEP_SUMMARY
echo "| ---- | ------ |" >> $GITHUB_STEP_SUMMARY
echo "| Invalid CODEQL_PATH causes startup failure | ✅ Pass |" >> $GITHUB_STEP_SUMMARY
echo "| Missing codeql (no PATH, no CODEQL_PATH) causes startup failure | ✅ Pass |" >> $GITHUB_STEP_SUMMARY
echo "| Valid CODEQL_PATH (no PATH) starts server | ✅ Pass |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Detail | Value |" >> $GITHUB_STEP_SUMMARY
echo "| ------ | ----- |" >> $GITHUB_STEP_SUMMARY
echo "| CodeQL Version | ${{ steps.locate-codeql.outputs.codeql-version }} |" >> $GITHUB_STEP_SUMMARY
echo "| CodeQL Binary | \`${{ steps.locate-codeql.outputs.codeql-binary }}\` |" >> $GITHUB_STEP_SUMMARY
echo "| OS | ${{ matrix.os }} |" >> $GITHUB_STEP_SUMMARY