Skip to content

Commit

Permalink
feat(action): add last-successful-state parameter (nrwl#146)
Browse files Browse the repository at this point in the history
  • Loading branch information
joh-klein committed Jun 12, 2024
1 parent d0adc4e commit d945754
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 23 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ jobs:
# Default: push
last-successful-event: ""

# One or more states of the last workflow that is to be considered successful.
# Possible values: completed, action_required, cancelled, failure, neutral, skipped, stale, success, timed_out, in_progress, queued, requested, waiting, pending"
#
# Default: "success"
last-successful-state: "waiting,success"

# The path where your repository is. This is only required for cases where the repository code is checked out or moved to a specific path.
#
# Default: .
Expand Down
6 changes: 5 additions & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ inputs:
last-successful-event:
description: "The type of event to check for the last successful commit corresponding to that workflow-id, e.g. push, pull_request, release etc"
default: "push"
last-successful-state:
description: "The state of the last workflow that is to be considered successful, one or more of completed, action_required, cancelled, failure, neutral, skipped, stale, success, timed_out, in_progress, queued, requested, waiting, pending"
default: "success"
working-directory:
description: "The directory where your repository is located"
default: "."
Expand Down Expand Up @@ -49,7 +52,8 @@ runs:
working_directory: ${{ inputs.working-directory }}
working_id: ${{ inputs.workflow-id }}
fallback_sha: ${{ inputs.fallback-sha }}
run: node "$GITHUB_ACTION_PATH/dist/index.js" "$gh_token" "$main_branch_name" "$error_on_no_successful_workflow" "$last_successful_event" "$working_directory" "$working_id" "$fallback_sha"
last_successful_state: ${{ inputs.last-successful-state }}
run: node "$GITHUB_ACTION_PATH/dist/index.js" "$gh_token" "$main_branch_name" "$error_on_no_successful_workflow" "$last_successful_event" "$working_directory" "$working_id" "$fallback_sha" "$last_successful_state"

- name: Log base and head SHAs used for nx affected
shell: bash
Expand Down
59 changes: 37 additions & 22 deletions find-successful-workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const lastSuccessfulEvent = process.argv[5];
const workingDirectory = process.argv[6];
const workflowId = process.argv[7];
const fallbackSHA = process.argv[8];
const lastSuccessfulState = process.argv[9];
const defaultWorkingDirectory = ".";

const ProxifiedClient = Octokit.plugin(proxyPlugin);
Expand Down Expand Up @@ -171,29 +172,43 @@ async function findSuccessfulCommit(
`Workflow Id not provided. Using workflow '${workflow_id}'\n`,
);
}
// fetch all workflow runs on a given repo/branch/workflow with push and success
const shas = await octokit
.request(
`GET /repos/${owner}/${repo}/actions/workflows/${workflow_id}/runs`,
{
owner,
repo,
// on some workflow runs we do not have branch property
branch:
lastSuccessfulEvent === "push" ||
lastSuccessfulEvent === "workflow_dispatch"
? branch
: undefined,
workflow_id,
event: lastSuccessfulEvent,
status: "success",
},
)
.then(({ data: { workflow_runs } }) =>
workflow_runs.map((run: { head_sha: any }) => run.head_sha),
);

return await findExistingCommit(octokit, branch, shas);
// on some workflow runs we do not have branch property
const branchProperty =
lastSuccessfulEvent === "push" ||
lastSuccessfulEvent === "workflow_dispatch"
? branch
: undefined;

const workflowStatesConsideredSuccessful = lastSuccessfulState.split(",");

const iterator = octokit.paginate.iterator(
`GET /repos/${owner}/${repo}/actions/workflows/${workflow_id}/runs`,
{
owner,
repo,
branch: branchProperty,
workflow_id,
event: lastSuccessfulEvent,
per_page: 100,
},
);

// iterate through each response
for await (const { data: workflow_runs } of iterator) {
const shas: string[] = workflow_runs
.filter(
(run: { status: string; conclusion: string }) =>
workflowStatesConsideredSuccessful.includes(run.status) ||
workflowStatesConsideredSuccessful.includes(run.conclusion),
)
.map((run: { head_sha: string }) => run.head_sha);

const firstExistingCommit = await findExistingCommit(octokit, branch, shas);
if (firstExistingCommit) {
return firstExistingCommit;
}
}
}

async function findMergeBaseRef(): Promise<string> {
Expand Down

0 comments on commit d945754

Please sign in to comment.