From f6b0bace624032e30a85a8fd9c1a7f8f611f5737 Mon Sep 17 00:00:00 2001 From: Roman Gilg Date: Thu, 15 Feb 2024 14:58:07 +0100 Subject: [PATCH] Optionally search for workflows (#270) * style: remove trailing whitespace * docs: update url The API is now versioned. The link has changed. * feat: optional search for workflows When no workflow is set, until now the current workflow has been chosen. But the workflow we get the artifact from could be another one determined by other criteria like the branch and the artifact name. We provide a new option workflow_search, that if set, allows us to search for the workflow repo-wide according to the other provided data. --- README.md | 3 +++ action.yml | 11 +++++++++-- main.js | 42 +++++++++++++++++++++++++++++------------- 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 301e284e..4d8d9483 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,9 @@ Let's suppose you have a workflow with a job in it that at the end uploads an ar # Optional, workflow file name or ID # If not specified, will be inferred from run_id (if run_id is specified), or will be the current workflow workflow: workflow_name.yml + # If no workflow is set and workflow_search set to true, then the most recent workflow matching + # all other criteria will be looked up instead of using the current workflow + workflow_search: false # Optional, the status or conclusion of a completed workflow to search for # Can be one of a workflow conclusion: # "failure", "success", "neutral", "cancelled", "skipped", "timed_out", "action_required" diff --git a/action.yml b/action.yml index 25491512..973f9393 100644 --- a/action.yml +++ b/action.yml @@ -15,11 +15,18 @@ inputs: If not specified, will be inferred from run_id (if run_id is specified), or will be the current workflow required: false + workflow_search: + description: | + Most recent workflow matching all other criteria will be looked up instead of using the current workflow + + https://docs.github.com/de/rest/actions/workflow-runs?apiVersion=2022-11-28#list-workflow-runs-for-a-repository + required: false + default: false workflow_conclusion: description: | Wanted status or conclusion to search for in recent runs - https://docs.github.com/en/free-pro-team@latest/rest/reference/actions#list-workflow-runs + https://docs.github.com/de/rest/actions/workflow-runs?apiVersion=2022-11-28#list-workflow-runs-for-a-workflow required: false default: success repo: @@ -78,7 +85,7 @@ inputs: required: false description: | Choose how to exit the action if no artifact is found - + fail, warn or ignore default: fail outputs: diff --git a/main.js b/main.js index a24fee48..422d9088 100644 --- a/main.js +++ b/main.js @@ -19,6 +19,15 @@ async function downloadAction(name, path) { core.setOutput("found_artifact", true) } +async function getWorkflow(client, owner, repo, runID) { + const run = await client.rest.actions.getWorkflowRun({ + owner: owner, + repo: repo, + run_id: runID || github.context.runId, + }) + return run.data.workflow_id +} + async function main() { try { const token = core.getInput("github_token", { required: true }) @@ -29,6 +38,7 @@ async function main() { const skipUnpack = core.getBooleanInput("skip_unpack") const ifNoArtifactFound = core.getInput("if_no_artifact_found") let workflow = core.getInput("workflow") + let workflowSearch = core.getInput("workflow_search") let workflowConclusion = core.getInput("workflow_conclusion") let pr = core.getInput("pr") let commit = core.getInput("commit") @@ -47,16 +57,13 @@ async function main() { core.info(`==> Artifact name: ${name}`) core.info(`==> Local path: ${path}`) - if (!workflow) { - const run = await client.rest.actions.getWorkflowRun({ - owner: owner, - repo: repo, - run_id: runID || github.context.runId, - }) - workflow = run.data.workflow_id + if (!workflow && !workflowSearch) { + workflow = await getWorkflow(client, owner, repo, runID) } - core.info(`==> Workflow name: ${workflow}`) + if (workflow) { + core.info(`==> Workflow name: ${workflow}`) + } core.info(`==> Workflow conclusion: ${workflowConclusion}`) const uniqueInputSets = [ @@ -106,17 +113,20 @@ async function main() { core.info(`==> Allow forks: ${allowForks}`) if (!runID) { + const runGetter = workflow ? client.rest.actions.listWorkflowRuns : client.rest.actions.listWorkflowRunsForRepo // Note that the runs are returned in most recent first order. - for await (const runs of client.paginate.iterator(client.rest.actions.listWorkflowRuns, { + for await (const runs of client.paginate.iterator(runGetter, { owner: owner, repo: repo, - workflow_id: workflow, + ...(workflow ? { workflow_id: workflow } : {}), ...(branch ? { branch } : {}), ...(event ? { event } : {}), - ...(commit ? { head_sha: commit } : {}), } )) { for (const run of runs.data) { + if (commit && run.head_sha != commit) { + continue + } if (runNumber && run.run_number != runNumber) { continue } @@ -148,9 +158,15 @@ async function main() { } } } + runID = run.id core.info(`==> (found) Run ID: ${runID}`) core.info(`==> (found) Run date: ${run.created_at}`) + + if (!workflow) { + workflow = await getWorkflow(client, owner, repo, runID) + core.info(`==> (found) Workflow: ${workflow}`) + } break } if (runID) { @@ -222,7 +238,7 @@ async function main() { } core.setOutput("found_artifact", true) - + for (const artifact of artifacts) { core.info(`==> Artifact: ${artifact.id}`) @@ -277,7 +293,7 @@ async function main() { function setExitMessage(ifNoArtifactFound, message) { core.setOutput("found_artifact", false) - + switch (ifNoArtifactFound) { case "fail": core.setFailed(message)