This is an automated email from the ASF dual-hosted git repository. potiuk pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/airflow-cancel-workflow-runs.git
commit f696c622a83e4a63fff74848d3b149074658607d Author: Jarek Potiuk <[email protected]> AuthorDate: Sat Oct 10 15:11:03 2020 +0200 Added capability of skipping some event types (#7) --- README.md | 6 ++++++ action.yml | 5 +++++ dist/index.js | 24 +++++++++++++++++------- src/main.ts | 30 +++++++++++++++++++++++++----- 4 files changed, 53 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 9de025f..5354a8e 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,8 @@ and `schedule` events are no longer needed. | `notifyPRCancelMessage` | no | | Optional cancel message to use instead of the default one when notifyPRCancel is true. It is only used in 'self' cancelling mode. | | `notifyPRMessageStart` | no | | Only for workflow_run events triggered by the PRs. If not empty, it notifies those PRs with the message specified at the start of the workflow - adding the link to the triggered workflow_run. | | `jobNameRegexps` | no | | An array of job name regexps. Only runs containing any job name matching any of of the regexp in this array are considered for cancelling in `failedJobs` and `namedJobs` cancel modes. | +| `skipEventTypes` | no | | Array of event names that should be skipped when cancelling (JSON-encoded string). This might be used in order to skip direct pushes or scheduled events.. | + The job cancel modes work as follows: @@ -303,6 +305,9 @@ This works for all kind of triggering events (`push`, `pull_request`, `schedule` events triggered in the local repository, as well as triggered from the forks, so you do not need to set up any extra actions to cancel internal Pushes/Pull Requests. +You can also choose to skip certain types of events (for example `push` and `schedule` if you want your +jobs to run to full completion for this kind of events. + ```yaml name: Cancelling on: @@ -322,6 +327,7 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} sourceRunId: ${{ github.event.workflow_run.id }} notifyPRCancel: true + skipEventTypes: '["push", "schedule"]' ``` Note that `duplicate` cancel mode cannot be used for `workflow_run` type of event without `sourceId` input. diff --git a/action.yml b/action.yml index 7accb50..8fc9087 100644 --- a/action.yml +++ b/action.yml @@ -41,6 +41,11 @@ inputs: Array of job name regexps (JSON-encoded string). Used by `failedJobs` and `namedJobs` cancel modes to match job names of workflow runs. required: false + skipEventTypes: + description: | + Array of event names that should be skipped when cancelling (JSON-encoded string). This might be used + in order to skip direct pushes or scheduled events. + required: false runs: using: 'node12' main: 'dist/index.js' diff --git a/dist/index.js b/dist/index.js index 7f28bf7..53c47fc 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1622,7 +1622,7 @@ function getWorkflowRuns(octokit, statusValues, cancelMode, createListRunQuery) return workflowRuns; }); } -function shouldBeCancelled(octokit, owner, repo, runItem, headRepo, cancelMode, sourceRunId, jobNamesRegexps) { +function shouldBeCancelled(octokit, owner, repo, runItem, headRepo, cancelMode, sourceRunId, jobNamesRegexps, skipEventTypes) { return __awaiter(this, void 0, void 0, function* () { if ('completed' === runItem.status.toString()) { core.info(`\nThe run ${runItem.id} is completed. Not cancelling it.\n`); @@ -1632,6 +1632,11 @@ function shouldBeCancelled(octokit, owner, repo, runItem, headRepo, cancelMode, core.info(`\nThe run ${runItem.id} is (${runItem.event} event - not in ${CANCELLABLE_RUNS}). Not cancelling it.\n`); return false; } + if (skipEventTypes.includes(runItem.event.toString())) { + core.info(`\nThe run ${runItem.id} is (${runItem.event} event - ` + + `it is in skipEventTypes ${skipEventTypes}). Not cancelling it.\n`); + return false; + } if (cancelMode === CancelMode.FAILED_JOBS) { // Cancel all jobs that have failed jobs (no matter when started) if (yield jobsMatchingNames(octokit, owner, repo, runItem.id, jobNamesRegexps, true)) { @@ -1705,7 +1710,7 @@ function cancelRun(octokit, owner, repo, runId) { } }); } -function findAndCancelRuns(octokit, selfRunId, sourceWorkflowId, sourceRunId, owner, repo, headRepo, headBranch, sourceEventName, cancelMode, notifyPRCancel, notifyPRMessageStart, jobNameRegexps, reason) { +function findAndCancelRuns(octokit, selfRunId, sourceWorkflowId, sourceRunId, owner, repo, headRepo, headBranch, sourceEventName, cancelMode, notifyPRCancel, notifyPRMessageStart, jobNameRegexps, skipEventTypes, reason) { return __awaiter(this, void 0, void 0, function* () { const statusValues = ['queued', 'in_progress']; const workflowRuns = yield getWorkflowRuns(octokit, statusValues, cancelMode, function (status) { @@ -1734,7 +1739,7 @@ function findAndCancelRuns(octokit, selfRunId, sourceWorkflowId, sourceRunId, ow const pullRequestToNotify = []; for (const [key, runItem] of workflowRuns) { core.info(`\nChecking run number: ${key}, RunId: ${runItem.id}, Url: ${runItem.url}. Status ${runItem.status}\n`); - if (yield shouldBeCancelled(octokit, owner, repo, runItem, headRepo, cancelMode, sourceRunId, jobNameRegexps)) { + if (yield shouldBeCancelled(octokit, owner, repo, runItem, headRepo, cancelMode, sourceRunId, jobNameRegexps, skipEventTypes)) { if (notifyPRCancel && runItem.event === 'pull_request') { const pullRequest = yield findPullRequest(octokit, owner, repo, runItem.head_repository.owner.login, runItem.head_branch, runItem.head_sha); if (pullRequest) { @@ -1832,7 +1837,7 @@ function getOrigin(octokit, runId, owner, repo) { ]; }); } -function performCancelJob(octokit, selfRunId, sourceWorkflowId, sourceRunId, owner, repo, headRepo, headBranch, sourceEventName, cancelMode, notifyPRCancel, notifyPRCancelMessage, notifyPRMessageStart, jobNameRegexps) { +function performCancelJob(octokit, selfRunId, sourceWorkflowId, sourceRunId, owner, repo, headRepo, headBranch, sourceEventName, cancelMode, notifyPRCancel, notifyPRCancelMessage, notifyPRMessageStart, jobNameRegexps, skipEventTypes) { return __awaiter(this, void 0, void 0, function* () { core.info('\n###################################################################################\n'); core.info(`All parameters: owner: ${owner}, repo: ${repo}, run id: ${sourceRunId}, ` + @@ -1862,7 +1867,7 @@ function performCancelJob(octokit, selfRunId, sourceWorkflowId, sourceRunId, own throw Error(`Wrong cancel mode ${cancelMode}! This should never happen.`); } core.info('\n###################################################################################\n'); - return yield findAndCancelRuns(octokit, selfRunId, sourceWorkflowId, sourceRunId, owner, repo, headRepo, headBranch, sourceEventName, cancelMode, notifyPRCancel, notifyPRMessageStart, jobNameRegexps, reason); + return yield findAndCancelRuns(octokit, selfRunId, sourceWorkflowId, sourceRunId, owner, repo, headRepo, headBranch, sourceEventName, cancelMode, notifyPRCancel, notifyPRMessageStart, jobNameRegexps, skipEventTypes, reason); }); } function verboseOutput(name, value) { @@ -1885,8 +1890,13 @@ function run() { const jobNameRegexps = jobNameRegexpsString ? JSON.parse(jobNameRegexpsString) : []; + const skipEventTypesString = core.getInput('skipEventTypes'); + const skipEventTypes = skipEventTypesString + ? JSON.parse(skipEventTypesString) + : []; const [owner, repo] = repository.split('/'); - core.info(`\nGetting workflow id for source run id: ${sourceRunId}, owner: ${owner}, repo: ${repo}\n`); + core.info(`\nGetting workflow id for source run id: ${sourceRunId}, owner: ${owner}, repo: ${repo},` + + ` skipEventTypes: ${skipEventTypes}\n`); const sourceWorkflowId = yield getWorkflowId(octokit, sourceRunId, owner, repo); core.info(`Repository: ${repository}, Owner: ${owner}, Repo: ${repo}, ` + `Event name: ${eventName}, CancelMode: ${cancelMode}, ` + @@ -1926,7 +1936,7 @@ function run() { body: `${notifyPRMessageStart} [The workflow run](${selfWorkflowRunUrl})` }); } - const cancelledRuns = yield performCancelJob(octokit, selfRunId, sourceWorkflowId, sourceRunId, owner, repo, headRepo, headBranch, sourceEventName, cancelMode, notifyPRCancel, notifyPRCancelMessage, notifyPRMessageStart, jobNameRegexps); + const cancelledRuns = yield performCancelJob(octokit, selfRunId, sourceWorkflowId, sourceRunId, owner, repo, headRepo, headBranch, sourceEventName, cancelMode, notifyPRCancel, notifyPRCancelMessage, notifyPRMessageStart, jobNameRegexps, skipEventTypes); verboseOutput('cancelledRuns', JSON.stringify(cancelledRuns)); }); } diff --git a/src/main.ts b/src/main.ts index 44ef1bc..e7bcbe8 100644 --- a/src/main.ts +++ b/src/main.ts @@ -204,7 +204,8 @@ async function shouldBeCancelled( headRepo: string, cancelMode: CancelMode, sourceRunId: number, - jobNamesRegexps: string[] + jobNamesRegexps: string[], + skipEventTypes: string[] ): Promise<boolean> { if ('completed' === runItem.status.toString()) { core.info(`\nThe run ${runItem.id} is completed. Not cancelling it.\n`) @@ -216,6 +217,13 @@ async function shouldBeCancelled( ) return false } + if (skipEventTypes.includes(runItem.event.toString())) { + core.info( + `\nThe run ${runItem.id} is (${runItem.event} event - ` + + `it is in skipEventTypes ${skipEventTypes}). Not cancelling it.\n` + ) + return false + } if (cancelMode === CancelMode.FAILED_JOBS) { // Cancel all jobs that have failed jobs (no matter when started) if ( @@ -333,6 +341,7 @@ async function findAndCancelRuns( notifyPRCancel: boolean, notifyPRMessageStart: string, jobNameRegexps: string[], + skipEventTypes: string[], reason: string ): Promise<number[]> { const statusValues = ['queued', 'in_progress'] @@ -406,7 +415,8 @@ async function findAndCancelRuns( headRepo, cancelMode, sourceRunId, - jobNameRegexps + jobNameRegexps, + skipEventTypes ) ) { if (notifyPRCancel && runItem.event === 'pull_request') { @@ -570,7 +580,8 @@ async function performCancelJob( notifyPRCancel: boolean, notifyPRCancelMessage: string, notifyPRMessageStart: string, - jobNameRegexps: string[] + jobNameRegexps: string[], + skipEventTypes: string[] ): Promise<number[]> { core.info( '\n###################################################################################\n' @@ -627,6 +638,7 @@ async function performCancelJob( notifyPRCancel, notifyPRMessageStart, jobNameRegexps, + skipEventTypes, reason ) } @@ -653,10 +665,17 @@ async function run(): Promise<void> { const jobNameRegexps = jobNameRegexpsString ? JSON.parse(jobNameRegexpsString) : [] + + const skipEventTypesString = core.getInput('skipEventTypes') + const skipEventTypes = skipEventTypesString + ? JSON.parse(skipEventTypesString) + : [] + const [owner, repo] = repository.split('/') core.info( - `\nGetting workflow id for source run id: ${sourceRunId}, owner: ${owner}, repo: ${repo}\n` + `\nGetting workflow id for source run id: ${sourceRunId}, owner: ${owner}, repo: ${repo},` + + ` skipEventTypes: ${skipEventTypes}\n` ) const sourceWorkflowId = await getWorkflowId( octokit, @@ -738,7 +757,8 @@ async function run(): Promise<void> { notifyPRCancel, notifyPRCancelMessage, notifyPRMessageStart, - jobNameRegexps + jobNameRegexps, + skipEventTypes ) verboseOutput('cancelledRuns', JSON.stringify(cancelledRuns))
