Skip to content

Automate the bundle upgrade #1630

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Apr 3, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Add workflow to automatically update the bundle
  • Loading branch information
henrymercer committed Apr 3, 2023
commit 1c0a788663a0650c0556d10697203ce32a0e6d69
14 changes: 14 additions & 0 deletions .github/actions/update-bundle/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: Update default CodeQL bundle
description: Updates 'src/defaults.json' to point to a new CodeQL bundle release.

runs:
using: composite
steps:
- name: Install ts-node
shell: bash
run: npm install -g ts-node

- name: Run update script
working-directory: ${{ github.action_path }}
shell: bash
run: ts-node ./index.ts
64 changes: 64 additions & 0 deletions .github/actions/update-bundle/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import * as fs from 'fs';
import * as github from '@actions/github';

interface BundleInfo {
bundleVersion: string;
cliVersion: string;
}

interface Defaults {
bundleVersion: string;
cliVersion: string;
priorBundleVersion: string;
priorCliVersion: string;
}

const CODEQL_BUNDLE_PREFIX = 'codeql-bundle-';

function getCodeQLCliVersionForRelease(release): string {
const cliVersionsFromMarkerFiles = release.assets
.map((asset) => asset.name.match(/cli-version-(.*)\.txt/)?.[1])
.filter((v) => v)
.map((v) => v as string);
if (cliVersionsFromMarkerFiles.length > 1) {
throw new Error(
`Release ${release.tag_name} has multiple CLI version marker files.`
);
} else if (cliVersionsFromMarkerFiles.length === 0) {
throw new Error(
`Failed to find the CodeQL CLI version for release ${release.tag_name}.`
);
}
return cliVersionsFromMarkerFiles[0];
}

async function getBundleInfoFromRelease(release): Promise<BundleInfo> {
return {
bundleVersion: release.tag_name.substring(CODEQL_BUNDLE_PREFIX.length),
cliVersion: getCodeQLCliVersionForRelease(release)
};
}

async function getNewDefaults(currentDefaults: Defaults): Promise<Defaults> {
const release = github.context.payload.release;
console.log('Updating default bundle as a result of the following release: ' +
`${JSON.stringify(release)}.`)

const bundleInfo = await getBundleInfoFromRelease(release);
return {
bundleVersion: bundleInfo.bundleVersion,
cliVersion: bundleInfo.cliVersion,
priorBundleVersion: currentDefaults.bundleVersion,
priorCliVersion: currentDefaults.cliVersion
};
}

async function main() {
const previousDefaults: Defaults = JSON.parse(fs.readFileSync('../../../src/defaults.json', 'utf8'));
const newDefaults = await getNewDefaults(previousDefaults);
fs.writeFileSync('../../../src/defaults.json', JSON.stringify(newDefaults, null, 2) + "\n");
}

// Ideally, we'd await main() here, but that doesn't work well with `ts-node`.
// So instead we rely on the fact that Node won't exit until the event loop is empty.
main();
82 changes: 82 additions & 0 deletions .github/workflows/update-bundle.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
name: Update default CodeQL bundle

on:
release:
types: [prereleased]

jobs:
update-bundle:
if: startsWith(github.event.release.tag_name, 'codeql-bundle-')
runs-on: ubuntu-latest
steps:
- name: Dump environment
run: env

- name: Dump GitHub context
env:
GITHUB_CONTEXT: '${{ toJson(github) }}'
run: echo "${GITHUB_CONTEXT}"

- uses: actions/checkout@v3

- name: Update git config
run: |
git config --global user.email "github-actions@github.com"
git config --global user.name "github-actions[bot]"

- name: Update bundle
uses: ./.github/actions/update-bundle

- name: Rebuild Action
run: npm run build

- name: Commit and push changes
env:
RELEASE_TAG: "${{ github.event.release.tag_name }}"
run: |
git checkout -b "update-bundle/${RELEASE_TAG}"
git commit -am "Update default bundle to ${RELEASE_TAG}"
git push --set-upstream origin "update-bundle/${RELEASE_TAG}"

- name: Open pull request
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
cli_version=$(jq -r '.cliVersion' src/defaults.json)
pr_url=$(gh pr create \
--title "Update default bundle to $cli_version" \
--body "This pull request updates the default CodeQL bundle, as used with \`tools: latest\` and on GHES, to $cli_version." \
--assignee "${GITHUB_ACTOR}" \
--draft \
)
echo "CLI_VERSION=$cli_version" >> $GITHUB_ENV
echo "PR_URL=$pr_url" >> $GITHUB_ENV

- name: Create changelog note
shell: python
run: |
import os
import re

# Get the PR number from the PR URL.
pr_number = os.environ['PR_URL'].split('/')[-1]
changelog_note = f"- Update default CodeQL bundle version to {os.environ['CLI_VERSION']}. [#{pr_number}]({os.environ['PR_URL']})"

# If the "[UNRELEASED]" section starts with "no user facing changes", remove that line.
# Use perl to avoid having to escape the newline character.

with open('CHANGELOG.md', 'r') as f:
changelog = f.read()

changelog = changelog.replace('## [UNRELEASED]\n\nNo user facing changes.', '## [UNRELEASED]\n')

# Add the changelog note to the bottom of the "[UNRELEASED]" section.
changelog = re.sub(r'\n## (\d+\.\d+\.\d+)', f'{changelog_note}\n\n## \\1', changelog, count=1)

with open('CHANGELOG.md', 'w') as f:
f.write(changelog)

- name: Push changelog note
run: |
git commit -am "Add changelog note"
git push
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy