From 7ea6e098589944c7cefb786a34e6064ad46c0081 Mon Sep 17 00:00:00 2001 From: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com> Date: Tue, 18 Aug 2026 16:12:05 -0700 Subject: [PATCH] ci: guard Windows (smoke job) + fix Windows install (MAX_PATH long paths) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two Windows durability changes, no runtime code touched. 1. Windows install blocker (docs/INSTALL.md). This repo ships SWE-bench eval fixtures under .amplifier/evaluation/tasks/swe-bench-pro/instances/ instance___-<40charsha>-v<40charsha>/meta.yaml -- the longest tracked path is 178 chars. `uv tool install --from git+...` clones the repo into a deep temp build dir, so those paths exceed Windows' 260-char MAX_PATH and the git checkout fails with "fatal: cannot create directory ... Filename too long" BEFORE the build even starts -- the documented install command fails on native Windows. Documented the one-time fix: `git config --global core.longpaths true` (+ the OS LongPathsEnabled registry key for OS-level MAX_PATH). 2. Windows CI leg (.github/workflows/ci.yml). CI ran only on ubuntu-latest via Makefile targets (make + POSIX shell are not native on Windows), so every Windows-only regression class was invisible to the gate. Added a `windows-smoke` job on windows-latest that enables core.longpaths, then installs (uv sync) and asserts the flagship IMPORTS and its CLI STARTS on Windows, plus ruff at the Makefile `lint` scope. It does not re-run the make gates; it guards install-time / import-time / CLI-start failures from POSIX-only APIs, path/encoding assumptions, and cp1252 defaults -- the class of bug the Ubuntu gate cannot see. The job deliberately does not run pyright. On Windows pyright resolves the stdlib against Windows stubs, where fcntl.flock, signal.SIGKILL and os.getsid/setsid do not exist, and it does not narrow `hasattr(module, "attr")` guards. Every POSIX-only call site in this repo is already guarded and documented -- an ImportError fallback that raises MigrationUnsupportedError in migration.py, hasattr probes in serve_lifecycle.py and single_turn.py -- so pyright-on-Windows reports exactly the code that handles Windows correctly, permanently and with no fix available short of churning working guards. Type correctness of this repo's own code is platform-invariant; the Ubuntu gate's `pyright src/` remains the type gate for both platforms. Evidence -- MAX_PATH reproduced + fix proven, native Windows (deep base dir): core.longpaths=false: CLONE_FAILED "fatal: cannot create directory .amplifier/evaluation/tasks/swe-bench-pro/instances/instance_NodeBB__... : Filename too long" core.longpaths=true: CLONE_OK, eval dir present Evidence -- windows-smoke on a real windows-latest runner: install, import smoke and CLI smoke all passed. The only red step was pyright, at the eight guarded POSIX-only sites described above; that step is removed rather than suppressed at the call sites. Note: the durable repo-side fix (stop committing 178-char eval-fixture paths, or relocate/fetch-on-demand) is a maintainer call -- renaming the dirs breaks the SWE-bench instance-id mapping -- so this change takes the non-invasive path (enable long paths) and documents it. 🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier) Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com> --- .github/workflows/ci.yml | 74 ++++++++++++++++++++++++++++++++++++++++ docs/INSTALL.md | 14 ++++++++ 2 files changed, 88 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 09ff809f..99db4e08 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -81,6 +81,80 @@ jobs: - name: make verify-parity (Python <-> TypeScript wire parity) run: make verify-parity + # Native-Windows smoke gate. This repo ships as a flagship engine that must run + # as well on Windows as on POSIX, but the `gate` job above runs only on Ubuntu + # via Makefile targets (make + POSIX shell are not native on windows-latest). + # This job does NOT re-run the make gates. + # + # What it verifies on native Windows: + # - the package installs -- every git clone `uv sync` performs succeeds + # under Windows' MAX_PATH limit + # - the three top-level packages import without POSIX-only crashes + # (signal.SIGKILL, os.kill(pid, 0), chmod-mode checks at import time) + # - the CLI entry point starts and its UTF-8 stdio reconfig runs + # - ruff is clean against a CRLF checkout, at the Makefile `lint` scope + # + # What it does NOT verify: runtime encoding behaviour. Nothing here reads a + # BOM'd or cp1252-encoded file, so credential loading and agent-md hydration + # stay unexercised -- catching regressions there needs targeted tests, not a + # smoke job. + # + # Deliberately no pyright here. On Windows pyright resolves the stdlib against + # Windows stubs, where fcntl.flock, signal.SIGKILL, and os.getsid/setsid do not + # exist -- and pyright does not narrow `hasattr(module, "attr")` guards. The + # POSIX-only call sites in this repo are all already guarded (an ImportError + # fallback in migration.py, hasattr probes in serve_lifecycle.py and + # single_turn.py) and documented, so pyright-on-Windows reports exactly the + # code that handles Windows correctly, and would do so permanently. Type + # correctness of this repo's own code is platform-invariant; the Ubuntu gate's + # `pyright src/` is the type gate for both platforms. + # + # Ruff runs directly rather than via make (make is not native on + # windows-latest) and is scoped to match Makefile `lint` exactly, so Windows + # never enforces a stricter style contract than Ubuntu. If this job goes red, + # a Windows regression has landed that the Ubuntu gate cannot see. + windows-smoke: + name: Windows smoke (install + import + CLI + lint) + runs-on: windows-latest + timeout-minutes: 15 + steps: + # The repo ships SWE-bench eval fixtures whose paths reach 178 chars; under + # a deep build/cache dir that exceeds Windows' 260-char MAX_PATH and git + # checkout fails with "Filename too long". core.longpaths lets git use the + # \\?\ long-path form. Set it BEFORE checkout so the checkout itself and + # every git clone `uv sync` performs are covered. + - name: Enable git long paths (Windows MAX_PATH) + run: git config --global core.longpaths true + + - name: Checkout + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + + - name: Install uv + uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0 + with: + enable-cache: true + + - name: Set up Python (uv-managed) + run: uv python install + + - name: Install dependencies + run: uv sync --all-extras --dev + + - name: Import smoke (packages import without POSIX-only crashes) + run: uv run python -c "import amplifier_agent_lib; import amplifier_agent_cli; import amplifier_agent_http.app; print('import ok')" + + - name: CLI smoke (entry point starts + UTF-8 stdio reconfig runs) + run: uv run amplifier-agent --help + + # Scope matches Makefile `lint` verbatim. Running this unscoped would pull + # in .amplifier/evaluation fixtures that have never been in the formatting + # contract, making Windows red on files the Ubuntu gate deliberately + # ignores. + - name: Ruff lint + format (same scope as Makefile `lint`) + run: | + uv run ruff check src/ scripts/ tests/ wrappers/ + uv run ruff format --check src/ scripts/ tests/ wrappers/ + # This is `make verify-wrapper`, the last piece of `make verify`. It is a # separate job because it needs Bun rather than uv/pnpm, and because it is the # gate in front of the npm publish in publish-wrapper.yml. diff --git a/docs/INSTALL.md b/docs/INSTALL.md index 991c6f30..7eac58b7 100644 --- a/docs/INSTALL.md +++ b/docs/INSTALL.md @@ -6,6 +6,20 @@ `git` is needed at run time, not just at install time: bundles and modules are fetched by cloning git repositories, so a machine without `git` on `PATH` can neither prime the cache nor mount a bundle. On Windows, installing [Git for Windows](https://git-scm.com/download/win) satisfies this and also provides the `bash` that the shell tool looks for. +> **Windows: enable git long paths before installing.** This repo ships evaluation +> fixtures whose paths reach ~178 characters. `uv tool install --from git+...` clones +> the repo into a deep temporary build directory, which pushes those paths past +> Windows' 260-character `MAX_PATH` limit — the install then fails with +> `fatal: cannot create directory ... Filename too long`. Enable long-path support +> once, before installing: +> +> ```powershell +> git config --global core.longpaths true +> ``` +> +> (For paths that also exceed `MAX_PATH` at the OS level, additionally enable +> `Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem\LongPathsEnabled = 1`.) + ## Recommended ```bash