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

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()