Add feature for forcing the nightly bundle in dynamic workflows#3484
Add feature for forcing the nightly bundle in dynamic workflows#3484
nightly bundle in dynamic workflows#3484Conversation
c4ada50 to
a61e3cb
Compare
There was a problem hiding this comment.
Pull request overview
This pull request adds a new ForceNightly feature flag that allows forcing the use of the nightly CodeQL CLI bundle in dynamic workflows (Default Setup, CCR, etc.). The feature flag is restricted to dynamic workflow events or test mode, preventing it from affecting advanced workflows. The PR includes comprehensive unit tests and an end-to-end PR check to validate the functionality.
Changes:
- Added
ForceNightlyfeature flag to enable nightly CLI for dynamic workflows - Enhanced
getCodeQLSourcewith documentation and logic to support forced nightly builds - Added unit tests for both
tools: nightlyand ForceNightly feature flag scenarios - Created new PR check workflow to validate the feature in CI
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/feature-flags.ts | Adds the ForceNightly feature flag definition with environment variable and default value |
| src/setup-codeql.ts | Implements logic to force nightly CLI when feature flag is enabled in dynamic workflows; adds JSDoc documentation and exports for testing |
| src/setup-codeql.test.ts | Adds comprehensive unit tests for nightly CLI selection via both explicit input and feature flag |
| pr-checks/checks/bundle-from-nightly.yml | Defines PR check template to validate ForceNightly feature works as expected |
| .github/workflows/__bundle-from-nightly.yml | Auto-generated workflow file from the PR check template |
| lib/*.js | Auto-generated JavaScript transpilation of TypeScript source changes (not reviewed per guidelines) |
| ]); | ||
| }); | ||
| }); | ||
|
|
There was a problem hiding this comment.
The test for ForceNightly feature flag only covers the case where the feature is enabled and the workflow event is "dynamic". Consider adding negative test cases similar to the AllowToolcacheInput feature (see lines 525-543) to verify that:
- The ForceNightly feature flag does NOT force nightly when the workflow event is not "dynamic" (e.g., "pull_request")
- The ForceNightly feature flag does NOT force nightly when the feature flag is not enabled
These test cases would ensure the feature flag's conditional behavior (restricted to dynamic workflows) is properly validated.
| test("ForceNightly does not force nightly when event is not dynamic", async (t) => { | |
| const loggedMessages: LoggedMessage[] = []; | |
| const logger = getRecordingLogger(loggedMessages); | |
| const features = createFeatures([Feature.ForceNightly]); | |
| process.env["GITHUB_EVENT_NAME"] = "pull_request"; | |
| const getApiClientStub = sinon | |
| .stub(api, "getApiClient") | |
| .throws( | |
| new Error( | |
| "getApiClient should not be called when ForceNightly is not applied", | |
| ), | |
| ); | |
| try { | |
| await withTmpDir(async (tmpDir) => { | |
| setupActionsVars(tmpDir, tmpDir); | |
| await setupCodeql.getCodeQLSource( | |
| undefined, | |
| SAMPLE_DEFAULT_CLI_VERSION, | |
| SAMPLE_DOTCOM_API_DETAILS, | |
| GitHubVariant.DOTCOM, | |
| false, | |
| features, | |
| logger, | |
| ); | |
| }); | |
| // If we reach this point, then getApiClient was not called and the nightly | |
| // path was not taken, which is the expected behavior. | |
| t.pass(); | |
| } finally { | |
| getApiClientStub.restore(); | |
| } | |
| }); | |
| test("ForceNightly does not force nightly when feature flag is disabled", async (t) => { | |
| const loggedMessages: LoggedMessage[] = []; | |
| const logger = getRecordingLogger(loggedMessages); | |
| const features = createFeatures([]); | |
| process.env["GITHUB_EVENT_NAME"] = "dynamic"; | |
| const getApiClientStub = sinon | |
| .stub(api, "getApiClient") | |
| .throws( | |
| new Error( | |
| "getApiClient should not be called when ForceNightly feature flag is disabled", | |
| ), | |
| ); | |
| try { | |
| await withTmpDir(async (tmpDir) => { | |
| setupActionsVars(tmpDir, tmpDir); | |
| await setupCodeql.getCodeQLSource( | |
| undefined, | |
| SAMPLE_DEFAULT_CLI_VERSION, | |
| SAMPLE_DOTCOM_API_DETAILS, | |
| GitHubVariant.DOTCOM, | |
| false, | |
| features, | |
| logger, | |
| ); | |
| }); | |
| // If we reach this point, then getApiClient was not called and the nightly | |
| // path was not taken, which is the expected behavior. | |
| t.pass(); | |
| } finally { | |
| getApiClientStub.restore(); | |
| } | |
| }); |
| * @param features Information about enabled features. | ||
| * @param logger The logger to use. | ||
| * | ||
| * @returns |
There was a problem hiding this comment.
The JSDoc comment for getCodeQLSource has an incomplete @returns tag. Consider adding a description such as:
@returns A CodeQLToolsSource object describing where the CodeQL CLI should be sourced from.
This would be consistent with other functions in this file (e.g., lines 764, 899) that provide complete return value descriptions.
| * @returns | |
| * @returns A CodeQLToolsSource object describing where the CodeQL CLI should be sourced from. |
Adds a
Featurewhich, when enabled, and the workflow was triggered by adynamicevent forcesgetCodeQLSourceto pick the latest, nightly release.Some drive-by improvements and observations:
getCodeQLSource.!toolsInput.startsWith("http")check would probably cause problems if a file happened to have a path that starts withhttp. Probably not a very likely problem, but could be tricky to troubleshoot if it happens. We could improve this by performing more explicit checks forhttp://andhttps://or whether the suspected file exists locally or not. Outside of the scope of this PR though.tools: nightlywhich didn't seem to exist.getNightlyToolsUrlseems to assume that the nightly tag iscodeql-bundle-followed by a semver, but this is no longer the case for nightly releases. There's a fallback logic which handles this fine, but we should probably update this to expect the date-based tags.Risk assessment
For internal use only. Please select the risk level of this change:
Which use cases does this change impact?
Workflow types:
dynamicworkflows (Default Setup, CCR, ...).Products:
analysis-kinds: code-scanning.analysis-kinds: code-quality.Environments:
github.comand/or GitHub Enterprise Cloud with Data Residency.How did/will you validate this change?
.test.tsfiles).pr-checks).If something goes wrong after this change is released, what are the mitigation and rollback strategies?
How will you know if something goes wrong after this change is released?
Are there any special considerations for merging or releasing this change?
Merge / deployment checklist