You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: .cursor/rules/llm-development-guidelines.mdc
+31-20Lines changed: 31 additions & 20 deletions
Original file line number
Diff line number
Diff line change
@@ -69,13 +69,13 @@ When you do generate it, use a clear heading such as `### PR description (GitHub
69
69
make test
70
70
```
71
71
**IMPORTANT**: Use the full test suite, not only a single test file, so regressions surface. If anything fails, fix it and **run `make test` again**. **Repeat** until all tests pass.
72
-
7. **Verify 100% diff coverage for GitHub merge** - Every new or changed line in the PR must be executed by tests (CI blocks merge below 100% on the diff). Use coverage output from `make test` and/or:
72
+
7. **Verify 100% diff coverage for GitHub merge** - CI uses `diff-cover` on the PR diff vs the base branch (same as `make test-diff-coverage`). After `git fetch origin`, run:
If the diff is not fully covered, add or extend tests and **return to step 6** until tests pass and the PR diff would satisfy diff coverage.
76
+
For a PR targeting a branch other than `main`, use `make test-diff-coverage COMPARE_BRANCH=origin/<base>`. If this fails, add or extend tests and **return to step 6** until the diff is fully covered. Use `python3 -m pytest --cov=pulp_tool --cov-report=term-missing` only for debugging specific files; the **authoritative local gate** is `make test-diff-coverage`.
77
77
78
-
**Never skip linting, pre-commit (must finish with a fully passing run), or tests (must finish with a fully passing `make test` and diff-ready coverage)** - They will fail in CI/CD and waste pipeline resources.
78
+
**Never skip linting, pre-commit (must finish with a fully passing run), or tests (must finish with a fully passing `make test` and `make test-diff-coverage` before a PR)** - They will fail in CI/CD and waste pipeline resources.
79
79
80
80
## Linting Tools
81
81
@@ -189,6 +189,12 @@ pre-commit run flake8 --all-files
189
189
# Run all tests with coverage (REQUIRED for new changes)
190
190
make test
191
191
192
+
# Same as PR CI: 100% of lines changed vs merge base (run after git fetch origin)
193
+
make test-diff-coverage
194
+
195
+
# Optional: non-main base branch
196
+
make test-diff-coverage COMPARE_BRANCH=origin/my-release-branch
197
+
192
198
# Run tests without coverage (faster, but won't verify coverage)
**IMPORTANT**: New changes require **100% coverage on the PR diff** for GitHub merge. Always run `make test` and confirm your branch would pass diff coverage before opening or updating a PR.
208
+
**IMPORTANT**: New changes require **100% coverage on the PR diff** for GitHub merge. Always run `make test-diff-coverage` (not only `make test`) before opening or updating a PR, after ensuring the compare branch exists locally (`git fetch origin`).
203
209
204
210
### Comprehensive Checks
205
211
206
212
```bash
207
213
# Run all checks (lint + test)
208
214
make check
209
215
210
-
# Run comprehensive check script (lint + test + coverage)
@@ -234,6 +241,7 @@ make format # Fix formatting if needed
234
241
# Loop until pre-commit passes completely:
235
242
pre-commit run --all-files # fix failures → run again → repeat until green
236
243
make test # fix failures / coverage → run again → repeat until green
244
+
make test-diff-coverage # before PR: 100% on git diff vs origin/main (git fetch origin first)
237
245
```
238
246
239
247
### 2. Fix Linting Errors Immediately
@@ -283,21 +291,23 @@ When in doubt, check the configuration files:
283
291
Run tests with coverage until the branch is PR-ready:
284
292
285
293
```bash
286
-
make test # Full test suite with coverage (REQUIRED)
294
+
make test # Full test suite with coverage (REQUIRED)
295
+
make test-diff-coverage # After git fetch origin: 100% on PR diff vs origin/main (REQUIRED before PR)
287
296
```
288
297
289
-
Review the coverage report for **lines that belong to your PR diff**. If anything is uncovered or tests fail:
298
+
`make test-diff-coverage` runs `diff-cover` on `coverage.xml` and lists **only uncovered lines that are part of the git diff**—the same signal as GitHub PR CI. If anything is uncovered or tests fail:
290
299
291
300
1. Fix tests or implementation, add tests for uncovered paths (edge cases, branches, errors)
292
-
2. Re-run `make test` until **all tests pass** and **100% of the diff** is covered (GitHub merge gate).
301
+
2. Re-run `make test` then `make test-diff-coverage` until both pass.
293
302
294
303
Treat “green once” as insufficient if a later fix breaks coverage—re-run the full suite after each substantive change.
295
304
296
305
### 7. Use Scripts for Comprehensive Checks
297
306
298
-
The `scripts/check-all.sh` script runs all checks including tests:
307
+
The `scripts/check-all.sh` script runs linters, tests (with `coverage.xml`), and—when `diff-cover` is installed and `origin/main` (or `DIFF_COVER_COMPARE_BRANCH`) exists—checks PR-style diff coverage at 100%:
299
308
300
309
```bash
310
+
git fetch origin # recommended so diff-cover can compare
301
311
./scripts/check-all.sh
302
312
```
303
313
@@ -360,13 +370,12 @@ Example addition under `[Unreleased]`:
360
370
361
371
**Solution**: The **merge gate is 100% coverage on the PR diff**. Ensure every new or changed line in the branch is executed by tests:
362
372
363
-
1. Run `make test` to see coverage report
364
-
2. Identify uncovered lines in your changes (match them to the diff GitHub/CI reports)
365
-
3. Write tests for all uncovered code paths
366
-
4. Include edge cases, error conditions, and all branches
367
-
5. Re-run `make test` until all tests pass **and** diff coverage is 100% on your changes
373
+
1. Run `git fetch origin` (or your PR base remote ref) so the compare branch exists
374
+
2. Run `make test-diff-coverage`; it prints only **diff** uncovered lines (same tool as CI)
375
+
3. Write tests for all uncovered code paths (edge cases, errors, branches)
376
+
4. Re-run `make test` then `make test-diff-coverage` until both pass
368
377
369
-
The CI/CD pipeline uses `diff-cover` (or equivalent) to check only new/changed lines against the merge base; **anything short of 100% on that diff blocks merging the PR in GitHub.** Keep extending tests and re-running `make test` until that bar is met.
378
+
The CI/CD pipeline uses `diff-cover` against the merge base; **anything short of 100% on that diff blocks merging the PR in GitHub.**
370
379
371
380
## References
372
381
@@ -385,14 +394,16 @@ The CI/CD pipeline uses `diff-cover` (or equivalent) to check only new/changed l
385
394
1. ✅ Run `make lint` to check for linting errors
386
395
2. ✅ Run `make format` to ensure proper formatting
387
396
3. ✅ Run `pre-commit run --all-files` and **repeat** (fix → re-run) until **all hooks pass**
388
-
4. ✅ Run `make test` (full suite) and **repeat** (fix → re-run) until **all tests pass** and **100% diff coverage** is satisfied for GitHub merge
389
-
5. ✅ If there are substantive edits that could ship as a PR, **ask whether the user wants PR materials**; **only after they confirm**, draft the paste-ready GitHub PR description **and** update `CHANGELOG.md` when required (same turn)—see **GitHub PR description (ask first; generate on confirmation)** and **Update CHANGELOG.md when drafting the PR**
397
+
4. ✅ Run `make test` (full suite) and **repeat** (fix → re-run) until **all tests pass**
398
+
5. ✅ Run `make test-diff-coverage` after `git fetch origin` and **repeat** (fix → re-run) until **100% diff coverage** passes (same gate as PR CI)
399
+
6. ✅ If there are substantive edits that could ship as a PR, **ask whether the user wants PR materials**; **only after they confirm**, draft the paste-ready GitHub PR description **and** update `CHANGELOG.md` when required (same turn)—see **GitHub PR description (ask first; generate on confirmation)** and **Update CHANGELOG.md when drafting the PR**
390
400
391
401
**Critical Requirements**:
392
402
- **Pre-commit must end clean** - Run `pre-commit run --all-files` in a loop until zero failures; do not stop after one failed run without a subsequent fully passing run
393
-
- **Tests must end green with diff coverage** - Run `make test` in a loop until the suite passes and new/changed lines are covered for the PR diff
394
-
- **100% diff coverage for GitHub merge** - CI enforces this; extend tests and re-run until the diff is fully covered
403
+
- **Tests must end green** - Run `make test` in a loop until the suite passes
404
+
- **100% diff coverage before a PR** - Run `make test-diff-coverage` (compare branch defaults to `origin/main`); CI enforces the same; extend tests and re-run until the diff is fully covered
395
405
- **Ask before PR text** - End with a short question about drafting the GitHub PR; provide the full paste-ready body only after the user says they are ready
396
406
- **`CHANGELOG.md` at PR draft time only** - Do not touch the changelog on every iteration; add `[Unreleased]` entries when the user confirms PR drafting (unless they explicitly ask earlier)
407
+
- **`make test-diff-coverage`** - Treat as required before declaring a branch PR-ready alongside `make test`
397
408
398
409
Following this workflow ensures your changes will pass CI/CD checks and avoids unnecessary pipeline runs.
Copy file name to clipboardExpand all lines: CHANGELOG.md
+5Lines changed: 5 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,6 +8,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8
8
## [Unreleased]
9
9
10
10
### Added
11
+
-`make test-diff-coverage` runs `diff-cover` at 100% vs `COMPARE_BRANCH` (default `origin/main`) after `make test`, matching the PR merge gate; `scripts/check-all.sh` also generates `coverage.xml` and runs `diff-cover` when the tool and compare ref exist (`DIFF_COVER_COMPARE_BRANCH` optional)
12
+
-`upload --target-arch-repo`: `pulp_results.json` includes per-architecture RPM distribution base URLs under `distributions` with keys `rpm_<arch>` (e.g. `rpm_x86_64`); serialized `distributions` uses sorted keys for stable `{name: url}` output, alongside build-scoped entries when those repos exist
13
+
- Upload optionally skips creating logs and SBOM repositories when no log or SBOM uploads are expected; `skip_logs_repo` / `skip_sbom_repo` on `UploadContext` and `PulpHelper.setup_repositories` (defaults preserve creating all repos for programmatic callers who omit the flags)
11
14
-`upload --target-arch-repo`: per-architecture RPM repos/distributions (``{namespace}/{arch}/Packages/...``); logs/SBOM/artifacts stay build-scoped; lazy repo creation at upload; works with `--results-json`, `--signed-by`, and `--overwrite`; with `--signed-by`, same arch repo and `signed_by` is label-only
12
15
-`upload --overwrite`: RPM-only; remove existing RPM package units in the target repo that match local file SHA256 (and `signed_by` when set) via `remove_content_units` before upload
13
16
-`upload --results-json`: Upload artifacts from pulp_results.json; files resolved from JSON directory or --files-base-path; --build-id and --namespace optional (extracted from artifact labels)
@@ -21,6 +24,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
21
24
- Username/password (Basic Auth) support for packages.redhat.com
22
25
23
26
### Changed
27
+
-`upload --target-arch-repo`: `pulp_results.json``distributions` keys for per-arch RPM bases are `rpm_<arch>` instead of bare architecture names (e.g. `rpm_x86_64` not `x86_64`)
28
+
-`upload` / `upload-files`: infer whether log and SBOM repos are needed before repository setup (directory `*.log` scan or `--results-json` artifact keys; SBOM via `--sbom-path` or SBOM-classified keys); omitted types are excluded from results `distributions`; clear errors if uploads are attempted without the matching repository
24
29
- Upload orchestration uses `RpmUploadResult` per architecture instead of ad-hoc dicts; gather/collect uses `PulpContentRow`, `ExtraArtifactRef`, and `FileInfoMap` for clearer typed data flow
25
30
- Upload flow populates `pulp_results.json` artifact entries incrementally as RPMs, logs, SBOMs, and generic files finish; final gather still reconciles via merge (keeps incremental entries when keys already exist)
26
31
- Repository setup logs use the concrete repo slug (e.g. ``rpms-signed``) instead of a generic ``Rpms`` label; distribution creation logs state that ``name`` and ``base_path`` match the repository name on one line
- Overall test coverage must remain at or above 85%
132
137
- New and changed lines must have 100% coverage (enforced in CI via diff coverage)
138
+
-**Before opening or updating a PR**, run `make test-diff-coverage` after `git fetch origin` so your local report matches the merge gate (`diff-cover` vs `origin/main` by default). Use `make test-diff-coverage COMPARE_BRANCH=origin/<base>` if the PR targets another branch.
133
139
- Tests should be fast and isolated
134
140
- Use fixtures from `tests/conftest.py` when possible
1.**Update CHANGELOG.md**: Add an entry describing your changes
167
173
2.**Update documentation**: If adding features, update README.md as needed
168
174
3.**Run all checks**: Ensure `make check` passes (or run `make lint`, then `pre-commit run --all-files` twice, then `make test`)
169
-
4.**Write tests**: Add tests for new functionality (new/changed code requires 100% diff coverage)
170
-
5.**Update type hints**: Ensure all functions have proper type annotations
175
+
4.**Verify PR diff coverage**: Run `make test-diff-coverage` (requires `git fetch origin` so `origin/main` or your `COMPARE_BRANCH` exists); CI fails below 100% on the diff
176
+
5.**Write tests**: Add tests for new functionality (new/changed code requires 100% diff coverage)
177
+
6.**Update type hints**: Ensure all functions have proper type annotations
171
178
172
179
### PR Checklist
173
180
174
181
-[ ] Code follows the project's style guidelines
175
182
-[ ] All tests pass (`make test`)
183
+
-[ ] PR diff coverage is 100% (`make test-diff-coverage` after `git fetch origin`)
176
184
-[ ] All linters pass (`make lint`)
177
185
-[ ] Pre-commit hooks pass (`pre-commit run --all-files`, run twice after fixing issues)
178
186
-[ ] Test coverage is maintained or improved (85%+ overall, 100% for new/changed lines)
**Overwrite:** When `--overwrite` is set, for each RPM about to be uploaded the tool searches Pulp by the file’s SHA256 (same mechanism as `search-by` checksum mode), keeps only matches that exist in the target RPM repository’s latest version, then calls the repository modify API with `remove_content_units` before uploading and adding the new RPMs. Use with `--signed-by` to scope the search to signed packages.
141
141
142
-
**Target-arch-repo:** When `--target-arch-repo` is set, RPM repositories and distributions are named by architecture only (`{arch}`), including when `--signed-by` is set (no separate `rpms-signed` path). Published paths look like `…/pulp-content/{namespace}/{arch}/`. The aggregate `{build}/rpms` repo is not created; RPM repos are created when each arch is uploaded. Results JSON uses each artifact’s `arch` label to build RPM URLs. Logs, SBOM, and generic artifacts still use `{build}/logs`, `{build}/sbom`, and `{build}/artifacts`.
142
+
**Target-arch-repo:** When `--target-arch-repo` is set, RPM repositories and distributions are named by architecture only (`{arch}`), including when `--signed-by` is set (no separate `rpms-signed` path). Published paths look like `…/pulp-content/{namespace}/{arch}/`. The aggregate `{build}/rpms` repo is not created; RPM repos are created when each arch is uploaded. `pulp_results.json``distributions` maps string names to base URLs (sorted keys when serialized); per-arch RPM bases use keys `rpm_<arch>` (e.g. `rpm_x86_64`). Logs, SBOM, and generic artifacts still use `{build}/logs`, `{build}/sbom`, and `{build}/artifacts`.
make install-dev # Install with dev deps + pre-commit
294
+
make install-dev # Install with dev deps + pre-commit (includes diff-cover)
295
295
make test# Run tests with coverage (85%+ required)
296
+
make test-diff-coverage # After git fetch origin: 100% coverage on git diff vs origin/main (PR CI gate)
296
297
make lint # Black, flake8, pylint, mypy
297
298
make format # Format with Black
298
299
make check # Lint + test
299
300
```
300
301
301
-
Before committing: `pre-commit run --all-files` (run twice after fixes). See [CONTRIBUTING.md](CONTRIBUTING.md).
302
+
Before committing: `pre-commit run --all-files` (run twice after fixes). Before a PR: `git fetch origin` and `make test-diff-coverage`. See [CONTRIBUTING.md](CONTRIBUTING.md).
302
303
303
304
## Troubleshooting
304
305
@@ -314,7 +315,7 @@ Before committing: `pre-commit run --all-files` (run twice after fixes). See [CO
314
315
1. Fork the repository
315
316
2. Create a feature branch
316
317
3. Make changes and add tests
317
-
4. Run `make test` and `pre-commit run --all-files`
318
+
4. Run `make test`, `make test-diff-coverage` (after `git fetch origin`), and `pre-commit run --all-files`
0 commit comments