Skip to content

Commit bb98ff4

Browse files
committed
Validate workflow to check that all codeql-action versions are the same
1 parent 31d3ae8 commit bb98ff4

File tree

4 files changed

+106
-2
lines changed

4 files changed

+106
-2
lines changed

lib/init-action-post.js

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/init-action.js

Lines changed: 18 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/workflow.test.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,65 @@ test("getWorkflowErrors() should not report a warning if there is a workflow_cal
655655
t.deepEqual(...errorCodes(errors, []));
656656
});
657657

658+
test("getWorkflowErrors() should report a warning if different versions of the CodeQL Action are used", async (t) => {
659+
const errors = await getWorkflowErrors(
660+
yaml.load(`
661+
name: "CodeQL"
662+
on:
663+
push:
664+
branches: [main]
665+
jobs:
666+
analyze:
667+
steps:
668+
- uses: github/codeql-action/init@v2
669+
- uses: github/codeql-action/analyze@v3
670+
`) as Workflow,
671+
await getCodeQLForTesting(),
672+
);
673+
674+
t.deepEqual(
675+
...errorCodes(errors, [WorkflowErrors.InconsistentActionVersion]),
676+
);
677+
});
678+
679+
test("getWorkflowErrors() should not report a warning if the same versions of the CodeQL Action are used", async (t) => {
680+
const errors = await getWorkflowErrors(
681+
yaml.load(`
682+
name: "CodeQL"
683+
on:
684+
push:
685+
branches: [main]
686+
jobs:
687+
analyze:
688+
steps:
689+
- uses: github/codeql-action/init@v3
690+
- uses: github/codeql-action/analyze@v3
691+
`) as Workflow,
692+
await getCodeQLForTesting(),
693+
);
694+
695+
t.deepEqual(...errorCodes(errors, []));
696+
});
697+
698+
test("getWorkflowErrors() should not report a warning involving versions of other actions", async (t) => {
699+
const errors = await getWorkflowErrors(
700+
yaml.load(`
701+
name: "CodeQL"
702+
on:
703+
push:
704+
branches: [main]
705+
jobs:
706+
analyze:
707+
steps:
708+
- uses: actions/checkout@v5
709+
- uses: github/codeql-action/init@v3
710+
`) as Workflow,
711+
await getCodeQLForTesting(),
712+
);
713+
714+
t.deepEqual(...errorCodes(errors, []));
715+
});
716+
658717
test("getCategoryInputOrThrow returns category for simple workflow with category", (t) => {
659718
process.env["GITHUB_REPOSITORY"] = "github/codeql-action-fake-repository";
660719
t.is(

src/workflow.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ function toCodedErrors(errors: {
7272
export const WorkflowErrors = toCodedErrors({
7373
MissingPushHook: `Please specify an on.push hook to analyze and see code scanning alerts from the default branch on the Security tab.`,
7474
CheckoutWrongHead: `git checkout HEAD^2 is no longer necessary. Please remove this step as Code Scanning recommends analyzing the merge commit for best results.`,
75+
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.`,
7576
});
7677

7778
/**
@@ -161,6 +162,32 @@ export async function getWorkflowErrors(
161162
}
162163
}
163164

165+
// Check that all `github/codeql-action` steps use the same ref, i.e. the same version.
166+
// Mixing different versions of the actions can lead to unpredictable behaviour.
167+
const codeqlStepRefs: string[] = [];
168+
for (const job of Object.values(doc?.jobs || {})) {
169+
if (Array.isArray(job.steps)) {
170+
for (const step of job.steps) {
171+
if (
172+
step.uses !== undefined &&
173+
step.uses.startsWith("github/codeql-action/")
174+
) {
175+
const parts = step.uses.split("@");
176+
if (parts.length >= 2) {
177+
codeqlStepRefs.push(parts[parts.length - 1]);
178+
}
179+
}
180+
}
181+
}
182+
}
183+
184+
if (
185+
codeqlStepRefs.length > 0 &&
186+
!codeqlStepRefs.every((ref) => ref === codeqlStepRefs[0])
187+
) {
188+
errors.push(WorkflowErrors.InconsistentActionVersion);
189+
}
190+
164191
// If there is no push trigger, we will not be able to analyze the default branch.
165192
// So add a warning to the user to add a push trigger.
166193
// If there is a workflow_call trigger, we don't need a push trigger since we assume

0 commit comments

Comments
 (0)