From 99a04b22dd843907c5f5cf9d3469cdd69b0180fc Mon Sep 17 00:00:00 2001 From: nstarman Date: Tue, 15 Sep 2026 11:17:50 -0400 Subject: [PATCH 1/7] fix(ci): skip no-commit-to-branch in the full-suite CI run no-commit-to-branch was blocking every push to main: CI checks out a real local branch literally named `main` for push events, so the hook always fired. It's a client-side guard for a human running `git commit`/`git push` locally (or via installed git hooks) -- not something a full "run every hook" CI invocation should re-evaluate after the fact. Skips it there via SKIP=no-commit-to-branch; the hook itself is untouched and still fully active locally. Co-Authored-By: Claude Sonnet 5 --- noxfile.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/noxfile.py b/noxfile.py index 9a35d81..0438ca8 100644 --- a/noxfile.py +++ b/noxfile.py @@ -30,7 +30,10 @@ def lint(s: nox.Session, /) -> None: @session(uv_groups=["lint"], reuse_venv=True) def precommit(s: nox.Session, /) -> None: """Run prek.""" - s.run("prek", "run", "--all-files", *s.posargs) + # no-commit-to-branch always fails here: CI checks out the real + # `main` branch on every push, which is exactly what the hook exists to + # block for a human running `git commit`/`git push` locally. + s.run("prek", "run", "--all-files", *s.posargs, env={"SKIP": "no-commit-to-branch"}) @session(uv_groups=["lint"], reuse_venv=True) From c7a1b73ecb6d80e593546257ca180ae70a3bfedb Mon Sep 17 00:00:00 2001 From: nstarman Date: Tue, 15 Sep 2026 11:40:25 -0400 Subject: [PATCH 2/7] fix(ci): don't clobber an existing SKIP when skipping no-commit-to-branch Appends no-commit-to-branch to any SKIP a developer already has set (e.g. via their shell) rather than overwriting it wholesale, matching the same fix applied in response to Copilot review feedback on GalacticDynamics/coordinax#885. Co-Authored-By: Claude Sonnet 5 --- noxfile.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/noxfile.py b/noxfile.py index 0438ca8..f01d309 100644 --- a/noxfile.py +++ b/noxfile.py @@ -4,6 +4,7 @@ # /// """Nox setup.""" +import os import shutil from pathlib import Path @@ -32,8 +33,10 @@ def precommit(s: nox.Session, /) -> None: """Run prek.""" # no-commit-to-branch always fails here: CI checks out the real # `main` branch on every push, which is exactly what the hook exists to - # block for a human running `git commit`/`git push` locally. - s.run("prek", "run", "--all-files", *s.posargs, env={"SKIP": "no-commit-to-branch"}) + # block for a human running `git commit`/`git push` locally. Add it to + # any SKIP a caller already set, rather than clobbering it. + skip = ",".join(filter(None, [os.environ.get("SKIP"), "no-commit-to-branch"])) + s.run("prek", "run", "--all-files", *s.posargs, env={"SKIP": skip}) @session(uv_groups=["lint"], reuse_venv=True) From 6cef4c1d7c557e345844ee7d1a77f7ef7643ac9a Mon Sep 17 00:00:00 2001 From: nstarman Date: Tue, 15 Sep 2026 12:30:00 -0400 Subject: [PATCH 3/7] docs(nox): clarify the no-commit-to-branch skip isn't CI-specific Addresses Copilot review feedback on GalacticDynamics/galax#847: the comment said "CI checks out the real main branch," but the skip applies unconditionally, including local `nox -s lint` runs -- which is correct (a CI-only skip would leave the same false failure for any local dev running the full suite while on `main`). Fixes the wording to match the actual, intended behavior instead of narrowing it. Co-Authored-By: Claude Sonnet 5 --- noxfile.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/noxfile.py b/noxfile.py index f01d309..50c37fc 100644 --- a/noxfile.py +++ b/noxfile.py @@ -31,10 +31,12 @@ def lint(s: nox.Session, /) -> None: @session(uv_groups=["lint"], reuse_venv=True) def precommit(s: nox.Session, /) -> None: """Run prek.""" - # no-commit-to-branch always fails here: CI checks out the real - # `main` branch on every push, which is exactly what the hook exists to - # block for a human running `git commit`/`git push` locally. Add it to - # any SKIP a caller already set, rather than clobbering it. + # no-commit-to-branch guards a human's local `git commit`/`git push`, + # not a manual "run every hook over all files" invocation like this + # one -- which CI also runs on every push to `main`, where it would + # otherwise always fail. Skipped here (locally or in CI); the + # installed git hook still catches the real case. Add it to any SKIP + # a caller already set, rather than clobbering it. skip = ",".join(filter(None, [os.environ.get("SKIP"), "no-commit-to-branch"])) s.run("prek", "run", "--all-files", *s.posargs, env={"SKIP": skip}) From 6742e72ca84e1c53a5e69d6f7d4ba7e74b6ec937 Mon Sep 17 00:00:00 2001 From: nstarman Date: Tue, 15 Sep 2026 12:36:59 -0400 Subject: [PATCH 4/7] docs(nox): clarify the precommit session still runs via prek Addresses Copilot review feedback on GalacticDynamics/dataclassish#94: the docstring "Run prek." on a session still named `precommit` could read as though the session itself was renamed. Spells out that it runs the pre-commit hooks, now via prek. Co-Authored-By: Claude Sonnet 5 --- noxfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/noxfile.py b/noxfile.py index 50c37fc..f3e522f 100644 --- a/noxfile.py +++ b/noxfile.py @@ -30,7 +30,7 @@ def lint(s: nox.Session, /) -> None: @session(uv_groups=["lint"], reuse_venv=True) def precommit(s: nox.Session, /) -> None: - """Run prek.""" + """Run the pre-commit hooks (via prek).""" # no-commit-to-branch guards a human's local `git commit`/`git push`, # not a manual "run every hook over all files" invocation like this # one -- which CI also runs on every push to `main`, where it would From 431730e935b926f46fcc487c5d1880290d505248 Mon Sep 17 00:00:00 2001 From: nstarman Date: Tue, 15 Sep 2026 12:41:49 -0400 Subject: [PATCH 5/7] docs(nox): fix now-inaccurate git-push mention in the SKIP comment Addresses Copilot review feedback on GalacticDynamics/galax#847: this comment still said no-commit-to-branch guards `git push`, but the earlier stages: [pre-commit] fix means it no longer runs on push at all. Clarifies that explicitly instead of leaving stale wording. Co-Authored-By: Claude Sonnet 5 --- noxfile.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/noxfile.py b/noxfile.py index f3e522f..dee013c 100644 --- a/noxfile.py +++ b/noxfile.py @@ -31,12 +31,13 @@ def lint(s: nox.Session, /) -> None: @session(uv_groups=["lint"], reuse_venv=True) def precommit(s: nox.Session, /) -> None: """Run the pre-commit hooks (via prek).""" - # no-commit-to-branch guards a human's local `git commit`/`git push`, - # not a manual "run every hook over all files" invocation like this - # one -- which CI also runs on every push to `main`, where it would - # otherwise always fail. Skipped here (locally or in CI); the - # installed git hook still catches the real case. Add it to any SKIP - # a caller already set, rather than clobbering it. + # no-commit-to-branch guards a human's local `git commit` (it's + # scoped to stages: [pre-commit] in .pre-commit-config.yaml, so it + # never runs on push) -- not a manual "run every hook over all files" + # invocation like this one, which CI also runs on every push to + # `main`, where it would otherwise always fail. Skipped here (locally + # or in CI); the installed git hook still catches the real case. Add + # it to any SKIP a caller already set, rather than clobbering it. skip = ",".join(filter(None, [os.environ.get("SKIP"), "no-commit-to-branch"])) s.run("prek", "run", "--all-files", *s.posargs, env={"SKIP": skip}) From 4e14e8d1505a250c5d48f30cc137504f3ec0a062 Mon Sep 17 00:00:00 2001 From: nstarman Date: Tue, 15 Sep 2026 12:55:56 -0400 Subject: [PATCH 6/7] docs: disambiguate "never fires on push" from the workflow's own push trigger Addresses Copilot review feedback on GalacticDynamics/galax#847: "it never fires on push" reads as a claim about this workflow's own `on: push:` trigger (which is false -- that's why the SKIP exists at all), when it actually means the git pre-push hook stage. Spells that out explicitly. Co-Authored-By: Claude Sonnet 5 --- noxfile.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/noxfile.py b/noxfile.py index dee013c..442e827 100644 --- a/noxfile.py +++ b/noxfile.py @@ -33,11 +33,12 @@ def precommit(s: nox.Session, /) -> None: """Run the pre-commit hooks (via prek).""" # no-commit-to-branch guards a human's local `git commit` (it's # scoped to stages: [pre-commit] in .pre-commit-config.yaml, so it - # never runs on push) -- not a manual "run every hook over all files" - # invocation like this one, which CI also runs on every push to - # `main`, where it would otherwise always fail. Skipped here (locally - # or in CI); the installed git hook still catches the real case. Add - # it to any SKIP a caller already set, rather than clobbering it. + # never fires as a pre-push git hook) -- not a manual "run every + # hook over all files" invocation like this one, which CI also runs + # on every push to `main`, where it would otherwise always fail. + # Skipped here (locally or in CI); the installed git hook still + # catches the real case. Add it to any SKIP a caller already set, + # rather than clobbering it. skip = ",".join(filter(None, [os.environ.get("SKIP"), "no-commit-to-branch"])) s.run("prek", "run", "--all-files", *s.posargs, env={"SKIP": skip}) From bb88425d1459aab4eb23d1686d06153ff818bf30 Mon Sep 17 00:00:00 2001 From: nstarman Date: Tue, 15 Sep 2026 13:53:25 -0400 Subject: [PATCH 7/7] docs: trim verbose inline comments down to the load-bearing WHY The archaeology (why pre-commit's nodeenv/pyyaml floors mattered, why --skip clobbers, the full CI-checkout explanation) belongs in commit history, not permanently inline. Keeps just enough to orient a future reader without re-litigating the whole investigation. Co-Authored-By: Claude Sonnet 5 --- noxfile.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/noxfile.py b/noxfile.py index 442e827..9edfc43 100644 --- a/noxfile.py +++ b/noxfile.py @@ -31,14 +31,8 @@ def lint(s: nox.Session, /) -> None: @session(uv_groups=["lint"], reuse_venv=True) def precommit(s: nox.Session, /) -> None: """Run the pre-commit hooks (via prek).""" - # no-commit-to-branch guards a human's local `git commit` (it's - # scoped to stages: [pre-commit] in .pre-commit-config.yaml, so it - # never fires as a pre-push git hook) -- not a manual "run every - # hook over all files" invocation like this one, which CI also runs - # on every push to `main`, where it would otherwise always fail. - # Skipped here (locally or in CI); the installed git hook still - # catches the real case. Add it to any SKIP a caller already set, - # rather than clobbering it. + # Not a real commit -- no-commit-to-branch would always fail here. + # Merge into any SKIP already set, rather than clobber it. skip = ",".join(filter(None, [os.environ.get("SKIP"), "no-commit-to-branch"])) s.run("prek", "run", "--all-files", *s.posargs, env={"SKIP": skip})