Skip to content

Commit

Permalink
ci(label): split js logic to file
Browse files Browse the repository at this point in the history
  • Loading branch information
clearloop committed Aug 17, 2023
1 parent d8055ae commit 9595863
Show file tree
Hide file tree
Showing 2 changed files with 167 additions and 97 deletions.
165 changes: 165 additions & 0 deletions .github/actions/label.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
/**
* Javascript module for the label action.
*/

const [owner, repo] = ["gear-tech", "gear"];
const { LABEL, REF, HEAD_SHA } = process.env;
const linux = LABEL === "A0-pleasereview";
const checks = linux ? ["linux", "win-cross"] : ["macos-x86"];
const workflow_id = linux
? ".github/workflows/build.yml"
: ".github/workflows/build-macos.yml";

/**
* Sleep for ms milliseconds.
**/
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));

/**
* If skipping this action.
**/
const skip = async ({ github }) => {
const {
data: { check_runs },
} = await github.rest.checks.listForRef({
owner,
repo,
ref: REF,
});

const runs = linux
? check_runs.filter((run) => run.name === "build")
: check_runs.filter((run) => run.name === "build / macox-x86");

if (runs.length === 0) return true;
if (runs[0].conclusion !== "skipped") return true;

return false;
};

/**
* Create build checks.
**/
const createChecks = async ({ core, github, url }) => {
let status = {};
for (check of checks) {
const { data: res } = await github.rest.checks.create({
owner,
repo,
name: `build / ${check}`,
head_sha: HEAD_SHA,
status: "in_progress",
output: {
title: `Build ${check}`,
summary: `details url: ${url}`,
},
});

core.setInfo(`Created check ${check}`);
status[check] = res;
}

return jobs;
};

/**
* Dispatch the target workflow.
*/
const dispatchWorkflow = async ({ core, github }) => {
await github.rest.actions.createWorkflowDispatch({
owner,
repo,
workflow_id,
ref: REF,
});

await sleep(10000);

// Get the target workflow run
const {
data: { workflow_runs },
} = await github.rest.actions.listWorkflowRuns({
owner,
repo,
workflow_id,
head_sha: HEAD_SHA,
});

if (workflow_runs.length != 1) {
core.setFailed(`Incorrect workflow runs`);
return;
}

return workflow_runs[0];
};

/// List jobs of workflow run.
const listJobs = async ({ github, core, run_id }) => {
const {
data: { jobs },
} = await github.rest.actions.listJobsForWorkflowRun({
owner,
repo,
run_id,
});

if (jobs.length === 0) {
core.setFailed(`Empty jobs from dispatched workflow`);
return;
}

const requiredJobs = jobs.filter((job) => checks.includes(job.name));
if (requiredJobs.length !== checks.length) {
core.setFailed(`Incorrect count for disptached jobs`);
return;
}

return requiredJobs;
};

/**
* The main function.
**/
module.exports = async ({ github, context, core }) => {
if (await skip({ github })) {
core.info("Build has already been processed.");
return;
}

const run = await dispatchWorkflow({ core, github });
let status = await createChecks({ core, github, url: run.html_url });

while (true) {
const jobs = await listJobs({ github, core, run_id: run.id });
completed = jobs.filter((job) => job.status === "completed").length;
core.info(`Completed ${completed} of ${checks.length} jobs.`);

for (job of jobs) {
let checkJob = status[job.name];
if (
checkJob.status !== job.status ||
checkJob.conclusion !== job.conclusion
) {
core.info(
`Updating check ${job.name}, status: ${job.status}, conclusion: ${job.conclusion}`
);
await github.rest.checks.update({
owner,
repo,
check_run_id: checkJob.id,
status: job.status,
conclusion: job.conclusion,
});
} else {
continue;
}
}

if (completed === checks.length) {
core.info("All jobs completed.");
break;
} else {
await sleep(10000);
}
}
};
99 changes: 2 additions & 97 deletions .github/workflows/label.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,100 +26,5 @@ jobs:
REF: ${{ github.head_ref || github.ref_name }}
with:
script: |
const { LABEL, REF, HEAD_SHA } = process.env;
const [owner, repo] = ["gear-tech", "gear"];
const linux = (LABEL === "A0-pleasereview");
// List the latest check runs
const {
data: { check_runs }
} = await github.rest.checks.listForRef({
owner,
repo,
ref: REF,
});
// Filter the traget skipped workflow run.
const runs = linux
?check_runs.filter((run) => run.name === "build")
:check_runs.filter((run) => run.name === "build / macox-x86")
if (runs.length === 0) return;
if (runs[0].conclusion !== "skipped") return;
/**
* The main logic starts from here.
**/
// Dispatch target workflow.
const workflow_id = linux
?".github/workflows/build.yml"
:".github/workflows/build-macos.yml";
const sleep = ms => new Promise(r => setTimeout(r, ms));
await github.rest.actions.createWorkflowDispatch({
owner,
repo,
workflow_id,
ref: REF,
});
await sleep(10000);
// Create check and update status
const { data: { workflow_runs } } = await github.rest.actions.listWorkflowRuns({
owner,
repo,
workflow_id,
head_sha: HEAD_SHA,
});
console.log(workflow_runs);
if (workflow_runs.length != 1) {
core.setFailed(`Empty workflow runs`);
return;
}
const { data: { jobs } } = await github.rest.actions.listJobsForWorkflowRun({
owner,
repo,
run_id: workflow_runs[0].id
});
console.log(jobs);
if (jobs.length === 0) {
core.setFailed(`Empty jobs from dispatched workflow`);
return;
}
const checks = linux
?["linux", "win-cross"]
:["macos-x86"];
for (check of checks) {
let runs = jobs.filter((run) => run.name === check);
if (runs.length !== 1) {
core.setFailed(`Could not find action ${check} from ${workflow_runs}`);
return;
}
const {
status,
conclusion,
id: external_id,
started_at,
url: details_url,
} = runs[0];
const { data: res } = await github.rest.checks.create({
owner,
repo,
name: `build / ${check}`,
head_sha: HEAD_SHA,
details_url,
// external_id,
});
console.log(res);
}
const script = require('./.github/actions/label.js');
await script({ github, context, core });

0 comments on commit 9595863

Please sign in to comment.