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
{{ message }}
Repository navigation
toolshed: fix copyright-year check to work outside staged-file workflows - #3352
toolshed/check_spdx.py used git diff --staged as a proxy for "was this file changed recently?" That signal is only valid during a git commit. Under pre-commit run --all-files or CI nothing is staged, so the gate short-circuited to return True and the copyright-year check was silently skipped for every file.
Root fix (toolshed/check_spdx.py): Replace is_staged() with last_modified_year(). It returns the current year when git status --porcelain reports any working-tree change (staged, unstaged, or untracked), and otherwise the year of the last commit that touched the file (git log -1). A file passes when its copyright end year is at least that year, so the result is the same under a git commit hook, pre-commit run --all-files, and CI. --fix is unchanged and always writes the current year, because committing the fix is itself a change made this year.
CI: .github/workflows/pre-commit.yml changes fetch-depth from 1 to 0 and adds filter: blob:none, because git log -1 -- <file> needs the full commit history. In a depth-1 clone every file appears to be introduced by the tip commit, so each file would be judged against the tip commit's year and files with older copyright years would fail. blob:none keeps all commits and trees but skips historical file contents, which a path-limited git log does not read; in a local test, a blobless clone returned the same last-change dates as full history without fetching any blobs. The other hooks only read the checked-out tree. An alternative design is to pass only the files changed against a base ref (--from-ref/--to-ref), which avoids the deep fetch but needs the year rule scoped away from --all-files; this PR does not do that. .github/workflows/ci-nightly.yml also installs pathspec for the CI-tools unit tests.
Backfill: Running the corrected check surfaced 20 files that were last committed in 2026 but still carried an earlier copyright end year. They are fixed in the second commit.
Tests: ci/tools/tests/test_check_spdx.py builds temporary git repositories with controlled commit dates and runs the script against them. It covers a file committed this year with a stale copyright (the bug), a file untouched since last year (no false positive), a staged edit checked and then rewritten by --fix, and a clean stale file that --fix rewrites and that is then accepted after the fix is committed. Years are derived from the current year so the tests do not expire. Run with python -m pytest ci/tools/tests/test_check_spdx.py -v --noconftest. Against the previous check_spdx.py, the stale-copyright case and the clean-stale-file case fail; the other two pass on both and guard existing behavior.
Replace is_staged() with last_modified_year(), which consults git status
for working-tree changes and git log -1 for committed files. The old
is_staged() gate used git diff --staged as a proxy for 'was this file
changed recently', which only holds during a git commit. Under
pre-commit run --all-files or CI nothing is staged, so the gate
short-circuited to 'return True' and the year was never checked.
Also change fetch-depth from 1 to 0 in the pre-commit CI workflow.
git log -1 needs enough history to find when each file was last touched;
a depth-1 shallow clone returns empty output for files not changed in the
tip commit, causing silent false passes on stale copyright years.
FixesNVIDIA#2273.
Running check_spdx.py --fix --all-files after the previous commit
updated files last committed in 2026 that still had a 2025 (or earlier)
copyright end year. These were invisible to the hook before because
is_staged() always returned False in the --all-files invocation mode.
--fix wrote the current year even for files whose last change was in an
earlier year, which would re-date untouched files whenever the year
rolled over. Use the same last_modified_year() the check compares
against, and report it in the OUTDATED message.
Add ci/tools/tests/test_check_spdx.py, which builds temporary git
repositories with controlled commit dates and covers committed, staged,
unstaged and untracked files, plus --fix. Install pathspec in the
nightly CI-tools job so the tests run there instead of skipping.
…behavior
Drop cases that exercise the same git-status branch or restate another
test: unstaged and untracked edits, the current-copyright happy path,
copyright-ahead-of-commit, and the stale-relative-to-last-commit case
already pinned by the --fix test. Fold the staged-edit check and the
--fix rewrite of a modified file into one test.
Writing the last-commit year for a clean, stale file is undone by
committing the fix, since that commit is itself a change made this year
(the cycle described in NVIDIA#1514). Revert to writing the current year and
restore the original OUTDATED message.
Replace the last-commit-year test with one that fixes a clean stale file,
commits the result, and checks that it is accepted.
check_spdx.py needs commit history to find when each file last changed.
Correct the comment: in a shallow clone every file appears to be
introduced by the tip commit, so each would be judged against the tip
commit's year (not a false pass, as the comment previously claimed).
Add filter: blob:none so the job fetches all commits and trees but not
historical file contents, which a path-limited git log does not read.
It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.
Updated copyright notices across project materials to include 2026.
Copyright checks now account for each file’s latest changes and include expanded test coverage.
CI setup now pins an additional testing utility and retrieves full commit history while omitting historical file contents.
Tests
Marked a CUDA memory-pool test as thread-unsafe due to a synchronization race.
Other
No application behavior changes are included in this update.
The SPDX checker now uses working-tree changes or the file’s latest commit to determine the year for copyright validation. Tests cover committed and edited files. CI fetches commit history and installs pathspec. Copyright notices were updated across project files.
Changes: SPDX year validation
Layer / File(s)
Summary
Year detection and validation toolshed/check_spdx.py, ci/tools/tests/test_check_spdx.py, .github/workflows/pre-commit.yml, .github/workflows/ci-nightly.yml
The checker uses the current UTC year for files with staged or unstaged changes. Otherwise, it uses the latest commit year, with a current-year fallback. Tests cover committed files, edits, fixes, UTC boundaries, and signed commits. CI fetches full history with blob:none and installs pathspec==0.12.1.
Copyright year updates .github/actions/*, .github/copy-pr-bot.yaml, ci/tools/guess_latest.sh, cuda_core/*, cuda_pathfinder/*
Copyright notices were extended through 2026 where changed. Some notices were replaced with identical text.
CUDA test marker
Layer / File(s)
Summary
Mempool test marker cuda_core/tests/test_memory.py
test_mempool_trim is marked thread-unsafe with a reason identifying a CUDA legacy-default-stream mempool teardown and synchronization race.
Assessment against linked issues
Objective
Addressed
Explanation
[#2273] Detect stale copyright years for files changed outside staged-file workflows.
✅
Out-of-scope changes
Code Change
Explanation
Mark test_mempool_trim as thread-unsafe (cuda_core/tests/test_memory.py:2949)
The linked issue concerns SPDX copyright-year validation and does not state an objective for CUDA test thread-safety markers.
Change: Bug fix
Merge Risk: Low · up to 93b8f
The implementation is broadly mergeable, but one diagnostic can prompt unnecessary edits and the new unstaged-file behavior should receive a focused regression test.
- [ ] Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Tip
🎯 Customize your risk assessments
Guide how CodeRabbit assesses merge risk and security architecture risk. Highlight sensitive changes and explain your security boundaries using Merge Risk Instructions and Security Risk Instructions in your review settings. Security architecture risk assessments require the Advanced plan or above.
✅ Automatic approvals, with your rules
Let CodeRabbit approve pull requests once required threads are resolved, pre-merge checks pass, and your risk limits are met. Enable Automatic approvals in review settings, with overrides for teams or file paths.
Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 9 remain after this review.
Reviewing files that changed from the base of the PR and between 8f6000a and b71d04f.
Files selected for processing: 1
toolshed/check_spdx.py
Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 11 remain after this review.
Reviewing files that changed from the base of the PR and between b71d04f and fcb4484.
Files selected for processing: 1
toolshed/check_spdx.py
Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 10 remain after this review.
— codex GPT-6 on behalf of Ralf —
Read committer timestamps and convert them explicitly to UTC so clean files
use the same year boundary as staged changes. Disable signature display so
signed commits cannot contaminate the timestamp parsed by the checker.
Cover both New Year timezone directions and signed history with regression
tests. All 312 CI-tool tests and the full pre-commit suite pass.
Signed-off-by: Ralf W. Grosse-Kunstleve <rgrossekunst@nvidia.com>
— codex GPT-6 on behalf of Ralf —
Mark only test_mempool_trim thread-unsafe, as proposed in NVIDIAgh-3350. Concurrent
legacy-default-stream pool teardown and context synchronization reproduce a
native driver crash without cuda.core; this test hit that failure twice in
the Windows A100 CI configuration.
Keep all parameter cases and assertions enabled while avoiding the known
concurrent lifecycle. Full pre-commit validation passes.
Signed-off-by: Ralf W. Grosse-Kunstleve <rgrossekunst@nvidia.com>
The reason will be displayed to describe this comment to others. Learn more.
Caution
Some comments are outside the diff and can’t be posted inline due to GitHub limitations.
⚠️ Outside diff range comments (1)
Minor · 🎯 Functional Correctness · check_spdx.py:178-181
toolshed/check_spdx.py:178-181 Minor · Functional Correctness · Quick win
important: Report the year used by validation
For a clean file, validation requires the latest commit year, but the diagnostic always reports CURRENT_YEAR. This can direct users to update the notice beyond the required year. Use the computed validation year and keep --fix writing CURRENT_YEAR.
Suggested fix
- if int(end_year) >= last_modified_year(filepath):+ expected_year = last_modified_year(filepath)+ if int(end_year) >= expected_year:
return True, blob
- print(f"OUTDATED copyright {years!r} (expected {CURRENT_YEAR!r}) in {filepath!r}")+ print(f"OUTDATED copyright {years!r} (expected {str(expected_year)!r}) in {filepath!r}")
The current suite exercises only staged edits and clean committed files. The working-tree branch in toolshed/check_spdx.py:76-82 has no test. A regression that ignored unstaged changes would pass the suite. The uncovered path is the one that the pre-commit run --all-files and CI cases depend on.
Do not add this assertion to test_staged_edit_requires_current_year_and_fix_writes_it. That test stages its edit on purpose. Add a separate test instead:
Suggested fix
# The rewrite is stable: a second run accepts the file.
assert run_checker(repo).returncode == 0
++def test_unstaged_edit_requires_current_year(repo):+ # Working-tree edit with nothing staged: `git status` reports it.+ path = commit(repo, SAMPLE, str(CURRENT_YEAR - 3), year=CURRENT_YEAR - 2)+ path.write_text(path.read_text(encoding="utf-8") + "# edited\n", encoding="utf-8")++ check = run_checker(repo)+ assert check.returncode == 1, check.stdout + check.stderr+ assert f"(expected '{CURRENT_YEAR}')" in check.stdout+
@pytest.mark.agent_authored(model="claude-sonnet-5.5")
def test_fix_of_clean_stale_file_survives_being_committed(repo):
Reviewing files that changed from the base of the PR and between 0f8ff10 and 93b8f25.
Files selected for processing: 1
cuda_core/tests/test_memory.py
Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 11 remain after this review.
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
bugSomething isn't workingCI/CDCI/CD infrastructurecuda.coreEverything related to the cuda.core modulecuda.pathfinderEverything related to the cuda.pathfinder module
2 participants
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.
Description
closes #2273
toolshed/check_spdx.pyusedgit diff --stagedas a proxy for "was this file changed recently?" That signal is only valid during agit commit. Underpre-commit run --all-filesor CI nothing is staged, so the gate short-circuited toreturn Trueand the copyright-year check was silently skipped for every file.Root fix (
toolshed/check_spdx.py): Replaceis_staged()withlast_modified_year(). It returns the current year whengit status --porcelainreports any working-tree change (staged, unstaged, or untracked), and otherwise the year of the last commit that touched the file (git log -1). A file passes when its copyright end year is at least that year, so the result is the same under agit commithook,pre-commit run --all-files, and CI.--fixis unchanged and always writes the current year, because committing the fix is itself a change made this year.CI:
.github/workflows/pre-commit.ymlchangesfetch-depthfrom 1 to 0 and addsfilter: blob:none, becausegit log -1 -- <file>needs the full commit history. In a depth-1 clone every file appears to be introduced by the tip commit, so each file would be judged against the tip commit's year and files with older copyright years would fail.blob:nonekeeps all commits and trees but skips historical file contents, which a path-limitedgit logdoes not read; in a local test, a blobless clone returned the same last-change dates as full history without fetching any blobs. The other hooks only read the checked-out tree. An alternative design is to pass only the files changed against a base ref (--from-ref/--to-ref), which avoids the deep fetch but needs the year rule scoped away from--all-files; this PR does not do that..github/workflows/ci-nightly.ymlalso installspathspecfor the CI-tools unit tests.Backfill: Running the corrected check surfaced 20 files that were last committed in 2026 but still carried an earlier copyright end year. They are fixed in the second commit.
Tests:
ci/tools/tests/test_check_spdx.pybuilds temporary git repositories with controlled commit dates and runs the script against them. It covers a file committed this year with a stale copyright (the bug), a file untouched since last year (no false positive), a staged edit checked and then rewritten by--fix, and a clean stale file that--fixrewrites and that is then accepted after the fix is committed. Years are derived from the current year so the tests do not expire. Run withpython -m pytest ci/tools/tests/test_check_spdx.py -v --noconftest. Against the previouscheck_spdx.py, the stale-copyright case and the clean-stale-file case fail; the other two pass on both and guard existing behavior.Checklist