🙅

GitHub Actions でも [skip ci] が使えるようになりました

2021/02/09に公開

公式ブログ

GitHub Actions: Skip pull request and push workflows with [skip ci] - GitHub Changelog

コミットメッセージの内容から pushpull_request のワークフローをスキップできるようになりました。

push または pull request (PR) の HEAD コミットに [skip ci], [ci skip], [no ci], [skip actions], [actions skip] のいずれかが含まれる場合にワークフローがスキップされます。

検証

[skip ci] を例に検証します。

1. スキップする単一コミット

ワークフローを作成。検証用のためトリガーは paths で絞ってあります。
[skip ci] というコミットメッセージで skip ブランチへコミット。
push, pull_request いずれのタイミングでも CI は走りませんでした。

.github/workflows/skip.yml
name: Skip CI

on:
  push:
    paths: 
      - .github/workflows/skip.yml
  pull_request:
    types:
      - opened
      - synchronize
    paths: 
      - .github/workflows/skip.yml

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - run: 'echo hello'

2. スキップしない単一コミット

上記のファイルを編集して通常通りコミット。
pushpull_request.synchronize の CI が走りました。

3. HEAD 以外でスキップする複数コミット

1つ目のコミットを [skip ci] でコミット。
2つ目のコミット (HEAD) を通常通りコミット。
これをまとめてプッシュすると push, pull_request.synchronize の CI が走りました。
HEAD 以外のメッセージは無視されるようですね。

4. HEAD でスキップする複数コミット

1つ目のコミットを通常通りコミット。
2つ目のコミット (HEAD) を [skip ci] でコミット。
これをまとめてプッシュすると push, pull_request のいずれも CI が走りませんでした。

3. をスキップする

他の CI サービスでは 3. のケースでもスキップできるようなので GitHub Actions でのやり方です。
jobs.<job_id>.if を利用します。
push ではワークフロー自体は走りますがジョブはスキップされます。
pull_request はペイロードが異なるのでワークフローが走ります。

.github/workflows/skip.yml
jobs:
  build:
    runs-on: ubuntu-latest
    if: ${{ !contains(github.event.commits.*.message, '[skip ci]') }}

補足: if

if 条件の中で式を使用する際には、式構文 (${{ }})を省略できますが、 ! は YAML の構文として解釈されパースエラーになってしまうので省略できません。
省略したい場合は以下のように書くこともできます。

if: contains(github.event.commits.*.message, '[skip ci]') == false

補足: contains

contains 関数は配列と文字列の両方に使うことができます。

配列の使用例
contains(github.event.issue.labels.*.name, 'bug')

文字列の使用例
contains('Hello world', 'llo')

PR の情報でスキップする

pull_request ではワークフロー自体は走りますがジョブはスキップされます。
push はペイロードが異なるのでワークフローが走ります。

タイトル

タイトルに [skip ci] を含めます。

.github/workflows/skip.yml
jobs:
  build:
    runs-on: ubuntu-latest
    if: ${{ !contains(github.event.pull_request.title, '[skip ci]') }}

本文

本文に [skip ci] を含めます。

.github/workflows/skip.yml
jobs:
  build:
    runs-on: ubuntu-latest
    if: ${{ !contains(github.event.pull_request.body, '[skip ci]') }}

ラベル

skip ci というラベルを作って PR に付けます。

.github/workflows/skip.yml
jobs:
  build:
    runs-on: ubuntu-latest
    if: ${{ !contains(github.event.pull_request.labels.*.name, 'skip ci') }}

Draft

PR が Draft のとき。

.github/workflows/skip.yml
jobs:
  build:
    runs-on: ubuntu-latest
    if: ${{ !github.event.pull_request.draft }}

まとめ

基本的にはトリガーで各イベントの typespaths で絞り、公式提供されるようになった [skip ci] に加えて ifWIP などをスキップしておくと捗りそうです。

Discussion