Skip to content

GitHub Actionsで特定フォルダの変更時のみワークフローを実行する方法

問題

GitHubリポジトリに複数のフォルダがある場合、特定のフォルダ(例:folder1)内のファイルが変更されたときだけGitHub Actionsのワークフローを実行したいというニーズがあります。これにより、不要なワークフローの実行を回避し、CI/CDプロセスを効率化できます。

基本的な解決策

パスフィルターの使用

GitHub Actionsでは、on.push.pathsまたはon.pull_request.pathsを使用して、特定のパターンに一致するファイルが変更されたときのみワークフローをトリガーできます。

yaml
on:
  push:
    paths:
      - 'folder1/**'

この設定により、folder1ディレクトリ内のいずれかのファイルが変更された場合にのみ、ワークフローが実行されます。

パターンの詳細

  • **: 任意の数のディレクトリとサブディレクトリにマッチ
  • *: 任意の数の文字にマッチ(パス区切り文字を除く)
  • ?: 任意の1文字にマッチ(パス区切り文字を除く)

高度な設定例

ブランチとの組み合わせ

特定のブランチでのみパスフィルターを適用する場合:

yaml
on:
  push:
    branches: ['main', 'development']
    paths: ['folder1/**']

複数のイベントタイプに対応

pushとpull_requestの両方でパスフィルターを適用する場合:

yaml
on:
  push:
    paths:
      - 'folder1/**'
  pull_request:
    paths: 
      - 'folder1/**'

除外パターンの使用

特定のパスを除外したい場合は、否定パターン(!プレフィックス)を使用できます。ただし、少なくとも1つの肯定パターンを含める必要があります。

yaml
on:
  push:
    paths:
      - 'sub-project/**'
      - '!sub-project/docs/**'

この例では、sub-projectディレクトリ内の変更でワークフローが実行されますが、sub-project/docsディレクトリの変更は無視されます。

ワークフローファイル自体の変更に対応

ワークフローファイル(通常は.github/workflows/内)が変更された場合もワークフローを実行したい場合は、明示的にパスを追加する必要があります。

yaml
on:
  push:
    paths:
      - 'folder1/**'
      - '.github/workflows/**'

ジョブレベルでのフィルタリング

パスフィルターはワークフロー全体に適用されますが、ジョブごとに条件を設定したい場合は、changed-filesアクションを使用できます。

yaml
jobs:
  my-job:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        
      - name: Get changed files
        id: changed-files
        uses: tj-actions/changed-files@v40
        
      - name: Run if folder1 changed
        if: contains(steps.changed-files.outputs.all_changed_files, 'folder1/')
        run: echo "folder1 was changed!"

注意点

重要

  • pathspaths-ignoreを同じイベントで同時に使用することはできません
  • パターンの評価順序は重要です(上から順に評価されます)
  • 否定パターンだけを使用することはできません(少なくとも1つの肯定パターンが必要)

まとめ

GitHub Actionsのパスフィルター機能を使用することで、特定のディレクトリ内のファイル変更時のみワークフローを実行するように設定できます。これにより、CI/CDプロセスの効率化とリソースの最適化が可能になります。複雑な条件が必要な場合は、サードパーティのアクションを組み合わせることで柔軟な対応ができます。