-
Notifications
You must be signed in to change notification settings - Fork 0
[WIP] Add conservative path filters to skip unaffected CI work #993
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
b3c436d
Initial plan
Claude 6227e66
Add conservative path filters to workflow
Claude 7bc75e7
Add aspire.config.json to backend filters and documentation
Claude 78f078d
Pin paths-filter to commit hash and simplify backend path filters
Claude 1dcb98a
Fix copilot review comments on path filters
Claude d0513c7
Merge branch 'main' into claude/phase-5-add-conservative-path-filters
dgee2 f846b37
Move backend under backend directory
dgee2 a8d4882
Update integration tests doc to reference .NET 10 SDK
Claude File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,7 @@ | ||
| { | ||
| "dotnet.defaultSolution": "MenuApi.sln", | ||
| "dotnet.defaultSolution": "backend/MenuApi.sln", | ||
| "sonarlint.connectedMode.project": { | ||
| "connectionId": "dgee2-github", | ||
| "projectKey": "dgee2_Menu" | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,163 @@ | ||
| # CI Path Filters | ||
|
|
||
| ## Overview | ||
|
|
||
| The CI workflow uses conservative path filters to skip unaffected work while ensuring no required validation is missed for cross-stack changes. | ||
|
|
||
| ## Implementation | ||
|
|
||
| The workflow uses the [dorny/paths-filter](https://github.com/dorny/paths-filter) action to detect which files have changed in pull requests and conditionally runs jobs based on those changes. | ||
|
|
||
| ### Path Filter Configuration | ||
|
|
||
| #### Backend Jobs | ||
|
|
||
| Backend jobs (`backend-build`, `backend-tests`, `backend-integration-tests`) run when any of these paths change: | ||
|
|
||
| - `backend/**` - All backend projects, solution files, and backend-specific configuration grouped under the `backend/` directory | ||
| - `.github/workflows/main.yml` - The workflow file itself | ||
|
|
||
| #### Frontend Job | ||
|
|
||
| The frontend job (`frontend`) runs when any of these files change: | ||
|
|
||
| - `ui/**` - Any file in the frontend directory | ||
| - `open-api/**` - OpenAPI specification files (triggers type regeneration) | ||
| - `.github/workflows/main.yml` - The workflow file itself | ||
|
|
||
| ## Behavior by Event Type | ||
|
|
||
| ### Pull Requests | ||
|
|
||
| - **Changes detected**: Only jobs matching the changed files run | ||
| - **No changes detected**: Backend/frontend build and test jobs are skipped when no relevant files change | ||
| - **Workflow file changes**: Both frontend and backend jobs run (conservative approach) | ||
|
|
||
| ### Push Events (main/master branches) | ||
|
|
||
| - **All jobs always run**: Path filters are only applied to pull requests | ||
| - This ensures complete validation on the main branches | ||
|
|
||
| ### Workflow Dispatch | ||
|
|
||
| - **All jobs always run**: Manual triggers run complete validation | ||
|
|
||
| ## Cross-Stack Scenarios | ||
|
|
||
| ### Scenario: Backend-only changes (e.g., only files under `backend/`) | ||
|
|
||
| - ✅ Backend jobs run | ||
| - ❌ Frontend job is skipped | ||
| - The checked-in OpenAPI spec in the repository remains unchanged | ||
|
|
||
| ### Scenario: Frontend-only changes (e.g., only `ui/` files) | ||
|
|
||
| - ❌ Backend jobs are skipped | ||
| - ✅ Frontend job runs | ||
| - The frontend uses the existing OpenAPI spec from the repository | ||
|
|
||
| ### Scenario: OpenAPI contract changes | ||
|
|
||
| - ❌ Backend jobs are skipped (OpenAPI is generated by backend build) | ||
| - ✅ Frontend job runs to regenerate types | ||
| - **Note**: If the OpenAPI spec is out of sync with the backend, both backend and frontend files should be changed together | ||
|
|
||
| ### Scenario: Both backend and frontend changes | ||
|
|
||
| - ✅ Backend jobs run | ||
| - ✅ Frontend job runs | ||
| - Normal full validation | ||
|
|
||
| ### Scenario: Workflow file changes | ||
|
|
||
| - ✅ Backend jobs run | ||
| - ✅ Frontend job runs | ||
| - Conservative approach to ensure workflow changes don't break validation | ||
|
|
||
| ## Frontend Job Dependencies | ||
|
|
||
| The frontend job has special dependency handling: | ||
|
|
||
| ```yaml | ||
| needs: [changes, backend-build] | ||
| if: | | ||
| !cancelled() && | ||
| (github.event_name != 'pull_request' || needs.changes.outputs.frontend == 'true') && | ||
| (needs.backend-build.result == 'success' || needs.backend-build.result == 'skipped') | ||
| ``` | ||
|
|
||
| This allows the frontend to run even when backend-build is skipped (frontend-only changes), while ensuring it waits for backend-build when it does run. | ||
|
|
||
| ### OpenAPI Artifact Handling | ||
|
|
||
| The "Download OpenAPI document" step in the frontend job is conditional: | ||
|
|
||
| ```yaml | ||
| - name: Download OpenAPI document | ||
| if: needs.backend-build.result == 'success' | ||
| uses: actions/download-artifact@v4 | ||
| ``` | ||
|
|
||
| - If backend-build runs and succeeds, the new OpenAPI spec is downloaded | ||
| - If backend-build is skipped, the existing OpenAPI spec from the repository is used | ||
|
|
||
| ## Performance Benefits | ||
|
|
||
| Path filters improve CI throughput by: | ||
|
|
||
| 1. **Reducing build time**: Backend builds (~2-3 minutes) are skipped for frontend-only PRs | ||
| 2. **Reducing test time**: Backend tests (~1-2 minutes) are skipped for frontend-only PRs | ||
| 3. **Reducing runner usage**: Skipped jobs don't consume GitHub Actions runner minutes | ||
|
|
||
| ### Example Savings | ||
|
|
||
| - **Frontend-only PR**: Saves ~5-7 minutes (skips 3 backend jobs) | ||
| - **Backend-only PR**: Saves ~2-3 minutes (skips 1 frontend job) | ||
| - **Documentation-only PR**: Saves ~7-10 minutes (skips all build/test jobs, runs only `changes` and `dependency-review`) | ||
|
|
||
|
dgee2 marked this conversation as resolved.
|
||
| ## Guardrails | ||
|
|
||
| The implementation includes several guardrails to prevent missing validation: | ||
|
|
||
| 1. **Conservative structure**: Backend projects and backend-only config files live under `backend/`, so one path captures solution, project, and analyzer changes together | ||
| 2. **Workflow file triggers both**: Changes to the workflow file trigger all jobs | ||
| 3. **Always run on push**: All jobs run on pushes to main/master branches | ||
| 4. **Dependency review still runs**: The dependency-review job always runs on PRs regardless of changed files | ||
|
|
||
| ## Testing Path Filters | ||
|
|
||
| To test the path filters work correctly: | ||
|
|
||
| 1. Create a PR with only backend changes (e.g., modify a `.cs` file) | ||
| - Verify backend jobs run and frontend job is skipped | ||
|
|
||
| 2. Create a PR with only frontend changes (e.g., modify a `.vue` file) | ||
| - Verify frontend job runs and backend jobs are skipped | ||
|
|
||
| 3. Create a PR with both backend and frontend changes | ||
| - Verify all jobs run | ||
|
|
||
| 4. Create a PR with only documentation changes (e.g., modify a `.md` file) | ||
| - Verify the `changes` job runs, `dependency-review` runs, and backend/frontend jobs are skipped | ||
|
|
||
| ## Troubleshooting | ||
|
|
||
| ### Jobs unexpectedly skipped | ||
|
|
||
| - Check if the changed files match the path patterns | ||
| - Verify the PR is against the correct base branch | ||
| - Check if this is a push event (push events always run all jobs) | ||
|
|
||
| ### Jobs not being skipped | ||
|
|
||
| - Ensure the event is a pull_request (not push) | ||
| - Check if the workflow file was changed (triggers all jobs) | ||
| - Verify the paths-filter action is running correctly in the changes job | ||
|
|
||
| ### Frontend fails because OpenAPI spec is missing | ||
|
|
||
| This can happen if: | ||
| - The backend changed but wasn't included in the PR | ||
| - The OpenAPI spec in the repo is out of sync | ||
|
|
||
| **Solution**: Include both backend and frontend changes in the same PR when the OpenAPI contract changes. | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.