Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 129 additions & 0 deletions .codex/prompts/setup-recommended-ci.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,135 @@ jobs:
run: npm run build
```

### CI最適化: Path Filters による実行最適化

**目的**: 変更されたファイルに応じて必要なジョブのみを実行することで、CIの実行時間を短縮し、コストを削減します。

#### 実装方法

GitHub Actionsの`on.push.paths`と`on.pull_request.paths`フィルター、および`dorny/paths-filter`アクションを組み合わせて使用します。

##### 1. ワークフローレベルでのフィルタリング

ワークフロー全体をスキップするには、`on`セクションで`paths`を指定します:

```yaml
on:
pull_request:
paths:
- '**.js'
- '**.ts'
- '**.mjs'
- '**.cjs'
- '**.json'
- '**.sh'
- '**.bats'
- '.github/workflows/**'
- 'package.json'
- 'package-lock.json'
- '.eslintrc.*'
- '.prettierrc.*'
- 'tsconfig.json'
push:
branches: [main, master]
paths:
- '**.js'
- '**.ts'
# ... 同様のパターン
```

##### 2. ジョブレベルでの細かい制御

各ジョブを変更内容に応じて実行するには、`dorny/paths-filter`を使用します:

```yaml
jobs:
changes:
name: Detect Changes
runs-on: ubuntu-latest
outputs:
code: ${{ steps.filter.outputs.code }}
scripts: ${{ steps.filter.outputs.scripts }}
workflows: ${{ steps.filter.outputs.workflows }}
dependencies: ${{ steps.filter.outputs.dependencies }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: filter
with:
filters: |
code:
- '**.js'
- '**.ts'
- 'src/**'
- 'test/**/*.test.{js,ts}'
scripts:
- '**.sh'
- 'script/**'
workflows:
- '.github/workflows/**'
dependencies:
- 'package.json'
- 'package-lock.json'

lint:
needs: changes
if: needs.changes.outputs.code == 'true' || needs.changes.outputs.dependencies == 'true'
# ... lintジョブの内容

test:
needs: changes
if: needs.changes.outputs.code == 'true' || needs.changes.outputs.dependencies == 'true'
# ... testジョブの内容

actionlint:
needs: changes
if: needs.changes.outputs.workflows == 'true'
# ... actionlintジョブの内容
```

##### 3. Quality Gate での skipped 状態の処理

ジョブがスキップされた場合も成功として扱うように、Quality Gateを更新します:

```yaml
quality-gate:
needs: [changes, lint, test, integration-test, actionlint]
if: always()
steps:
- name: Verify all checks passed
run: |
function check_result() {
local result=$1
[[ "$result" == "success" || "$result" == "skipped" ]]
}

if ! check_result "${{ needs.lint.result }}"; then
echo "::error::Lint & Format failed"
exit 1
fi
# ... 他のジョブも同様にチェック
```

#### Path Filters のベストプラクティス

| 対象ワークフロー | 推奨フィルター | 理由 |
| ---------------------- | ----------------------------------------------------- | ---------------------------------------- |
| **CI Pipeline** | コード、設定ファイル、ワークフロー自体 | ドキュメントのみの変更でテストをスキップ |
| **Docker Image Build** | `.devcontainer/**`, `npm/global.json`, `package.json` | DevContainer関連の変更時のみビルド |
| **Security Scans** | コード、依存関係ファイル | セキュリティに影響する変更のみスキャン |
| **Documentation** | `**.md`, `docs/**` | ドキュメント変更時のみデプロイ |

#### 効果測定

Path Filtersを導入すると、以下のような効果が期待できます:

- ドキュメントのみの変更: CI実行時間 **90%削減** (10分 → 1分)
- DevContainer変更なし: Docker Image Build **スキップ** (45分 → 0分)
- ワークフローのみの変更: Lint/Test **スキップ**、Actionlintのみ実行

**注意**: mainブランチへのpushでは、すべてのチェックを実行することを推奨します(path filtersを適用しない、または緩めに設定)。

### フル構成版 (Next.js + Supabase プロジェクト向け)

Elu-co-jp リポジトリから参照:
Expand Down
102 changes: 99 additions & 3 deletions .github/workflows/ci.yml

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚫 [actionlint] reported by reviewdog 🐶
avoid using deprecated input "fail_on_error" in action "reviewdog/action-actionlint@v1": Deprecated, use fail_level instead [action]

fail_on_error: true

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [actionlint] reported by reviewdog 🐶
shellcheck reported issue in this script: SC2086:info:1:35: Double quote to prevent globbing and word splitting [shellcheck]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [actionlint] reported by reviewdog 🐶
shellcheck reported issue in this script: SC2086:info:2:12: Double quote to prevent globbing and word splitting [shellcheck]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [actionlint] reported by reviewdog 🐶
shellcheck reported issue in this script: SC2086:info:3:28: Double quote to prevent globbing and word splitting [shellcheck]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [actionlint] reported by reviewdog 🐶
shellcheck reported issue in this script: SC2086:info:4:28: Double quote to prevent globbing and word splitting [shellcheck]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [actionlint] reported by reviewdog 🐶
shellcheck reported issue in this script: SC2086:info:5:44: Double quote to prevent globbing and word splitting [shellcheck]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [actionlint] reported by reviewdog 🐶
shellcheck reported issue in this script: SC2086:info:6:41: Double quote to prevent globbing and word splitting [shellcheck]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [actionlint] reported by reviewdog 🐶
shellcheck reported issue in this script: SC2086:info:7:55: Double quote to prevent globbing and word splitting [shellcheck]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [actionlint] reported by reviewdog 🐶
shellcheck reported issue in this script: SC2086:info:8:50: Double quote to prevent globbing and word splitting [shellcheck]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚫 [actionlint] reported by reviewdog 🐶
shellcheck reported issue in this script: SC2129:style:1:1: Consider using { cmd1; cmd2; } >> file instead of individual redirects [shellcheck]

Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,82 @@ name: CI

on:
pull_request:
paths:
- '**.js'
- '**.ts'
- '**.mjs'
- '**.cjs'
- '**.json'
- '**.sh'
- '**.bats'
- '.github/workflows/**'
- 'package.json'
- 'package-lock.json'
- '.eslintrc.*'
- '.prettierrc.*'
- 'tsconfig.json'
push:
branches: [main, master]
paths:
- '**.js'
- '**.ts'
- '**.mjs'
- '**.cjs'
- '**.json'
- '**.sh'
- '**.bats'
- '.github/workflows/**'
- 'package.json'
- 'package-lock.json'
- '.eslintrc.*'
- '.prettierrc.*'
- 'tsconfig.json'
Comment on lines +5 to +34

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Workflow-level path filters are broader than job-level filters.

The workflow-level paths include patterns like **.json, **.sh, and **.bats that may trigger the workflow even when no jobs will actually run. For example:

  • **.json at workflow level, but job-level only checks specific files (package.json, tsconfig.json)
  • If a JSON file unrelated to dependencies/tsconfig changes, the workflow runs but all jobs skip

This creates unnecessary workflow runs with no actual CI execution.

Consider removing workflow-level path filters

Since you're using job-level filtering with dorny/paths-filter, the workflow-level paths are redundant and can cause mismatches. Remove them entirely and rely solely on job-level filtering:

 on:
   pull_request:
-    paths:
-      - '**.js'
-      - '**.ts'
-      - '**.mjs'
-      - '**.cjs'
-      - '**.json'
-      - '**.sh'
-      - '**.bats'
-      - '.github/workflows/**'
-      - 'package.json'
-      - 'package-lock.json'
-      - '.eslintrc.*'
-      - '.prettierrc.*'
-      - 'tsconfig.json'
   push:
     branches: [main, master]
-    paths:
-      - '**.js'
-      - '**.ts'
-      - '**.mjs'
-      - '**.cjs'
-      - '**.json'
-      - '**.sh'
-      - '**.bats'
-      - '.github/workflows/**'
-      - 'package.json'
-      - 'package-lock.json'
-      - '.eslintrc.*'
-      - '.prettierrc.*'
-      - 'tsconfig.json'

The changes job already runs quickly (5 min timeout) and will cause dependent jobs to skip appropriately. This approach is more maintainable and eliminates filter duplication.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
.github/workflows/ci.yml lines 5-34: The workflow-level paths filter is broader
than the job-level filters and causes unnecessary runs; remove the top-level
paths block (the '**.js', '**.ts', '**.json', '**.sh', '**.bats',
'.github/workflows/**', 'package.json', 'package-lock.json', '.eslintrc.*',
'.prettierrc.*', 'tsconfig.json' entries) so the workflow triggers only on
branches (keep the push/pull_request branch settings) and rely on the existing
job-level dorny/paths-filter checks to decide which jobs run; alternatively, if
you prefer keeping workflow-level filters, narrow them to exactly match the
job-level patterns (e.g., only package.json and tsconfig.json) to avoid
mismatches.


concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
changes:
name: Detect Changes
runs-on: ubuntu-latest
timeout-minutes: 5
outputs:
code: ${{ steps.filter.outputs.code }}
scripts: ${{ steps.filter.outputs.scripts }}
workflows: ${{ steps.filter.outputs.workflows }}
dependencies: ${{ steps.filter.outputs.dependencies }}
steps:
- uses: actions/checkout@v4

- uses: dorny/paths-filter@v3
id: filter
with:
filters: |
code:
- '**.js'
- '**.ts'
- '**.mjs'
- '**.cjs'
- 'src/**'
- 'test/**/*.test.{js,ts}'
- 'tsconfig.json'
scripts:
- '**.sh'
- 'script/**'
- 'test/integration/**'
workflows:
- '.github/workflows/**'
dependencies:
- 'package.json'
- 'package-lock.json'

lint:
name: Lint & Format
runs-on: ubuntu-latest
timeout-minutes: 10
needs: changes
if: needs.changes.outputs.code == 'true' || needs.changes.outputs.scripts == 'true' || needs.changes.outputs.dependencies == 'true'
steps:
- uses: actions/checkout@v4

Expand Down Expand Up @@ -41,6 +105,8 @@ jobs:
name: Unit Tests
runs-on: ubuntu-latest
timeout-minutes: 15
needs: changes
if: needs.changes.outputs.code == 'true' || needs.changes.outputs.dependencies == 'true'
steps:
- uses: actions/checkout@v4

Expand Down Expand Up @@ -87,6 +153,8 @@ jobs:
name: Integration Tests
runs-on: ubuntu-latest
timeout-minutes: 15
needs: changes
if: needs.changes.outputs.scripts == 'true' || needs.changes.outputs.dependencies == 'true'
steps:
- uses: actions/checkout@v4

Expand Down Expand Up @@ -118,6 +186,8 @@ jobs:
name: Workflow Lint
runs-on: ubuntu-latest
timeout-minutes: 5
needs: changes
if: needs.changes.outputs.workflows == 'true'
steps:
- uses: actions/checkout@v4

Expand All @@ -131,7 +201,7 @@ jobs:
name: Quality Gate
runs-on: ubuntu-latest
timeout-minutes: 5
needs: [lint, test, integration-test, actionlint]
needs: [changes, lint, test, integration-test, actionlint]
if: always()
steps:
- name: Check job results
Expand All @@ -154,9 +224,35 @@ jobs:
env:
LINT_RESULT: ${{ needs.lint.result }}
TEST_RESULT: ${{ needs.test.result }}
INTEGRATION_RESULT: ${{ needs.integration-test.result }}
ACTIONLINT_RESULT: ${{ needs.actionlint.result }}
run: |
if [ "$LINT_RESULT" != "success" ] || [ "$TEST_RESULT" != "success" ]; then
echo "::error::Quality gate failed - lint or test jobs did not succeed"
# skipped は成功扱い(該当ファイルの変更がない場合)
function check_result() {
local result=$1
[[ "$result" == "success" || "$result" == "skipped" ]]
}

FAILED=false
if ! check_result "$LINT_RESULT"; then
echo "::error::Lint & Format failed"
FAILED=true
fi
if ! check_result "$TEST_RESULT"; then
echo "::error::Unit Tests failed"
FAILED=true
fi
if ! check_result "$INTEGRATION_RESULT"; then
echo "::error::Integration Tests failed"
FAILED=true
fi
if ! check_result "$ACTIONLINT_RESULT"; then
echo "::error::Workflow Lint failed"
FAILED=true
fi

if [ "$FAILED" = true ]; then
echo "::error::Quality gate failed - one or more jobs did not succeed"
exit 1
fi

Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/docker-image.yml

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [actionlint] reported by reviewdog 🐶
shellcheck reported issue in this script: SC2086:info:30:32: Double quote to prevent globbing and word splitting [shellcheck]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [actionlint] reported by reviewdog 🐶
shellcheck reported issue in this script: SC2086:info:31:37: Double quote to prevent globbing and word splitting [shellcheck]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [actionlint] reported by reviewdog 🐶
shellcheck reported issue in this script: SC2086:info:32:30: Double quote to prevent globbing and word splitting [shellcheck]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚫 [actionlint] reported by reviewdog 🐶
shellcheck reported issue in this script: SC2129:style:30:1: Consider using { cmd1; cmd2; } >> file instead of individual redirects [shellcheck]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [actionlint] reported by reviewdog 🐶
shellcheck reported issue in this script: SC2086:info:10:39: Double quote to prevent globbing and word splitting [shellcheck]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [actionlint] reported by reviewdog 🐶
shellcheck reported issue in this script: SC2086:info:11:32: Double quote to prevent globbing and word splitting [shellcheck]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [actionlint] reported by reviewdog 🐶
shellcheck reported issue in this script: SC2086:info:6:31: Double quote to prevent globbing and word splitting [shellcheck]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [actionlint] reported by reviewdog 🐶
shellcheck reported issue in this script: SC2086:info:9:34: Double quote to prevent globbing and word splitting [shellcheck]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚫 [actionlint] reported by reviewdog 🐶
shellcheck reported issue in this script: SC2129:style:9:3: Consider using { cmd1; cmd2; } >> file instead of individual redirects [shellcheck]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [actionlint] reported by reviewdog 🐶
shellcheck reported issue in this script: SC2086:info:3:50: Double quote to prevent globbing and word splitting [shellcheck]

Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ name: Build and Release DevContainer Image
on:
push:
branches: [main]
paths:
- '.devcontainer/**'
- 'npm/global.json'
- 'package.json'
- 'package-lock.json'
- '.github/workflows/docker-image.yml'
workflow_dispatch:
inputs:
release_mode:
Expand Down
20 changes: 20 additions & 0 deletions .github/workflows/security.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,28 @@ name: Security Scans
on:
push:
branches: [main]
paths:
- '**.js'
- '**.ts'
- '**.mjs'
- '**.cjs'
- '**.sh'
- 'package.json'
- 'package-lock.json'
- 'npm/global.json'
- '.github/workflows/security.yml'
pull_request:
branches: [main]
paths:
- '**.js'
- '**.ts'
- '**.mjs'
- '**.cjs'
- '**.sh'
- 'package.json'
- 'package-lock.json'
- 'npm/global.json'
- '.github/workflows/security.yml'
schedule:
- cron: '0 5 * * *'

Expand Down
Loading
Loading