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 f4a9f5b commit 8a361e6
Show file tree
Hide file tree
Showing 3 changed files with 179 additions and 98 deletions.
175 changes: 175 additions & 0 deletions .github/actions/label/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
/**
* 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"] : ["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" || run.name === "build / linux")
: check_runs.filter((run) => run.name === "build / macox-x86");

if (runs.length === 0) return false;
for (run of runs) {
if (run.conclusion !== "skipped") return true;
}

return false;
};

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

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

return status;
};

/**
* 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, core }) => {
if (await skip({ github })) {
core.info("Build has already been processed.");
return;
}

const run = await dispatchWorkflow({ core, github });
let labelChecks = await createChecks({ core, github });

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

for (job of jobs) {
let checkJob = labelChecks[job.name];
if (
checkJob.status !== job.status ||
checkJob.conclusion !== job.conclusion
) {
core.info(
`Updating check ${job.name}, status: ${job.status}, conclusion: ${job.conclusion}`
);

let { status, conclusion } = job;

let data = {
owner,
repo,
check_run_id: checkJob.id,
status,
output: {
title: `Build ${job.name}`,
summary: `ref ${job.html_url}`,
},
};

labelChecks[job.name].status = status;
if (conclusion) {
data.conclusion = conclusion;
labelChecks[job.name].conclusion = conclusion;
}

await github.rest.checks.update(data);
} else {
continue;
}
}

if (completed === checks.length) {
core.info("All jobs completed.");
break;
} else {
await sleep(10000);
}
}
};
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ jobs:
env:
CARGO_BUILD_TARGET: x86_64-pc-windows-msvc

macos-x86:
macos:
needs: linux
if: ${{ always() && inputs.macos }}
uses: ./.github/workflows/build-macos.yml
100 changes: 3 additions & 97 deletions .github/workflows/label.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Prefix A for adjusting the new created checks into this check suite.
name: Label

on:
Expand Down Expand Up @@ -26,100 +27,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/build.js');
await script({ github, core });

0 comments on commit 8a361e6

Please sign in to comment.