ci-skip icon indicating copy to clipboard operation
ci-skip copied to clipboard

GitHub Actions to skip build execution based on commit message

= CI SKIP

GitHub Actions to skip build execution based on commit message.

IMPORTANT: Since 8th February 2021 GitHub Actions https://github.blog/changelog/2021-02-08-github-actions-skip-pull-request-and-push-workflows-with-skip-ci/[supports skipping workflows] out of the box. This GitHub Action is not needed anymore and will be not developed anymore. This repo is in read only mode.

NOTE: Thank you for using and support! Implemented issue: https://github.com/actions/runner/issues/774[#774].

Sometimes there is a need to skip build on Continuous Integration (CI) server (GitHub Actions in this case), e.g. to avoid many releases after several merges to master/main branch. This is standard functionality well known in other CI systems, but missed in GitHub Actions. That's why this is needed.

If the commit message (or a merge message) contains [ci skip] (in subject of body) the action will stop.

== Use cases

=== Simple fail fast

The simplest use case is to fail job fast after evaluating action.

.Fail fast example [source,yaml]

on: [push]

jobs: hello_world_job: runs-on: ubuntu-latest name: Build steps: - uses: actions/checkout@v2 with: # The git history is needed for good evaluation of Pull Request commit messages. # By default this action checkout only last commit. # For PR it's temporary merge commit to current master and orginal commit message is missing. # For big projects can be set to 1000 for performance reasons. fetch-depth: '0' - uses: mstachniuk/ci-skip@v1 with: fail-fast: true - name: Verification run: | echo "The previous step should exiting with 42 code and this code should not run"

The action will immediately exit before Validation step returning exit code 42. You can customize this exit code:

.Fail fast with custom exit code example [source,yaml]

[...] - uses: mstachniuk/ci-skip@v1 with: fail-fast: true exit-code: 22 [...]

Now step will immediately exit with exit code 22. If you don't like it, try fail-safe.

=== Fail safe

This is default behaviour. Remember to check in each next step the env.CI_SKIP or env.CI_SKIP_NOT value in if.

.Fail safe example (from: link:.github/workflows/fail-safe-should-success.yaml[.github/workflows/fail-safe-should-success.yaml]) [source,yaml]

on: [push]

jobs: hello_world_job: runs-on: ubuntu-latest name: Should success steps: - uses: actions/checkout@v2 with: fetch-depth: '0' - uses: mstachniuk/ci-skip@v1 - name: Check if expression CI_SKIP # Remember to check condition in each step if: ${{ env.CI_SKIP == 'false' }} run: | echo "This step should not be executed when commit message contains [ci skip]" - name: Check if expression CI_SKIP_NOT # Remember to check condition in each step if: ${{ env.CI_SKIP_NOT == 'true' }} run: | echo "This step should not be executed when commit message contains [ci skip]"

In this approach the build will success when commit message contains [ci skip].

=== Change commit filter

If you like to use another marker than [ci skip] for skipping CI build then use commit-filter input.

.Change commit filter example (from: link:.github/workflows/fail-safe-commit-filter-should-success.yaml[.github/workflows/fail-safe-commit-filter-should-success.yaml]) [source,yaml]

[...] - uses: mstachniuk/ci-skip@v1 with: commit-filter: 'banana banana' [...]

In this case when commit message contains banana banana then action will be skipped.

=== Multiple filters

If you want to use multiple filters at once, it's possible to separate them with the commit-filter-separator input.

.Multiple commit filers example (from: link:.github/workflows/fail-safe-commit-filter-separator-should-success.yaml[.github/workflows/fail-safe-commit-filter-separator-should-success.yaml]) [source,yaml]

[...] - uses: mstachniuk/ci-skip@v1 with: commit-filter: 'banana;orange' commit-filter-separator: ';' [...]

=== Job to check skip message

It's also possible to create a job dedicated to check skip messages.

.Job to skip example (from: link:fail-safe-check-job-should-success.yaml[fail-safe-check-job-should-success.yaml]) [source,yaml]

[...] jobs: init: runs-on: ubuntu-latest outputs: skip: ${{ steps.ci-skip-step.outputs.ci-skip }} skip-not: ${{ steps.ci-skip-step.outputs.ci-skip-not }} steps: - uses: actions/checkout@v2 with: fetch-depth: 0 - id: ci-skip-step uses: mstachniuk/ci-skip@master

main_job: needs: init if: ${{ needs.init.outputs.skip == 'false' }} [...]

In this example, main_job will be skipped depending on the result of check_skip.

== Google Chrome Extension

If you would decide on merge to skip or not an action the https://github.com/mstachniuk/shipkit-chrome-extension[shipkit-chrome-extension] can be helpful.

== Alternatives

. https://github.com/veggiemonk/skip-commit/issues/5[Just use YAML]: It doesn't work for merge commits. . https://github.com/marketplace/actions/skip-based-on-commit-message[Skip based on commit message]: It's a nice solution, but doesn't work on merge commits and it's not maintained anymore. . https://github.com/styfle/cancel-workflow-action[Cancel Workflow Action]: It can cancel jobs with a status of queued or in_progress.