Update CodeQL CLI Dependencies #171
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Update CodeQL CLI Dependencies | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| target_version: | |
| description: 'Target CodeQL CLI version (e.g. vX.Y.Z). Leave empty to use the latest available CodeQL CLI release.' | |
| required: false | |
| type: string | |
| # Nightly check for new CodeQL CLI releases | |
| schedule: | |
| - cron: '30 5 * * *' | |
| permissions: | |
| contents: read | |
| jobs: | |
| # ───────────────────────────────────────────────────────────────────────────── | |
| # Step 1: Detect new CodeQL CLI version | |
| # | |
| # Compares the current CodeQL CLI version in .codeql-version against the | |
| # latest release from github/codeql-cli-binaries. If a newer version is | |
| # available, downstream jobs orchestrate the update and PR creation. | |
| # ───────────────────────────────────────────────────────────────────────────── | |
| detect-update: | |
| name: Detect CodeQL CLI Update | |
| runs-on: ubuntu-latest | |
| outputs: | |
| current_version: ${{ steps.check-version.outputs.current_version }} | |
| latest_version: ${{ steps.check-version.outputs.latest_version }} | |
| update_needed: ${{ steps.check-version.outputs.update_needed }} | |
| version: ${{ steps.check-version.outputs.version }} | |
| steps: | |
| - name: Detect - Checkout repository | |
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| - name: Detect - Check latest CodeQL CLI version | |
| id: check-version | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| TARGET_VERSION: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.target_version || '' }} | |
| run: | | |
| echo "Checking latest CodeQL CLI version..." | |
| # Read current version from .codeql-version (stores vX.Y.Z) | |
| current_version_raw=$(cat .codeql-version | tr -d '[:space:]') | |
| current_version="${current_version_raw#v}" | |
| # Trim whitespace from target version input | |
| TARGET_VERSION=$(echo "${TARGET_VERSION}" | tr -d '[:space:]') | |
| if [ -n "${TARGET_VERSION}" ]; then | |
| # Use the manually specified target version | |
| latest_clean="${TARGET_VERSION#v}" | |
| echo "Using manually specified target version: ${latest_clean}" | |
| # Validate the target version exists as a release | |
| if ! gh release view "v${latest_clean}" --repo github/codeql-cli-binaries --json tagName > /dev/null 2>&1; then | |
| echo "❌ Error: Target version v${latest_clean} does not exist in github/codeql-cli-binaries releases" >&2 | |
| exit 1 | |
| fi | |
| else | |
| # Get latest release from codeql-cli-binaries | |
| latest_tag=$(gh release list --repo github/codeql-cli-binaries --json 'tagName,isLatest' --jq '.[] | select(.isLatest == true) | .tagName') | |
| # Validate that we found a latest release | |
| if [ -z "${latest_tag}" ]; then | |
| echo "❌ Error: Could not determine latest CodeQL CLI version from github/codeql-cli-binaries" >&2 | |
| echo "No release marked as 'latest' was found. This may indicate an API issue or repository change." >&2 | |
| exit 1 | |
| fi | |
| latest_clean="${latest_tag#v}" | |
| fi | |
| echo "Current CodeQL CLI version: ${current_version}" | |
| echo "Target CodeQL CLI version: ${latest_clean}" | |
| if [ "${latest_clean}" != "${current_version}" ]; then | |
| echo "✅ Update available: ${current_version} → ${latest_clean}" | |
| echo "update_needed=true" >> $GITHUB_OUTPUT | |
| echo "current_version=${current_version}" >> $GITHUB_OUTPUT | |
| echo "latest_version=${latest_clean}" >> $GITHUB_OUTPUT | |
| echo "version=v${latest_clean}" >> $GITHUB_OUTPUT | |
| else | |
| echo "ℹ️ CodeQL CLI is already up-to-date at version ${current_version}" | |
| echo "update_needed=false" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Detect - Summary | |
| run: | | |
| echo "## CodeQL CLI Update Check" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| if [ "${{ steps.check-version.outputs.update_needed }}" == "true" ]; then | |
| echo "✅ Update available: ${{ steps.check-version.outputs.current_version }} → ${{ steps.check-version.outputs.latest_version }}" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "Initiating update pipeline for \`${{ steps.check-version.outputs.version }}\`..." >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "ℹ️ CodeQL CLI is already up-to-date. No changes needed." >> $GITHUB_STEP_SUMMARY | |
| fi | |
| # ───────────────────────────────────────────────────────────────────────────── | |
| # Step 2: Check whether the upgrade branch already exists | |
| # | |
| # When this workflow runs on its nightly cron schedule and an upgrade PR has | |
| # already been opened for the target version, re-running `create-pr` would | |
| # force-push over the existing branch and silently discard any review | |
| # commits already made on top of the bot's initial push (e.g., manual fixes | |
| # to upgrade-packs.sh output or reviewer follow-ups). This job short-circuits | |
| # subsequent work in that case so the existing branch is preserved. | |
| # | |
| # The branch check is skipped on `workflow_dispatch` so a maintainer can | |
| # always re-run the upgrade pipeline on demand to re-create the branch. | |
| # ───────────────────────────────────────────────────────────────────────────── | |
| check-existing-branch: | |
| name: Check for Existing Upgrade Branch | |
| needs: detect-update | |
| if: needs.detect-update.outputs.update_needed == 'true' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| outputs: | |
| branch_exists: ${{ steps.check-branch.outputs.branch_exists }} | |
| steps: | |
| - name: Check - Look up upgrade branch on origin | |
| id: check-branch | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| BRANCH: 'codeql/upgrade-to-${{ needs.detect-update.outputs.version }}' | |
| EVENT_NAME: ${{ github.event_name }} | |
| run: | | |
| if [ "${EVENT_NAME}" = "workflow_dispatch" ]; then | |
| echo "ℹ️ Manual dispatch — skipping existing-branch check." | |
| echo "branch_exists=false" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| echo "Checking whether branch '${BRANCH}' exists on ${GITHUB_REPOSITORY}..." | |
| if gh api "repos/${GITHUB_REPOSITORY}/branches/${BRANCH}" \ | |
| --silent > /dev/null 2>&1; then | |
| echo "✅ Branch '${BRANCH}' already exists — skipping update to preserve manual edits." | |
| echo "branch_exists=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "ℹ️ Branch '${BRANCH}' does not exist — proceeding with update." | |
| echo "branch_exists=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Check - Summary | |
| env: | |
| BRANCH: 'codeql/upgrade-to-${{ needs.detect-update.outputs.version }}' | |
| run: | | |
| echo "## Upgrade Branch Preflight" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| if [ "${{ steps.check-branch.outputs.branch_exists }}" = "true" ]; then | |
| echo "⏭️ Branch \`${BRANCH}\` already exists — skipping the rest of the pipeline to preserve any manual edits or review commits on it." >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "Trigger this workflow manually via \`workflow_dispatch\` to force a refresh." >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "▶️ Branch \`${BRANCH}\` does not exist — proceeding with the update pipeline." >> $GITHUB_STEP_SUMMARY | |
| fi | |
| # ───────────────────────────────────────────────────────────────────────────── | |
| # Step 3: Update version, build, test, and create PR | |
| # | |
| # Updates all version-bearing files, installs dependencies, runs the full | |
| # build-and-test suite, and creates a pull request with the changes. | |
| # ───────────────────────────────────────────────────────────────────────────── | |
| create-pr: | |
| name: Create Update Pull Request | |
| needs: [detect-update, check-existing-branch] | |
| if: | | |
| needs.detect-update.outputs.update_needed == 'true' && | |
| needs.check-existing-branch.outputs.branch_exists != 'true' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| steps: | |
| - name: Update - Checkout repository | |
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| - name: Update - Update .codeql-version | |
| run: | | |
| printf "v%s\n" "${{ needs.detect-update.outputs.latest_version }}" > .codeql-version | |
| echo "Updated .codeql-version to ${{ needs.detect-update.outputs.version }}" | |
| - name: Update - Setup CodeQL environment | |
| uses: ./.github/actions/setup-codeql-environment | |
| with: | |
| add-to-path: true | |
| install-language-runtimes: false | |
| - name: Update - Setup Node.js | |
| uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 | |
| with: | |
| cache: 'npm' | |
| node-version-file: '.node-version' | |
| - name: Update - Update version in all files | |
| run: | | |
| LATEST="${{ needs.detect-update.outputs.latest_version }}" | |
| echo "Updating all version-bearing files to ${LATEST}..." | |
| ./server/scripts/update-release-version.sh "${LATEST}" | |
| - name: Update - Install dependencies | |
| run: npm install --include=optional --ignore-scripts | |
| - name: Update - Upgrade CodeQL pack dependencies | |
| run: server/scripts/upgrade-packs.sh | |
| - name: Update - Install xvfb and VS Code dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y xvfb libgbm1 libgtk-3-0 libxshmfence1 | |
| sudo apt-get install -y libasound2t64 || sudo apt-get install -y libasound2 | |
| - name: Update - Build and test | |
| run: xvfb-run -a npm run build-and-test | |
| - name: Update - Create Pull Request | |
| uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1 | |
| with: | |
| title: 'Upgrade CodeQL CLI dependency to ${{ needs.detect-update.outputs.version }}' | |
| body: | | |
| This PR upgrades the CodeQL CLI version to ${{ needs.detect-update.outputs.version }}. | |
| **Changes made:** | |
| - Updated `.codeql-version` to `${{ needs.detect-update.outputs.version }}` | |
| - Updated all version-bearing files (package.json, extensions/vscode/package.json, codeql-pack.yml) to `${{ needs.detect-update.outputs.latest_version }}` | |
| - Regenerated `package-lock.json` | |
| - Upgraded CodeQL pack lock files | |
| - Build and tests passed ✅ | |
| commit-message: 'Upgrade CodeQL CLI dependency to ${{ needs.detect-update.outputs.version }}' | |
| delete-branch: true | |
| branch: 'codeql/upgrade-to-${{ needs.detect-update.outputs.version }}' | |
| - name: Update - Summary | |
| run: | | |
| VERSION="${{ needs.detect-update.outputs.version }}" | |
| CURRENT="${{ needs.detect-update.outputs.current_version }}" | |
| LATEST="${{ needs.detect-update.outputs.latest_version }}" | |
| echo "## CodeQL CLI Update Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "Triggered by CodeQL CLI update: ${CURRENT} → ${LATEST}" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "| Property | Old Value | New Value |" >> $GITHUB_STEP_SUMMARY | |
| echo "| -------- | --------- | --------- |" >> $GITHUB_STEP_SUMMARY | |
| echo "| .codeql-version | v${CURRENT} | ${VERSION} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| package.json versions | ${CURRENT} | ${LATEST} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| extensions/vscode/package.json | ${CURRENT} | ${LATEST} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| codeql-pack.yml versions | ${CURRENT} | ${LATEST} |" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "A pull request has been created with these changes." >> $GITHUB_STEP_SUMMARY |