diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8242e3d1..e5e47255 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -113,8 +113,8 @@ jobs: # THE SAME SUITE ON WINDOWS, because `setup-project.py` exists for a machine # nobody here runs. A SECOND JOB rather than a matrix on the first one: that - # job also installs `git-filter-repo` and downloads a linux-amd64 actionlint - # binary, and neither belongs on a Windows runner. + # job downloads a linux-amd64 actionlint binary, which belongs on no Windows + # runner. tests-windows: runs-on: windows-latest # SKIPPED on a push to main: a squash-interaction regression is not @@ -168,11 +168,18 @@ jobs: - name: install the test runner run: python -m pip install --disable-pip-version-check pytest==8.3.4 - # NO git-filter-repo, on purpose. It is what `adopt-project.py` extracts - # a leg's history with, and the adoption suites SKIP without it — which - # is the honest outcome here: what this job is for is the entry point and - # the materializer on Windows, not a second platform's worth of history - # rewriting. The ubuntu job installs it and runs those tests. + # git-filter-repo IS installed here now, at the ubuntu job's pin (#471). + # It is what `adopt-project.py` extracts a leg's history with, and the + # adoption suites SKIP without it. This job used to leave it out on + # purpose, as a job for the entry point and the materializer alone. But + # v1.0.0 says that adopt works end to end on Windows too, and while no + # Windows runner ever executed an adoption, that sentence was a claim: + # the same claim the macOS job's step below exists to stop making. + # + # ONE LINE: PowerShell is this runner's default shell, and the ubuntu + # job's `\` continuation is bash's, not PowerShell's. + - name: install git-filter-repo + run: python -m pip install --disable-pip-version-check git-filter-repo==2.47.0 # Per-invocation identity, never `git config --global`. PowerShell is the # default shell on this runner, so the append is `>> $env:GITHUB_ENV` @@ -232,7 +239,7 @@ jobs: - name: install the test runner run: python3 -m pip install --disable-pip-version-check pytest==8.3.4 - # git-filter-repo IS installed here, unlike the windows job. The + # git-filter-repo IS installed here, as on the other two runners. The # adoption suites SKIP without it, and `adopt-project.py` is run on a # Mac by whoever adopts a repository from one — a claim that stays a # claim while the only runner that extracts history is Linux. Same pin. diff --git a/tests/test_adopt_clone_template.py b/tests/test_adopt_clone_template.py index aa1c2716..02f373fe 100644 --- a/tests/test_adopt_clone_template.py +++ b/tests/test_adopt_clone_template.py @@ -41,7 +41,7 @@ swapped after the mount. Only the end-to-end tests need `git filter-repo`. The verification tests build -their legs by hand, so the Windows job, which installs none, runs them. Every +their legs by hand, so a machine that has none still runs them. Every repository and remote is local; no network is used, and the operator's configuration reaches git through `GIT_CONFIG_GLOBAL`, a file each test writes, so nothing here reads or writes the global configuration of whoever diff --git a/tests/test_adopt_entry_paths.py b/tests/test_adopt_entry_paths.py index 45298bef..292ecd01 100644 --- a/tests/test_adopt_entry_paths.py +++ b/tests/test_adopt_entry_paths.py @@ -17,8 +17,8 @@ `check` to refuse that answer. NO NETWORK AND NO GITHUB. `git filter-repo` is needed only by the end-to-end -test at the bottom, which skips without it as `test_adopt_e2e.py` does; the -Windows job installs none, so there it is the tests above it that run. They +test at the bottom, which skips without it as `test_adopt_e2e.py` does; on a +machine that has none, it is the tests above it that run. They load `adopt-project.py` through importlib and stub its probe for the tool, as `test_adopt_execute_refusals.py` does: every refusal under test is raised before the tool would be used. diff --git a/tests/test_adopt_ignored_shape_files.py b/tests/test_adopt_ignored_shape_files.py index 10c4381a..b02a89ae 100644 --- a/tests/test_adopt_ignored_shape_files.py +++ b/tests/test_adopt_ignored_shape_files.py @@ -16,8 +16,8 @@ put it, and the check finds a pinned file through the split tree's own links, so it agrees with the first bootstrap. All repositories and remotes are local fixtures; no network is used. The end-to-end tests need `git filter-repo`; the -others do not, so they run on the Windows job, which installs none -- except -the ones that make a symlink on the DISK, which skip there. +others do not, so they run on a machine that has none too. The ones that make +a symlink on the DISK skip on Windows. """ from __future__ import annotations @@ -534,9 +534,24 @@ def test_the_split_lands_the_files_the_pin_names(adopted): cwd=adopted.source).stdout == OWN_ATTRIBUTES +#: KNOWN ON WINDOWS, AND STRICT, for the source with attributes of its own +#: (#471): the shape's `* text=auto eol=lf` lands at `shape/.gitattributes`, +#: where it governs only `shape/`, so a Windows checkout writes CRLF into the +#: pinned copies at the root and the first bootstrap reports shape-copy-drift +#: on every one. Strict, so the fix that appends the shape's rule to the +#: source's own `.gitattributes` turns this red until the mark is removed. +WINDOWS_CRLF_COPIES = pytest.mark.xfail( + sys.platform == "win32", strict=True, + reason="#471: the source's own .gitattributes keeps the shape's eol=lf " + "rule off the root's pinned copies, which a Windows checkout " + "writes with CRLF, so bootstrap reports shape-copy-drift") + + @needs_filter_repo def test_the_assembly_bootstraps_where_it_failed_with_shape_copy_missing( - adopted, tmp_path): + adopted, tmp_path, request): + if adopted.own: + request.applymarker(WINDOWS_CRLF_COPIES) clone = tmp_path / PROJECT git(*FILE_PROTOCOL, "clone", "-q", "--recurse-submodules", "-b", BRANCH, str(adopted.source), str(clone), cwd=tmp_path) diff --git a/tests/test_adopt_mount_ignored.py b/tests/test_adopt_mount_ignored.py index a9751ef3..9d1d93e1 100644 --- a/tests/test_adopt_mount_ignored.py +++ b/tests/test_adopt_mount_ignored.py @@ -31,8 +31,8 @@ what its remediation says of the run, and that its next step adopts. The mount tests call `_mount_the_legs` on hand-made repositories, so they need -no `git filter-repo` and run on the Windows job, which installs none -- except -the two that make a symlink on the DISK, which skip there. The end-to-end +no `git filter-repo` and run on a machine that has none too; the two that +make a symlink on the DISK skip on Windows. The end-to-end tests need `git filter-repo`. All repositories and remotes are local fixtures; no network is used. """ diff --git a/tests/test_adopt_submodules.py b/tests/test_adopt_submodules.py index 8dffb47f..5a519fa6 100644 --- a/tests/test_adopt_submodules.py +++ b/tests/test_adopt_submodules.py @@ -28,7 +28,7 @@ #: What the end-to-end test needs and the mount tests below do not: they call #: `_mount_the_legs` on hand-made repositories, so they run on a machine with -#: no `git filter-repo` (the Windows CI job installs none). +#: no `git filter-repo`. needs_filter_repo = pytest.mark.skipif( shutil.which("git-filter-repo") is None, reason="git filter-repo is not installed: `pip install git-filter-repo`") diff --git a/tests/test_adopt_verify.py b/tests/test_adopt_verify.py index 65725e6e..8821ad1a 100644 --- a/tests/test_adopt_verify.py +++ b/tests/test_adopt_verify.py @@ -12,7 +12,7 @@ EVERY TEST BUT THE LAST TWO CALLS `_verify` DIRECTLY on hand-made commits, their gitlinks written with `git update-index --cacheinfo 160000,...`. No `git -filter-repo` is involved, so the Windows job, which installs none, runs all of +filter-repo` is involved, so a machine that has none still runs all of those. The last two run `execute`, so they need `git filter-repo` and are skipped without it, as every `execute` test is: one proves `cmd_execute` hands `_verify` the PLAN'S mount paths and that the assembly clones and bootstraps diff --git a/tests/test_shape_doctor.py b/tests/test_shape_doctor.py index 154d8af3..1f82976d 100644 --- a/tests/test_shape_doctor.py +++ b/tests/test_shape_doctor.py @@ -1552,11 +1552,12 @@ def no_adoption_offered(text: str = "", rows: dict | None = None, THE `machine` ROW IS THE ONE PLACE THE NAME MAY APPEAR, and it is UNCHANGED by #205 (`machine_row_unchanged`): on a workstation without - `git-filter-repo` -- the Windows CI job, by design -- it says that only - `adopt-project.py` needs that tool, in a COMPLIANT report exactly as - here. That is a sentence about the machine and never an offer to adopt - anything, so the text report is read around that row's one line, and the - row itself may name the tool only while the tool is missing. Everything + `git-filter-repo` -- never a CI runner since #471 installed it on all + three -- it says that only `adopt-project.py` needs that tool, in a + COMPLIANT report exactly as here. That is a sentence about the machine + and never an offer to adopt anything, so the text report is read around + that row's one line, and the row itself may name the tool only while the + tool is missing. Everything else -- the kind line, every reason, every NEXT, every `detail`, the verdict -- names it not at all, `plan` or no `plan`. """