You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
177 lines
6.2 KiB
177 lines
6.2 KiB
const core = require('@actions/core') |
|
const github = require('@actions/github') |
|
const AdmZip = require('adm-zip') |
|
const filesize = require('filesize') |
|
const pathname = require('path') |
|
const fs = require('fs') |
|
|
|
async function main() { |
|
try { |
|
const token = core.getInput("github_token", { required: true }) |
|
const workflow = core.getInput("workflow", { required: true }) |
|
const [owner, repo] = core.getInput("repo", { required: true }).split("/") |
|
const pathFromAction = core.getInput("path", { required: true }) |
|
const artifactNamesFromAction = core.getInput("artifacts") ? core.getInput("artifacts") : "*" |
|
let workflowConclusion = core.getInput("workflow_conclusion") |
|
let pr = core.getInput("pr") |
|
let commit = core.getInput("commit") |
|
let branch = core.getInput("branch") |
|
let event = core.getInput("event") |
|
let runID = core.getInput("run_id") |
|
let runNumber = core.getInput("run_number") |
|
let checkArtifacts = core.getInput("check_artifacts") |
|
|
|
const client = github.getOctokit(token) |
|
|
|
console.log("==> Workflow:", workflow) |
|
console.log("==> Repo:", owner + "/" + repo) |
|
console.log("==> Conclusion:", workflowConclusion) |
|
|
|
if (pr) { |
|
console.log("==> PR:", pr) |
|
|
|
const pull = await client.pulls.get({ |
|
owner: owner, |
|
repo: repo, |
|
pull_number: pr, |
|
}) |
|
commit = pull.data.head.sha |
|
} |
|
|
|
if (commit) { |
|
console.log("==> Commit:", commit) |
|
} |
|
|
|
if (branch) { |
|
branch = branch.replace(/^refs\/heads\//, "") |
|
console.log("==> Branch:", branch) |
|
} |
|
|
|
if (event) { |
|
console.log("==> Event:", event) |
|
} |
|
|
|
if (runNumber) { |
|
console.log("==> RunNumber:", runNumber) |
|
} |
|
|
|
if (!runID) { |
|
|
|
for (let pageNumber = 1; pageNumber < 5 && !runID; pageNumber++) { |
|
|
|
let runs = await client.actions.listWorkflowRuns({ |
|
owner: owner, |
|
repo: repo, |
|
workflow_id: workflow, |
|
per_page: 100, |
|
page: pageNumber |
|
}).then(workflowRunsResponse => { |
|
return workflowRunsResponse.data.workflow_runs |
|
.sort((a, b) => { |
|
a_date = new Date(a.created_at) |
|
b_date = new Date(b.created_at) |
|
// descending order |
|
return b_date - a_date |
|
}) |
|
}) |
|
|
|
if (branch) { |
|
runs = runs.filter(run => run.head_branch == branch) |
|
} |
|
|
|
for (const run of runs) { |
|
if (commit && run.head_sha != commit) { |
|
continue |
|
} |
|
if (runNumber && run.run_number != runNumber) { |
|
continue |
|
} |
|
if (workflowConclusion && (workflowConclusion != run.conclusion && workflowConclusion != run.status)) { |
|
continue |
|
} |
|
if (checkArtifacts) { |
|
let artifacts = await client.actions.listWorkflowRunArtifacts({ |
|
owner: owner, |
|
repo: repo, |
|
run_id: run.id, |
|
}) |
|
if (artifacts.data.artifacts.length == 0) { |
|
continue |
|
} |
|
} |
|
runID = run.id |
|
break |
|
} |
|
if (runID) { |
|
break |
|
} |
|
} |
|
|
|
if (!runID) { |
|
throw new Error("no matching workflow run found in last 500 runs") |
|
} |
|
} |
|
|
|
if (runID) { |
|
console.log("==> RunID:", runID) |
|
} else { |
|
throw new Error("no matching workflow run found") |
|
} |
|
|
|
const allArtifacts = await client.paginate(client.actions.listWorkflowRunArtifacts, { |
|
owner: owner, |
|
repo: repo, |
|
run_id: runID, |
|
}) |
|
|
|
// One artifact, a list of artifacts, or all if `name` input is not specified. |
|
const matchesWithRegex = (stringToTest, regexRule) => { |
|
const escapeSpecialChars = (string) => string.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1"); |
|
const builtRegexRule = "^" + regexRule.split("*").map(escapeSpecialChars).join(".*") + "$" |
|
return new RegExp(builtRegexRule).test(stringToTest) |
|
} |
|
const artifactNames = artifactNamesFromAction.split(",").map(artifactName => artifactName.trim()) |
|
|
|
const artifactsToDownload = allArtifacts.filter(artifact => { |
|
return artifactNames.map(name => matchesWithRegex(artifact.name, name)).reduce((prevValue, currValue) => prevValue || currValue) |
|
}) |
|
|
|
if (artifactsToDownload.length == 0) { |
|
throw new Error("no artifacts found") |
|
} |
|
|
|
for (const artifact of artifactsToDownload) { |
|
console.log("==> Artifact:", artifact.id) |
|
|
|
const size = filesize(artifact.size_in_bytes, { base: 10 }) |
|
|
|
console.log(`==> Downloading: ${artifact.name}.zip (${size})`) |
|
|
|
const zip = await client.actions.downloadArtifact({ |
|
owner: owner, |
|
repo: repo, |
|
artifact_id: artifact.id, |
|
archive_format: "zip", |
|
}) |
|
|
|
//const dir = artifacts.length == 1 ? pathFromAction : pathname.join(path, artifact.name) |
|
|
|
fs.mkdirSync(pathFromAction, { recursive: true }) |
|
|
|
const adm = new AdmZip(Buffer.from(zip.data)) |
|
|
|
adm.getEntries().forEach((entry) => { |
|
const action = entry.isDirectory ? "creating" : "inflating" |
|
const filepath = pathname.join(pathFromAction, entry.entryName) |
|
|
|
console.log(` ${action}: ${filepath}`) |
|
}) |
|
|
|
adm.extractAllTo(pathFromAction, true) |
|
} |
|
} catch (error) { |
|
core.setFailed(error.message) |
|
} |
|
} |
|
|
|
main()
|
|
|