Skip to content

fix(ci): renormalize docker.yml to LF — and fail CI on CRLF blobs - #141

Merged
MrChengLen merged 1 commit into
mainfrom
pr-docker-yml-lf
Sep 26, 2026
Merged

MrChengLen merged 1 commit into
mainfrom
pr-docker-yml-lf

Conversation

@MrChengLen

@MrChengLen MrChengLen commented Sep 25, 2026 •

Copy link
Copy Markdown
Owner

What

  • .github/workflows/docker.yml back to LF. Stored with CRLF since f72dedc (PR ci(docker): allow a manual rebuild via workflow_dispatch #129), although .gitattributes pins *.yml to LF. No content change: git diff -w against main is empty, and the new blob is the old one with every CRLF replaced by LF (git ls-files --eol now shows i/lf).
  • New guard tests/test_line_endings.py. Reads git ls-files --eol and fails when any tracked file's index blob is CRLF or mixed, unless .gitattributes marks it -text.
  • CHANGELOG entry.

Why

f72dedc was created via createCommitOnBranch, which stores exactly the bytes it is sent, and those bytes had CRLF line endings. The 11-line change already showed as 223 changed lines, and the next ordinary edit would renormalise all 117 lines into another whole-file diff. That's the same class of problem as requirements.lock in 7caa75e (PR #81), repaired in PR #85.

The guard covers every tracked file, not only *.yml/*.py/*.md. * text=auto normalises all text, and the files most at risk are the text=auto ones that a Windows checkout writes as CRLF. It asserts "not CRLF/mixed" rather than "is LF", because i/none is legitimate: the .gitkeep files and the one-line Tailwind bundle have no line endings at all.

Dependabot #131

It bumps two actions in docker.yml on top of the CRLF version. I checked with git merge-tree: it will conflict once this lands, because every line differs on one side. Dependabot rebases conflicted PRs by default, which regenerates the 2-line bump on the LF file, and CI then runs the new guard on it.

Overlap with #146

pr-ci-lockfile-parity renormalises docker.yml too, and deliberately. Its blob is byte-identical to this one (01f23fd), and its real change to the file is empty. So the two PRs don't conflict on docker.yml; whichever merges second simply loses that part of its diff. Its CHANGELOG.md entry will need the usual 3-way merge.

Rebased

Rebased twice, each time because another PR added a CHANGELOG.md entry: onto 4dcd69d (after #143 and #145), then onto 51745d5 (after #148). The only conflict each time was CHANGELOG.md. This entry now sits on top of theirs, and the diff against main is exactly this block. It's still a single commit with the same three files and the same docker.yml blob. All five checks were green on both earlier heads (6c99cbe, ef183de).

Verification

  • New test red against an index built from main (51745d5): it names exactly .github/workflows/docker.yml. Green with this change.
  • Edge cases checked with a synthetic index: a CRLF blob marked -text is exempt, i/mixed is flagged, and an empty w/ column and a non-ASCII path both parse.
  • Full suite on Windows after the rebase: 1231 passed, 63 skipped. The WeasyPrint/pikepdf tests only run here in CI.
  • ruff check + format clean; gitleaks and the pre-commit scope guard clean.
  • security-auditor: PASS. code-reviewer: approve; its docstring and wording fixes are applied.

🤖 Generated with Claude Code

@MrChengLen
MrChengLen enabled auto-merge (squash) September 26, 2026 13:28
docker.yml has been stored with CRLF line endings since f72dedc, although
.gitattributes pins *.yml to LF. That commit went through the GraphQL
createCommitOnBranch API, which stores exactly the bytes it is sent, and the
bytes it was sent had CRLF line endings, so an 11-line change already showed
up as 223 changed lines. GitHub runs the workflow either way, so nothing
failed. The next cost would come with the next edit: its `git add`
renormalises all 117 lines and buries the real change in another whole-file
diff. This commit is that renormalisation and nothing else. `git diff -w`
against main is empty, and the new blob is the old one with every CRLF
replaced by LF.

tests/test_line_endings.py reads `git ls-files --eol` and fails on any
tracked file whose index blob is CRLF or mixed, unless .gitattributes marks
it -text. It covers every tracked file, not only *.yml/*.py/*.md: `* text=auto`
normalises all text, and the files most at risk are the text=auto ones that a
Windows checkout writes as CRLF (requirements.lock was one: 7caa75e in PR #81,
repaired in PR #85). It asserts "not CRLF" rather than "is LF" because i/none
is legitimate for the .gitkeep files and the one-line Tailwind bundle. It
reads the index, not the working tree, so a Windows checkout with autocrlf
stays green. Verified red against an index built from main (it names exactly
.github/workflows/docker.yml) and green with this change.

Dependabot PR #131 bumps two actions in docker.yml on top of the CRLF version,
so it will conflict once this lands. Dependabot rebases conflicted PRs by
default, which regenerates the bump on the LF file.

Full suite 1250 passed, 64 skipped locally on Windows (the WeasyPrint and
pikepdf tests run in CI); ruff check + ruff format clean; gitleaks and the
pre-commit scope guard clean; security-auditor and code-reviewer approve.
i18n drift and pip-audit not applicable: no templates, catalogs or
requirements touched.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MrChengLen
MrChengLen merged commit 9f639ec into main Sep 26, 2026
5 checks passed
@MrChengLen
MrChengLen deleted the pr-docker-yml-lf branch September 26, 2026 13:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant