Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/dependabot.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,8 @@ updates:
ignore:
- dependency-name: 'zod'
versioning-strategy: 'increase'
- package-ecosystem: 'npm'
directory: '/extensions/vscode/'
schedule:
interval: 'weekly'
versioning-strategy: 'increase'
89 changes: 89 additions & 0 deletions .github/workflows/build-extension.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
name: Build Extension - CodeQL Development MCP Server

on:
pull_request:
branches: ['main']
paths:
- '.github/workflows/build-extension.yml'
- '.node-version'
- 'extensions/vscode/**'
- 'server/dist/**'
- 'server/ql/*/tools/src/**'
push:
branches: ['main']
paths:
- '.github/workflows/build-extension.yml'
- '.node-version'
- 'extensions/vscode/**'
- 'server/dist/**'
- 'server/ql/*/tools/src/**'
workflow_dispatch:

permissions:
contents: read

jobs:
build-extension:
name: Build Extension
runs-on: ubuntu-latest

steps:
- name: Build Extension - Checkout repository
uses: actions/checkout@v6

- name: Build Extension - Setup Node.js environment
uses: actions/setup-node@v6
with:
cache: 'npm'
node-version-file: '.node-version'

- name: Build Extension - Install dependencies
run: npm ci --include=optional

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

- name: Build Extension - Run extension tests with coverage
working-directory: extensions/vscode
run: npm run test:coverage

- name: Build Extension - Bundle extension and server
working-directory: extensions/vscode
run: |
npm run clean
npm run lint
npm run bundle
npm run bundle:server

- name: Build Extension - Verify VSIX packaging
working-directory: extensions/vscode
run: npx @vscode/vsce package --no-dependencies --out codeql-development-mcp-server.vsix

- name: Build Extension - Verify VSIX contents
working-directory: extensions/vscode
run: |
echo "## VSIX Contents" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
npx @vscode/vsce ls --no-dependencies --tree 2>&1 | head -50 >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY

- name: Build Extension - Check for uncommitted changes
run: |
if [ -n "$(git status --porcelain)" ]; then
echo "❌ Uncommitted changes detected after build:"
git status --porcelain
git diff
exit 1
else
echo "✅ No uncommitted changes after build"
fi

- name: Build Extension - Summary
run: |
echo "## Build Extension Summary" >> $GITHUB_STEP_SUMMARY
echo "✅ ESLint checks completed" >> $GITHUB_STEP_SUMMARY
echo "✅ All tests passed with coverage" >> $GITHUB_STEP_SUMMARY
echo "✅ Extension bundled successfully" >> $GITHUB_STEP_SUMMARY
echo "✅ Server bundled into extension" >> $GITHUB_STEP_SUMMARY
echo "✅ VSIX packaging verified" >> $GITHUB_STEP_SUMMARY
echo "✅ No uncommitted changes detected" >> $GITHUB_STEP_SUMMARY
136 changes: 136 additions & 0 deletions .github/workflows/release-vsix.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
name: Release VSIX - Build and Package VS Code Extension

on:
workflow_call:
inputs:
version:
description: 'Release version tag (e.g., vX.Y.Z). Must start with "v".'
required: true
type: string
outputs:
release_name:
description: 'The release name without "v" prefix (e.g., X.Y.Z)'
value: ${{ jobs.publish-vsix.outputs.release_name }}
version:
description: 'The full version string with "v" prefix (e.g., vX.Y.Z)'
value: ${{ jobs.publish-vsix.outputs.version }}
vsix_name:
description: 'The VSIX filename (e.g., codeql-development-mcp-server.vsix)'
value: ${{ jobs.publish-vsix.outputs.vsix_name }}

# Note: This workflow is called exclusively via workflow_call from release.yml.
# It does NOT have a workflow_dispatch trigger to keep release.yml as the single
# entry point for all release operations. To re-build the VSIX standalone,
# use workflow_dispatch on release.yml with publish_npm=false and
# publish_codeql_packs=false.

permissions:
contents: read

jobs:
publish-vsix:
name: Build and Package VSIX Extension
runs-on: ubuntu-latest

environment: release-vsix

permissions:
contents: read

outputs:
release_name: ${{ steps.version.outputs.release_name }}
version: ${{ steps.version.outputs.version }}
vsix_name: ${{ steps.package.outputs.vsix_name }}

steps:
- name: VSIX - Validate and parse version
id: version
run: |
VERSION="${{ inputs.version }}"
if [[ ! "${VERSION}" =~ ^v ]]; then
echo "::error::Version '${VERSION}' must start with 'v'"
exit 1
fi
echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "release_name=${VERSION#v}" >> $GITHUB_OUTPUT

- name: VSIX - Checkout tag
uses: actions/checkout@v6
with:
ref: refs/tags/${{ steps.version.outputs.version }}

- name: VSIX - Setup Node.js
uses: actions/setup-node@v6
with:
cache: 'npm'
node-version-file: '.node-version'

- name: VSIX - Install dependencies
run: npm ci --include=optional

- name: VSIX - Validate version consistency
run: |
RELEASE_NAME="${{ steps.version.outputs.release_name }}"
EXTENSION_VERSION=$(node -e "console.log(require('./extensions/vscode/package.json').version)")
if [ "${EXTENSION_VERSION}" != "${RELEASE_NAME}" ]; then
echo "::error::Extension version (${EXTENSION_VERSION}) does not match release (${RELEASE_NAME})"
exit 1
fi
echo "✅ Extension version matches release: ${RELEASE_NAME}"

- name: VSIX - Build server
run: npm run build -w server

- name: VSIX - Package VSIX
id: package
working-directory: extensions/vscode
run: |
VSIX_NAME="codeql-development-mcp-server.vsix"
npx @vscode/vsce package --no-dependencies --out "${VSIX_NAME}"
echo "vsix_name=${VSIX_NAME}" >> $GITHUB_OUTPUT
echo "✅ Packaged ${VSIX_NAME}"

- name: VSIX - Verify VSIX contents
working-directory: extensions/vscode
run: |
echo "Verifying bundled server and tool query packs..."
npx @vscode/vsce ls --no-dependencies 2>&1 | tee /tmp/vsix-contents.txt

# Verify critical files are included
for required in \
"dist/extension.cjs" \
"server/dist/codeql-development-mcp-server.js" \
"server/package.json" \
"server/ql/javascript/tools/src/PrintAST/PrintAST.ql"; do
if grep -q "${required}" /tmp/vsix-contents.txt; then
echo " ✅ ${required}"
else
echo " ❌ Missing: ${required}"
exit 1
fi
done

- name: VSIX - Upload artifact
uses: actions/upload-artifact@v6
with:
name: codeql-development-mcp-server-vsix-${{ steps.version.outputs.version }}
path: extensions/vscode/${{ steps.package.outputs.vsix_name }}

- name: VSIX - Summary
run: |
VERSION="${{ steps.version.outputs.version }}"
VSIX_NAME="${{ steps.package.outputs.vsix_name }}"
VSIX_SIZE=$(du -h "extensions/vscode/${VSIX_NAME}" | cut -f1)
echo "## VSIX Build Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Property | Value |" >> $GITHUB_STEP_SUMMARY
echo "| -------- | ----- |" >> $GITHUB_STEP_SUMMARY
echo "| Version | ${VERSION} |" >> $GITHUB_STEP_SUMMARY
echo "| VSIX | \`${VSIX_NAME}\` |" >> $GITHUB_STEP_SUMMARY
echo "| Size | ${VSIX_SIZE} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Bundled Contents" >> $GITHUB_STEP_SUMMARY
echo "- \`dist/extension.cjs\` — Extension entry point" >> $GITHUB_STEP_SUMMARY
echo "- \`server/dist/\` — Bundled MCP server" >> $GITHUB_STEP_SUMMARY
echo "- \`server/ql/*/tools/src/\` — CodeQL tool query packs" >> $GITHUB_STEP_SUMMARY
echo "- \`server/package.json\` — Server package metadata" >> $GITHUB_STEP_SUMMARY
26 changes: 25 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,22 @@ jobs:
publish_codeql_packs: ${{ needs.resolve-version.outputs.publish_codeql_packs == 'true' }}
version: ${{ needs.resolve-version.outputs.version }}

# ─────────────────────────────────────────────────────────────────────────────
# Step 3c: Build the VS Code extension VSIX
#
# Checks out the clean tag, builds the server and extension (including the
# bundled MCP server), and packages the self-contained VSIX. Runs in parallel
# with npm/CodeQL publishing since it only needs the tag.
# ─────────────────────────────────────────────────────────────────────────────
build-vsix:
name: Build VSIX Extension
needs: [resolve-version, ensure-tag]
permissions:
contents: read
uses: ./.github/workflows/release-vsix.yml
with:
version: ${{ needs.resolve-version.outputs.version }}

# ─────────────────────────────────────────────────────────────────────────────
# Step 4: Create GitHub Release
#
Expand All @@ -153,7 +169,7 @@ jobs:
always() && !failure() && !cancelled()
&& needs.resolve-version.outputs.create_github_release == 'true'
&& needs.resolve-version.outputs.publish_npm == 'true'
needs: [resolve-version, ensure-tag, publish-npm, publish-codeql]
needs: [resolve-version, ensure-tag, publish-npm, publish-codeql, build-vsix]
runs-on: ubuntu-latest

permissions:
Expand All @@ -171,6 +187,12 @@ jobs:
name: codeql-tool-query-packs-${{ needs.resolve-version.outputs.version }}
path: dist-packs

- name: Release - Download VSIX artifact
uses: actions/download-artifact@v7
with:
name: codeql-development-mcp-server-vsix-${{ needs.resolve-version.outputs.version }}
path: dist-vsix

- name: Release - Create distribution directory
run: |
mkdir -p dist-package/server
Expand Down Expand Up @@ -217,6 +239,7 @@ jobs:
files: |
codeql-development-mcp-server-${{ needs.resolve-version.outputs.version }}.tar.gz
dist-packs/*.tar.gz
dist-vsix/codeql-development-mcp-server.vsix
generate_release_notes: true
tag_name: ${{ needs.resolve-version.outputs.version }}

Expand All @@ -238,6 +261,7 @@ jobs:
echo "| CodeQL pack publish | ⏭️ Skipped (packs bundled only) |" >> $GITHUB_STEP_SUMMARY
fi
echo "| Distribution archive | ✅ Created |" >> $GITHUB_STEP_SUMMARY
echo "| VSIX extension | ✅ Built |" >> $GITHUB_STEP_SUMMARY
echo "| GitHub Release | ✅ Created |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Package Contents" >> $GITHUB_STEP_SUMMARY
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ codeql-development-mcp-server.code-workspace
*.tar.gz
*~

.vscode/mcp.json
.vscode/settings.json

# Ignore state tracking for local, integration testing
Expand Down
Loading
Loading