Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: fkirc/skip-duplicate-actions
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v5.0.0
Choose a base ref
...
head repository: fkirc/skip-duplicate-actions
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref

Commits on Sep 22, 2022

  1. Copy the full SHA
    0eb36ff View commit details
  2. Allow release for do_not_skip input (#273)

    * Allow 'release' as option for 'do_not_skip' input
    * Small optimizations
      * Use meaningful variable ('file' vs. 'f')
      * Remove unnecessary default values for boolean inputs
      * Directly return commit response (remove 'res' variable)
    paescuj authored Sep 22, 2022
    Copy the full SHA
    b807605 View commit details

Commits on Sep 23, 2022

  1. Copy the full SHA
    ce525f3 View commit details
  2. Copy the full SHA
    aac2bd1 View commit details

Commits on Sep 26, 2022

  1. Add a job summary (#277)

    paescuj authored Sep 26, 2022
    Copy the full SHA
    3d95da3 View commit details
  2. Cleanup README (#278)

    fkirc authored Sep 26, 2022
    Copy the full SHA
    8d7e744 View commit details

Commits on Sep 27, 2022

  1. Copy the full SHA
    ed436fa View commit details

Commits on Oct 1, 2022

  1. Copy the full SHA
    0e85978 View commit details
  2. Copy the full SHA
    ae7e574 View commit details
  3. Copy the full SHA
    f115215 View commit details

Commits on Oct 31, 2022

  1. Copy the full SHA
    116cb9e View commit details

Commits on Nov 1, 2022

  1. Bump @typescript-eslint/eslint-plugin from 5.41.0 to 5.42.0 (#289)

    Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 5.41.0 to 5.42.0.
    - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
    - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
    - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.42.0/packages/eslint-plugin)
    
    ---
    updated-dependencies:
    - dependency-name: "@typescript-eslint/eslint-plugin"
      dependency-type: direct:development
      update-type: version-update:semver-minor
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Nov 1, 2022
    Copy the full SHA
    01cdd04 View commit details
  2. Bump @typescript-eslint/parser from 5.41.0 to 5.42.0 (#291)

    Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 5.41.0 to 5.42.0.
    - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
    - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
    - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.42.0/packages/parser)
    
    ---
    updated-dependencies:
    - dependency-name: "@typescript-eslint/parser"
      dependency-type: direct:development
      update-type: version-update:semver-minor
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Nov 1, 2022
    Copy the full SHA
    2ab7af9 View commit details

Commits on Dec 1, 2022

  1. Bump eslint-plugin-github from 4.4.0 to 4.4.1 (#300)

    Bumps [eslint-plugin-github](https://github.com/github/eslint-plugin-github) from 4.4.0 to 4.4.1.
    - [Release notes](https://github.com/github/eslint-plugin-github/releases)
    - [Commits](github/eslint-plugin-github@v4.4.0...v4.4.1)
    
    ---
    updated-dependencies:
    - dependency-name: eslint-plugin-github
      dependency-type: direct:development
      update-type: version-update:semver-patch
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Dec 1, 2022
    Copy the full SHA
    bf741f0 View commit details
  2. Bump prettier from 2.7.1 to 2.8.0 (#299)

    Bumps [prettier](https://github.com/prettier/prettier) from 2.7.1 to 2.8.0.
    - [Release notes](https://github.com/prettier/prettier/releases)
    - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
    - [Commits](prettier/prettier@2.7.1...2.8.0)
    
    ---
    updated-dependencies:
    - dependency-name: prettier
      dependency-type: direct:development
      update-type: version-update:semver-minor
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Dec 1, 2022
    Copy the full SHA
    b36b9c1 View commit details
  3. Bump @typescript-eslint/parser from 5.42.0 to 5.45.0 (#298)

    Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 5.42.0 to 5.45.0.
    - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
    - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
    - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.45.0/packages/parser)
    
    ---
    updated-dependencies:
    - dependency-name: "@typescript-eslint/parser"
      dependency-type: direct:development
      update-type: version-update:semver-minor
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Dec 1, 2022
    Copy the full SHA
    fb5cfd8 View commit details
  4. Bump @typescript-eslint/eslint-plugin from 5.42.0 to 5.45.0 (#296)

    Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 5.42.0 to 5.45.0.
    - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
    - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
    - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.45.0/packages/eslint-plugin)
    
    ---
    updated-dependencies:
    - dependency-name: "@typescript-eslint/eslint-plugin"
      dependency-type: direct:development
      update-type: version-update:semver-minor
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Dec 1, 2022
    Copy the full SHA
    67e698f View commit details
  5. Bump eslint from 8.26.0 to 8.28.0 (#295)

    Bumps [eslint](https://github.com/eslint/eslint) from 8.26.0 to 8.28.0.
    - [Release notes](https://github.com/eslint/eslint/releases)
    - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
    - [Commits](eslint/eslint@v8.26.0...v8.28.0)
    
    ---
    updated-dependencies:
    - dependency-name: eslint
      dependency-type: direct:development
      update-type: version-update:semver-minor
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Dec 1, 2022
    Copy the full SHA
    39b87d4 View commit details
  6. Bump @types/node from 16.18.3 to 16.18.4 (#297)

    Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 16.18.3 to 16.18.4.
    - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
    - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)
    
    ---
    updated-dependencies:
    - dependency-name: "@types/node"
      dependency-type: direct:development
      update-type: version-update:semver-patch
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Dec 1, 2022
    Copy the full SHA
    48144db View commit details
  7. Bump typescript from 4.8.4 to 4.9.3 (#294)

    Bumps [typescript](https://github.com/Microsoft/TypeScript) from 4.8.4 to 4.9.3.
    - [Release notes](https://github.com/Microsoft/TypeScript/releases)
    - [Commits](microsoft/TypeScript@v4.8.4...v4.9.3)
    
    ---
    updated-dependencies:
    - dependency-name: typescript
      dependency-type: direct:development
      update-type: version-update:semver-minor
    ...
    
    Signed-off-by: dependabot[bot] <support@github.com>
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    dependabot[bot] authored Dec 1, 2022
    Copy the full SHA
    12aca0a View commit details

Commits on Dec 30, 2022

  1. Increase robustness in case of GitHub API failures (#302)

    * Increase robustness in case of GitHub API failures
    
    attempt to mitigate #301
    fkirc authored Dec 30, 2022
    Copy the full SHA
    fc7bbd5 View commit details

Commits on Sep 28, 2023

  1. Copy the full SHA
    c925fb1 View commit details

Commits on Oct 9, 2023

  1. feat: do not skip merge group (#329)

    * feat: do not skip merge gorup
    
    - add `merge_group` as workflow trigger
    - add `merge_group` to default value sfor `do-not-skip` triggers : else, worfklow will be skipped when the PR is added to a merge queue since it just ran before
    
    * chore: compile
    
    ---------
    
    Co-authored-by: Felix K <17876666+fkirc@users.noreply.github.com>
    wahtique and fkirc authored Oct 9, 2023
    Copy the full SHA
    f75f66c View commit details

Commits on Dec 10, 2023

  1. Add paths_filter hint (#336)

    fkirc authored Dec 10, 2023
    Copy the full SHA
    2d93cbd View commit details

Commits on Dec 16, 2023

  1. Update the license (#337)

    fkirc authored Dec 16, 2023
    Copy the full SHA
    f54720a View commit details

Commits on Apr 20, 2024

  1. Fix an example in README.md (#342)

    Only run when both should_skip flags are false
    mhariri authored Apr 20, 2024
    Copy the full SHA
    84931c6 View commit details

Commits on Oct 8, 2024

  1. Copy the full SHA
    04a1aeb View commit details
Showing with 2,687 additions and 649 deletions.
  1. +1 −22 .github/workflows/test.yml
  2. +5 −0 LICENSE
  3. +97 −24 README.md
  4. +6 −2 action.yml
  5. +1,902 −216 dist/index.js
  6. +547 −340 package-lock.json
  7. +13 −13 package.json
  8. +116 −32 src/main.ts
23 changes: 1 addition & 22 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -36,28 +36,7 @@ jobs:
concurrent_skipping: 'never'
skip_after_successful_duplicate: 'true'
paths_ignore: '["**/README.md", "**/docs/**"]'

- name: Print outputs
run: |
echo '::group::should_skip'
echo '${{ steps.skip_check.outputs.should_skip }}'
echo '::endgroup::'
echo '::group::reason'
echo '${{ steps.skip_check.outputs.reason }}'
echo '::endgroup::'
echo '::group::skipped_by'
echo '${{ toJSON(fromJSON(steps.skip_check.outputs.skipped_by)) }}'
echo '::endgroup::'
echo '::group::paths_result'
echo '${{ toJSON(fromJSON(steps.skip_check.outputs.paths_result)) }}'
echo '::endgroup::'
echo '::group::changed_files'
echo '${{ toJSON(fromJSON(steps.skip_check.outputs.changed_files)) }}'
echo '::endgroup::'
skip_summary: 'true'

main_job:
needs: pre_job
5 changes: 5 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
We take a clear stand against imperialistic regimes that are trying to re-build a "Reich".
We seek to defend the rule of law against the rule of tyranny.
We seek to defend democracy against fascism.
Russian users are encouraged to act against the lies that have been used to justify the war.

MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy
121 changes: 97 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
@@ -103,12 +103,12 @@ A YAML-string with named [`paths_ignore`](#paths_ignore) / [`paths`](#paths) pat
```yaml
frontend:
paths_ignore:
- 'frontend/docs/**/*'
- 'frontend/docs/**'
paths:
- 'frontend/**/*'
- 'frontend/**'
backend:
paths:
- 'backend/**/*'
- 'backend/**'
### Here you can optionally control/limit backtracking
# Boolean or number (default: true)
# 'false' means disable backtracking completely
@@ -135,9 +135,9 @@ If true, skip if an already finished duplicate run can be found.

A JSON-array with triggers that should never be skipped.

Possible values are `pull_request`, `push`, `workflow_dispatch`, `schedule`.
Possible values are `pull_request`, `push`, `workflow_dispatch`, `schedule`, `release`, `merge_group`.

**Default:** `'["workflow_dispatch", "schedule"]'`
**Default:** `'["workflow_dispatch", "schedule", "merge_group"]'`

### `concurrent_skipping`

@@ -235,6 +235,7 @@ To minimize changes to existing jobs, it is often easier to skip entire jobs.
>
> - You may need to use [`fromJSON`](https://docs.github.com/en/actions/learn-github-actions/expressions#fromjson) to access properties of object outputs. For example, for `skipped_by.id`, you can use the expression: `${{ fromJSON(steps.skip_check.outputs.skipped_by).id }}`.
> - For GitHub repositories where [default permissions](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository#setting-the-permissions-of-the-github_token-for-your-repository) for `GITHUB_TOKEN` has been set to "permissive (read-only)", the following lines must be included in the workflow (see [permissions syntax](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions)):
>
> ```yaml
> # Minimum permissions required by skip-duplicate-actions
> permissions:
@@ -257,7 +258,7 @@ jobs:
should_skip: ${{ steps.skip_check.outputs.should_skip }}
steps:
- id: skip_check
uses: fkirc/skip-duplicate-actions@v4
uses: fkirc/skip-duplicate-actions@v5
with:
# All of these options are optional, so you can remove them if you are happy with the defaults
concurrent_skipping: 'never'
@@ -267,7 +268,7 @@ jobs:
main_job:
needs: pre_job
if: ${{ needs.pre_job.outputs.should_skip != 'true' }}
if: needs.pre_job.outputs.should_skip != 'true'
runs-on: ubuntu-latest
steps:
- run: echo "Running slow tests..." && sleep 30
@@ -284,18 +285,22 @@ jobs:
runs-on: ubuntu-latest
steps:
- id: skip_check
uses: fkirc/skip-duplicate-actions@v4
uses: fkirc/skip-duplicate-actions@v5
with:
cancel_others: 'false'
paths: '["src/**", "dist/**"]'
- if: ${{ steps.skip_check.outputs.should_skip != 'true' }}
- if: steps.skip_check.outputs.should_skip != 'true'
run: |
echo "Run only if src/ or dist/ changed..." && sleep 30
echo "Do other stuff..."
```

### Example 3: Skip using `paths_filter`

> [!WARNING]
> If the paths_filter option is not working correctly, then you could copy the “example 1" multiple times according to your needs (see <https://github.com/fkirc/skip-duplicate-actions/issues/326> for details).


The `paths_filter` option can be used if you have multiple jobs in a workflow and want to skip them based on different [`paths_ignore`](#paths_ignore) / [`paths`](#paths) patterns. When defining such filters, the action returns corresponding information in the [`paths_result`](#paths_result) output.
For example in a monorepo, you might want to run jobs related to the "frontend" only if some files in the corresponding "frontend/" folder have changed and the same for "backend". This can be achieved with the following configuration:

@@ -308,17 +313,17 @@ jobs:
paths_result: ${{ steps.skip_check.outputs.paths_result }}
steps:
- id: skip_check
uses: fkirc/skip-duplicate-actions@v4
uses: fkirc/skip-duplicate-actions@v5
with:
paths_filter: |
frontend:
paths_ignore:
- 'frontend/docs/**/*'
- 'frontend/docs/**'
paths:
- 'frontend/**/*'
- 'frontend/**'
backend:
paths:
- 'backend/**/*'
- 'backend/**'
# Can be mixed with the "global" 'paths_ignore' / 'paths' options, for example:
# paths_ignore: '["**/README.md"]'
@@ -327,11 +332,11 @@ jobs:
# If 'skip-duplicate-actions' terminates before the paths checks are performed (for example, when a successful duplicate run has
# been found) 'paths_result' outputs an empty object ('{}'). This can be easily intercepted in the if condition of a job
# by checking the result of the "global" 'should_skip' output first.
if: needs.pre_job.outputs.should_skip != 'true' || !fromJSON(needs.pre_job.outputs.paths_result).frontend.should_skip
...
if: needs.pre_job.outputs.should_skip != 'true' && !fromJSON(needs.pre_job.outputs.paths_result).frontend.should_skip
# ...
backend:
...
# ...
```

## How does it work?
@@ -346,25 +351,93 @@ After querying such workflow runs, it will compare them with the current workflo
## How does path-skipping work?

As mentioned above, `skip-duplicate-actions` provides a path-skipping functionality that is somewhat similar to GitHub's native `paths` and `paths_ignore` functionality.
However, path-skipping is not entirely trivial because there exist multiple options on how to do path-skipping.
Depending on your project, you might want to choose one of the following options:
However, path-skipping is not entirely trivial because there exist multiple options on how to do path-skipping:

### Option 1: Only look at the "current" commit

This is the thing that GitHub is currently doing, and I consider it as insufficient because it doesn't work for "required" checks.
Another problem is that the outcomes can be heavily dependent on which commits were pushed at which time, instead of the actual content that was pushed.
This is the thing that GitHub is currently doing, and we consider it as insufficient because it does not work for "required" checks.
Another problem is that the outcomes can be heavily dependent on the pushing-sequence of commits.

### Option 2: Look at Pull-Request-diffs

This option is probably implemented by https://github.com/dorny/paths-filter.
PR-diffs are simple to understand, but not everyone is using PRs for everything, so this is not an option for everyone.
PR-diffs are simple to understand, but they only work after opening a PR, not immediately after pushing a feature-branch.

### Option 3: Look for successful checks of previous commits

This is my personal favorite option and this is implemented by `skip-duplicate-actions`.
An advantage is that this works regardless of whether you are using PRs or feature-branches, and of course it also works for "required" checks.
This option is implemented by `skip-duplicate-actions`.
An advantage is that this works regardless of whether you are using PRs or raw feature-branches, and of course it also works for "required" checks.
Internally, `skip-duplicate-actions` uses the [Repos Commit API](https://docs.github.com/en/rest/reference/repos#get-a-commit) to perform an efficient backtracking-algorithm for paths-skipping-detection.

This is how the algorithm works approximately:

```mermaid
stateDiagram-v2
Check_Commit: Check Commit
[*] --> Check_Commit: Current commit
state Path_Ignored <<choice>>
Check_Commit --> Path_Ignored: Do all changed files match against "paths_ignore"?
Ignored_Yes: Yes
Ignored_No: No
Path_Ignored --> Ignored_Yes
Path_Ignored --> Ignored_No
state Path_Skipped <<choice>>
Ignored_No --> Path_Skipped: Do none of the changed files match against "paths"?
Skipped_Yes: Yes
Skipped_No: No
Path_Skipped --> Skipped_Yes: No matches
Path_Skipped --> Skipped_No: Some matches
Parent_Commit: Fetch Parent Commit
Ignored_Yes --> Parent_Commit
Skipped_Yes --> Parent_Commit
state Successful_Run <<choice>>
Parent_Commit --> Successful_Run: Is there a successful run for this commit?
Run_Yes: Yes
Run_No: No
Successful_Run --> Run_Yes
Successful_Run --> Run_No
Run_No --> Check_Commit: Parent commit
Skip: Skip!
Run_Yes --> Skip: (Because all changes since this run are in ignored or skipped paths)
Dont_Skip: Don't Skip!
Skipped_No --> Dont_Skip: (Because changed files needs to be "tested")
```

## Frequently Asked Questions

### How to Use Skip Check With Required Matrix Jobs?

Discussed in <https://github.com/fkirc/skip-duplicate-actions/issues/44>.

If you have matrix jobs that are registered as required status checks and the matrix runs conditionally based on the skip check, you might run into the problem that the pull request remains in a unmergable state forever because the jobs are not executed at all and thus not reported as skipped (`Expected - Waiting for status to be reported`).

There are several approaches to circumvent this problem:

- Define the condition (`if`) in each step in the matrix job instead of a single condition on the job level: <https://github.com/fkirc/skip-duplicate-actions/issues/44>
- If you want the check to be considered successful only if all jobs in the matrix were successful, you can add a subsequent job whose only task is to report the final status of the matrix. Then you can register this final job as a required status check:

```yaml
result:
name: Result
if: needs.pre_job.outputs.should_skip != 'true' && always()
runs-on: ubuntu-latest
needs:
- pre_job
- example-matrix-job
steps:
- name: Mark result as failed
if: needs.example-matrix-job.result != 'success'
run: exit 1
```

- Define an opposite workflow, as offically suggested by GitHub: [Handling skipped but required checks](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/troubleshooting-required-status-checks#handling-skipped-but-required-checks)

## Maintainers

- [@paescuj](https://github.com/paescuj)
8 changes: 6 additions & 2 deletions action.yml
Original file line number Diff line number Diff line change
@@ -31,11 +31,15 @@ inputs:
do_not_skip:
description: 'A JSON-array with triggers that should never be skipped'
required: false
default: '["workflow_dispatch", "schedule"]'
default: '["workflow_dispatch", "schedule", "merge_group"]'
concurrent_skipping:
description: 'One of never, same_content, same_content_newer, outdated_runs, always'
required: true
default: 'never'
skip_summary:
description: 'If true, make the workflow logs shorter'
required: false
default: 'false'
outputs:
should_skip:
description: 'Returns true if the current run should be skipped according to your configured rules'
@@ -48,5 +52,5 @@ outputs:
paths_result:
description: 'Returns information for each configured filter in paths_filter'
runs:
using: 'node16'
using: 'node20'
main: 'dist/index.js'
Loading