Skip to content

Commit 1a34fc8

Browse files
committed
Refactor job generation into generateJob
1 parent 6aad426 commit 1a34fc8

File tree

1 file changed

+120
-97
lines changed

1 file changed

+120
-97
lines changed

pr-checks/sync.ts

Lines changed: 120 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,122 @@ function getSetupSteps(checkSpecification: Specification): {
351351
return { inputs, steps };
352352
}
353353

354+
/**
355+
* Generates an Actions job from the `checkSpecification`.
356+
*
357+
* @param specDocument
358+
* The raw YAML document of the PR check specification.
359+
* Used to extract `jobs` without losing the original formatting.
360+
* @param checkSpecification The PR check specification.
361+
* @returns The job and additional workflow inputs.
362+
*/
363+
function generateJob(
364+
specDocument: yaml.Document,
365+
checkSpecification: Specification,
366+
) {
367+
const matrix: Array<Record<string, any>> =
368+
generateJobMatrix(checkSpecification);
369+
370+
const useAllPlatformBundle = checkSpecification.useAllPlatformBundle
371+
? checkSpecification.useAllPlatformBundle
372+
: "false";
373+
374+
// Determine which languages or frameworks have to be installed.
375+
const setupInfo = getSetupSteps(checkSpecification);
376+
const workflowInputs = setupInfo.inputs;
377+
378+
// Construct the workflow steps needed for this check.
379+
const steps: any[] = [
380+
{
381+
name: "Check out repository",
382+
uses: "actions/checkout@v6",
383+
},
384+
{
385+
name: "Prepare test",
386+
id: "prepare-test",
387+
uses: "./.github/actions/prepare-test",
388+
with: {
389+
version: "${{ matrix.version }}",
390+
"use-all-platform-bundle": useAllPlatformBundle,
391+
// If the action is being run from a container, then do not setup kotlin.
392+
// This is because the kotlin binaries cannot be downloaded from the container.
393+
"setup-kotlin": "container" in checkSpecification ? "false" : "true",
394+
},
395+
},
396+
...setupInfo.steps,
397+
];
398+
399+
const installYq = checkSpecification.installYq;
400+
401+
if (installYq) {
402+
steps.push({
403+
name: "Install yq",
404+
if: "runner.os == 'Windows'",
405+
env: {
406+
YQ_PATH: "${{ runner.temp }}/yq",
407+
// This is essentially an arbitrary version of `yq`, which happened to be the one that
408+
// `choco` fetched when we moved away from using that here.
409+
// See https://github.com/github/codeql-action/pull/3423
410+
YQ_VERSION: "v4.50.1",
411+
},
412+
run:
413+
'gh release download --repo mikefarah/yq --pattern "yq_windows_amd64.exe" "$YQ_VERSION" -O "$YQ_PATH/yq.exe"\n' +
414+
'echo "$YQ_PATH" >> "$GITHUB_PATH"',
415+
});
416+
}
417+
418+
// Extract the sequence of steps from the YAML document to persist as much formatting as possible.
419+
const specSteps = specDocument.get("steps") as yaml.YAMLSeq;
420+
421+
// A handful of workflow specifications use double quotes for values, while we generally use single quotes.
422+
// This replaces double quotes with single quotes for consistency.
423+
yaml.visit(specSteps, {
424+
Scalar(_key, node) {
425+
if (node.type === "QUOTE_DOUBLE") {
426+
node.type = "QUOTE_SINGLE";
427+
}
428+
},
429+
});
430+
431+
// Add the generated steps in front of the ones from the specification.
432+
specSteps.items.unshift(...steps);
433+
434+
const checkJob: Record<string, any> = {
435+
strategy: {
436+
"fail-fast": false,
437+
matrix: {
438+
include: matrix,
439+
},
440+
},
441+
name: checkSpecification.name,
442+
if: "github.triggering_actor != 'dependabot[bot]'",
443+
permissions: {
444+
contents: "read",
445+
"security-events": "read",
446+
},
447+
"timeout-minutes": 45,
448+
"runs-on": "${{ matrix.os }}",
449+
steps: specSteps,
450+
};
451+
452+
if (checkSpecification.permissions) {
453+
checkJob.permissions = checkSpecification.permissions;
454+
}
455+
456+
for (const key of ["env", "container", "services"] as const) {
457+
if (checkSpecification[key] !== undefined) {
458+
checkJob[key] = checkSpecification[key];
459+
}
460+
}
461+
462+
checkJob.env = checkJob.env ?? {};
463+
if (!("CODEQL_ACTION_TEST_MODE" in checkJob.env)) {
464+
checkJob.env.CODEQL_ACTION_TEST_MODE = true;
465+
}
466+
467+
return { checkJob, workflowInputs };
468+
}
469+
354470
/**
355471
* Main entry point for the sync script.
356472
*/
@@ -383,103 +499,10 @@ function main(): void {
383499

384500
console.log(`Processing: ${checkName} — "${checkSpecification.name}"`);
385501

386-
const matrix: Array<Record<string, any>> = generateJobMatrix(checkSpecification);
387-
const useAllPlatformBundle = checkSpecification.useAllPlatformBundle
388-
? checkSpecification.useAllPlatformBundle
389-
: "false";
390-
391-
// Determine which languages or frameworks have to be installed.
392-
const setupInfo = getSetupSteps(checkSpecification);
393-
const workflowInputs = setupInfo.inputs;
394-
395-
// Construct the workflow steps needed for this check.
396-
const steps: any[] = [
397-
{
398-
name: "Check out repository",
399-
uses: "actions/checkout@v6",
400-
},
401-
{
402-
name: "Prepare test",
403-
id: "prepare-test",
404-
uses: "./.github/actions/prepare-test",
405-
with: {
406-
version: "${{ matrix.version }}",
407-
"use-all-platform-bundle": useAllPlatformBundle,
408-
// If the action is being run from a container, then do not setup kotlin.
409-
// This is because the kotlin binaries cannot be downloaded from the container.
410-
"setup-kotlin": "container" in checkSpecification ? "false" : "true",
411-
},
412-
},
413-
...setupInfo.steps,
414-
];
415-
416-
const installYq = checkSpecification.installYq;
417-
418-
if (installYq) {
419-
steps.push({
420-
name: "Install yq",
421-
if: "runner.os == 'Windows'",
422-
env: {
423-
YQ_PATH: "${{ runner.temp }}/yq",
424-
// This is essentially an arbitrary version of `yq`, which happened to be the one that
425-
// `choco` fetched when we moved away from using that here.
426-
// See https://github.com/github/codeql-action/pull/3423
427-
YQ_VERSION: "v4.50.1",
428-
},
429-
run:
430-
'gh release download --repo mikefarah/yq --pattern "yq_windows_amd64.exe" "$YQ_VERSION" -O "$YQ_PATH/yq.exe"\n' +
431-
'echo "$YQ_PATH" >> "$GITHUB_PATH"',
432-
});
433-
}
434-
435-
// Extract the sequence of steps from the YAML document to persist as much formatting as possible.
436-
const specSteps = specDocument.get("steps") as yaml.YAMLSeq;
437-
438-
// A handful of workflow specifications use double quotes for values, while we generally use single quotes.
439-
// This replaces double quotes with single quotes for consistency.
440-
yaml.visit(specSteps, {
441-
Scalar(_key, node) {
442-
if (node.type === "QUOTE_DOUBLE") {
443-
node.type = "QUOTE_SINGLE";
444-
}
445-
},
446-
});
447-
448-
// Add the generated steps in front of the ones from the specification.
449-
specSteps.items.unshift(...steps);
450-
451-
const checkJob: Record<string, any> = {
452-
strategy: {
453-
"fail-fast": false,
454-
matrix: {
455-
include: matrix,
456-
},
457-
},
458-
name: checkSpecification.name,
459-
if: "github.triggering_actor != 'dependabot[bot]'",
460-
permissions: {
461-
contents: "read",
462-
"security-events": "read",
463-
},
464-
"timeout-minutes": 45,
465-
"runs-on": "${{ matrix.os }}",
466-
steps: specSteps,
467-
};
468-
469-
if (checkSpecification.permissions) {
470-
checkJob.permissions = checkSpecification.permissions;
471-
}
472-
473-
for (const key of ["env", "container", "services"] as const) {
474-
if (checkSpecification[key] !== undefined) {
475-
checkJob[key] = checkSpecification[key];
476-
}
477-
}
478-
479-
checkJob.env = checkJob.env ?? {};
480-
if (!("CODEQL_ACTION_TEST_MODE" in checkJob.env)) {
481-
checkJob.env.CODEQL_ACTION_TEST_MODE = true;
482-
}
502+
const { checkJob, workflowInputs } = generateJob(
503+
specDocument,
504+
checkSpecification,
505+
);
483506

484507
// If this check belongs to a named collection, record it.
485508
if (checkSpecification.collection) {

0 commit comments

Comments
 (0)