From 4aa7907322900a796212e404c07f305045f22f9d Mon Sep 17 00:00:00 2001 From: Felix Kirchengast <17876666+fkirc@users.noreply.github.com> Date: Tue, 15 Dec 2020 21:45:47 +0100 Subject: [PATCH] Skip outdated runs (#70) --- .github/workflows/test.yml | 2 +- README.md | 6 ++++-- action.yml | 2 +- dist/index.js | 20 ++++++++++++++------ src/index.ts | 21 ++++++++++++++------- 5 files changed, 34 insertions(+), 17 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1b77f0b..0d9515b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -54,7 +54,7 @@ jobs: github_token: ${{ github.token }} paths_ignore: '["**/*.md"]' cancel_others: 'true' - concurrent_skipping: 'always' + concurrent_skipping: 'outdated_runs' do_not_skip: '["pull_request", "workflow_dispatch", "schedule"]' - if: ${{ steps.skip_check.outputs.should_skip == 'false' }} run: | diff --git a/README.md b/README.md index b4c35ec..dc6cbd0 100644 --- a/README.md +++ b/README.md @@ -29,8 +29,10 @@ Sometimes, there are workflows that you do not want to run twice at the same tim Therefore, `skip-duplicate-actions` provides the following options to skip a workflow-run if the same workflow is already running: - **Always skip:** This is useful if you have a workflow that you never want to run twice at the same time. - In contrast to the [cancel_others](#cancel-outdated-workflow-runs) option, this option lets the older run finish. + In contrast to the [cancel_others](#cancel-outdated-workflow-runs) option, this option allows older runs to finish. - **Only skip same content:** For example, this can be useful if a workflow has both a `push` and a `pull_request` trigger, or if you push a tag right after pushing a commit. +- **Only skip outdated runs:** For example, this can be useful for skip-checks that are not at the beginning of a job. + In contrast to the [cancel_others](#cancel-outdated-workflow-runs) option, this option skips at pre-defined places instead of cancelling at arbitrary places. - **Never skip:** This disables the concurrent skipping functionality, but still lets you use all other options like duplicate skipping. ## Skip ignored paths @@ -92,7 +94,7 @@ A JSON-array with triggers that should never be skipped. Default `'["workflow_di ### `concurrent_skipping` -One of `never`, `same_content`, `always`. Default `never`. +One of `never`, `same_content`, `outdated_runs`, `always`. Default `never`. ## Outputs diff --git a/action.yml b/action.yml index 8e10b36..94aef1d 100644 --- a/action.yml +++ b/action.yml @@ -26,7 +26,7 @@ inputs: required: false default: '["workflow_dispatch", "schedule"]' concurrent_skipping: - description: 'One of never, same_content, always' + description: 'One of never, same_content, outdated_runs, always' required: true default: 'never' diff --git a/dist/index.js b/dist/index.js index 81b2286..a7f48b4 100644 --- a/dist/index.js +++ b/dist/index.js @@ -9883,6 +9883,7 @@ const micromatch = __webpack_require__(6228); const concurrentSkippingMap = { "always": null, "same_content": null, + "outdated_runs": null, "never": null, }; function getConcurrentSkippingOptions() { @@ -10047,14 +10048,21 @@ function detectConcurrentRuns(context) { core.info(`Skip execution because another instance of the same workflow is already running in ${concurrentRuns[0].html_url}`); exitSuccess({ shouldSkip: true }); } - const concurrentDuplicate = concurrentRuns.find((run) => run.treeHash === context.currentRun.treeHash); - if (concurrentDuplicate) { - core.info(`Skip execution because the exact same files are concurrently checked in ${concurrentDuplicate.html_url}`); - exitSuccess({ shouldSkip: true }); + else if (context.concurrentSkipping === "outdated_runs") { + const newerRun = concurrentRuns.find((run) => new Date(run.createdAt).getTime() > new Date(context.currentRun.createdAt).getTime()); + if (newerRun) { + core.info(`Skip execution because a newer instance of the same workflow is running in ${newerRun.html_url}`); + exitSuccess({ shouldSkip: true }); + } } - else { - core.info(`Did not find any duplicate concurrent workflow-runs`); + else if (context.concurrentSkipping === "same_content") { + const concurrentDuplicate = concurrentRuns.find((run) => run.treeHash === context.currentRun.treeHash); + if (concurrentDuplicate) { + core.info(`Skip execution because the exact same files are concurrently checked in ${concurrentDuplicate.html_url}`); + exitSuccess({ shouldSkip: true }); + } } + core.info(`Did not find any skippable concurrent workflow-runs`); } async function backtracePathSkipping(context) { var _a, _b; diff --git a/src/index.ts b/src/index.ts index bcdd8a5..169a30a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -13,6 +13,7 @@ type WorkflowRunConclusion = 'success' | 'failure' | 'neutral' | 'cancelled' | ' const concurrentSkippingMap = { "always": null, "same_content": null, + "outdated_runs": null, "never": null, } function getConcurrentSkippingOptions(): string[] { @@ -214,14 +215,20 @@ function detectConcurrentRuns(context: WRunContext) { if (context.concurrentSkipping === "always") { core.info(`Skip execution because another instance of the same workflow is already running in ${concurrentRuns[0].html_url}`); exitSuccess({ shouldSkip: true }); + } else if (context.concurrentSkipping === "outdated_runs") { + const newerRun = concurrentRuns.find((run) => new Date(run.createdAt).getTime() > new Date(context.currentRun.createdAt).getTime()); + if (newerRun) { + core.info(`Skip execution because a newer instance of the same workflow is running in ${newerRun.html_url}`); + exitSuccess({ shouldSkip: true }); + } + } else if (context.concurrentSkipping === "same_content") { + const concurrentDuplicate = concurrentRuns.find((run) => run.treeHash === context.currentRun.treeHash); + if (concurrentDuplicate) { + core.info(`Skip execution because the exact same files are concurrently checked in ${concurrentDuplicate.html_url}`); + exitSuccess({ shouldSkip: true }); + } } - const concurrentDuplicate = concurrentRuns.find((run) => run.treeHash === context.currentRun.treeHash); - if (concurrentDuplicate) { - core.info(`Skip execution because the exact same files are concurrently checked in ${concurrentDuplicate.html_url}`); - exitSuccess({ shouldSkip: true }); - } else { - core.info(`Did not find any duplicate concurrent workflow-runs`); - } + core.info(`Did not find any skippable concurrent workflow-runs`); } async function backtracePathSkipping(context: WRunContext) {