Validate workflow to check that all codeql-action versions are the same

This commit is contained in:
Michael B. Gale
2025-09-10 12:18:50 +01:00
parent 31d3ae847e
commit bb98ff4838
4 changed files with 106 additions and 2 deletions

View File

@@ -655,6 +655,65 @@ test("getWorkflowErrors() should not report a warning if there is a workflow_cal
t.deepEqual(...errorCodes(errors, []));
});
test("getWorkflowErrors() should report a warning if different versions of the CodeQL Action are used", async (t) => {
const errors = await getWorkflowErrors(
yaml.load(`
name: "CodeQL"
on:
push:
branches: [main]
jobs:
analyze:
steps:
- uses: github/codeql-action/init@v2
- uses: github/codeql-action/analyze@v3
`) as Workflow,
await getCodeQLForTesting(),
);
t.deepEqual(
...errorCodes(errors, [WorkflowErrors.InconsistentActionVersion]),
);
});
test("getWorkflowErrors() should not report a warning if the same versions of the CodeQL Action are used", async (t) => {
const errors = await getWorkflowErrors(
yaml.load(`
name: "CodeQL"
on:
push:
branches: [main]
jobs:
analyze:
steps:
- uses: github/codeql-action/init@v3
- uses: github/codeql-action/analyze@v3
`) as Workflow,
await getCodeQLForTesting(),
);
t.deepEqual(...errorCodes(errors, []));
});
test("getWorkflowErrors() should not report a warning involving versions of other actions", async (t) => {
const errors = await getWorkflowErrors(
yaml.load(`
name: "CodeQL"
on:
push:
branches: [main]
jobs:
analyze:
steps:
- uses: actions/checkout@v5
- uses: github/codeql-action/init@v3
`) as Workflow,
await getCodeQLForTesting(),
);
t.deepEqual(...errorCodes(errors, []));
});
test("getCategoryInputOrThrow returns category for simple workflow with category", (t) => {
process.env["GITHUB_REPOSITORY"] = "github/codeql-action-fake-repository";
t.is(

View File

@@ -72,6 +72,7 @@ function toCodedErrors(errors: {
export const WorkflowErrors = toCodedErrors({
MissingPushHook: `Please specify an on.push hook to analyze and see code scanning alerts from the default branch on the Security tab.`,
CheckoutWrongHead: `git checkout HEAD^2 is no longer necessary. Please remove this step as Code Scanning recommends analyzing the merge commit for best results.`,
InconsistentActionVersion: `Not all workflow steps that use \`github/codeql-action\` actions use the same version. Please ensure that all such steps use the same version to avoid compatibility issues.`,
});
/**
@@ -161,6 +162,32 @@ export async function getWorkflowErrors(
}
}
// Check that all `github/codeql-action` steps use the same ref, i.e. the same version.
// Mixing different versions of the actions can lead to unpredictable behaviour.
const codeqlStepRefs: string[] = [];
for (const job of Object.values(doc?.jobs || {})) {
if (Array.isArray(job.steps)) {
for (const step of job.steps) {
if (
step.uses !== undefined &&
step.uses.startsWith("github/codeql-action/")
) {
const parts = step.uses.split("@");
if (parts.length >= 2) {
codeqlStepRefs.push(parts[parts.length - 1]);
}
}
}
}
}
if (
codeqlStepRefs.length > 0 &&
!codeqlStepRefs.every((ref) => ref === codeqlStepRefs[0])
) {
errors.push(WorkflowErrors.InconsistentActionVersion);
}
// If there is no push trigger, we will not be able to analyze the default branch.
// So add a warning to the user to add a push trigger.
// If there is a workflow_call trigger, we don't need a push trigger since we assume