|
| 1 | +# AGENTS.md |
| 2 | + |
| 3 | +This file provides guidance for AI agents and developers working with the |
| 4 | +`git-for-windows/setup-git-for-windows-sdk` repository. |
| 5 | + |
| 6 | +## Repository purpose |
| 7 | + |
| 8 | +This repository contains a GitHub Action that sets up a Git for Windows |
| 9 | +SDK (or a subset thereof) on a Windows runner, so that workflows can |
| 10 | +build Git for Windows, package its installer, or run its test suite |
| 11 | +without first having to install the full SDK by hand. The Action is |
| 12 | +published as `git-for-windows/setup-git-for-windows-sdk` and is consumed |
| 13 | +by [git-for-windows/git](https://github.com/git-for-windows/git), |
| 14 | +[git-for-windows/build-extra](https://github.com/git-for-windows/build-extra), |
| 15 | +[git-for-windows/MINGW-packages](https://github.com/git-for-windows/MINGW-packages), |
| 16 | +[git-for-windows/MSYS2-packages](https://github.com/git-for-windows/MSYS2-packages), |
| 17 | +and assorted other Git for Windows component repositories. Changes here |
| 18 | +ripple across that entire ecosystem, so backwards compatibility matters. |
| 19 | + |
| 20 | +The Action is written in TypeScript, bundled with `@vercel/ncc` into a |
| 21 | +single `dist/index.js`, and invoked as a Node 24 action declared by |
| 22 | +`action.yml`. There is no composite-action layer; everything happens in |
| 23 | +`main.ts` and `src/`. |
| 24 | + |
| 25 | +## Repository structure |
| 26 | + |
| 27 | +- `action.yml` -- Action manifest. Declares inputs (`flavor`, |
| 28 | + `architecture`, `msys`, `path`, `cleanup`, `verbose`, `cache`, |
| 29 | + `github-token`), branding, and points `runs.main` / `runs.post` at |
| 30 | + `dist/index.js` under `node24`. |
| 31 | +- `main.ts` -- Entry point. Selects between the CI-artifact fast path |
| 32 | + and the git-clone path, sets up `PATH`, `MSYSTEM`, and `LC_CTYPE`, |
| 33 | + creates `/dev/{fd,stdin,stdout,stderr}` symlinks, and handles the |
| 34 | + POST-action cleanup when the `cleanup` input is `true`. |
| 35 | +- `src/git.ts` -- The git-clone path. Maps `(flavor, architecture)` |
| 36 | + to `(repo, artifactName)` in `getArtifactMetadata`, then either does |
| 37 | + a bare clone plus `git worktree add` (for `flavor: full`) or a bare |
| 38 | + clone plus `please.sh create-sdk-artifact` (for the other flavors, |
| 39 | + using `build-extra`'s `please.sh`). |
| 40 | +- `src/ci_artifacts.ts` -- The fast path. Pulls the |
| 41 | + `git-sdk-<arch>-<flavor>.tar.{gz,zst}` asset from the |
| 42 | + `ci-artifacts` release in the matching `git-sdk-*` repo and pipes |
| 43 | + it through `tar.exe`. Only the `minimal` flavor (always) and |
| 44 | + `build-installers` (when the runner has Windows 11 24H2's |
| 45 | + Zstandard-capable `tar.exe`) take this path. |
| 46 | +- `src/downloader.ts`, `src/spawn.ts` -- small utilities used by the |
| 47 | + two paths above. |
| 48 | +- `src/__tests__/git.test.ts`, `__tests__/main.test.ts` -- Vitest |
| 49 | + tests. `main.test.ts` is gated on `RUN_NETWORK_TESTS=true` because |
| 50 | + it really downloads an SDK. |
| 51 | +- `dist/index.js`, `dist/index.js.map` -- the `ncc`-bundled artifact |
| 52 | + that is actually executed at runtime. Always regenerated alongside |
| 53 | + source changes, but in a dedicated follow-up commit (see commit |
| 54 | + conventions below). |
| 55 | + |
| 56 | +## Build, test, package |
| 57 | + |
| 58 | +The full validation chain is `npm run all`, which runs in order: |
| 59 | +`build` -> `format` -> `lint` -> `typecheck` -> `package` -> `test`. |
| 60 | +For incremental work, the individual scripts in `package.json` are: |
| 61 | + |
| 62 | +- `npm ci` -- install dependencies (lockfile-strict). |
| 63 | +- `npm run build` -- `tsc`, compiling `.ts` into `lib/`. |
| 64 | +- `npm run lint` -- `eslint **/*.ts`. |
| 65 | +- `npm run typecheck` -- `tsc --noEmit -p tsconfig.eslint.json`. |
| 66 | +- `npm run format` / `npm run format-check` -- Prettier. |
| 67 | +- `npm run test` -- Vitest. Set `RUN_NETWORK_TESTS=true` to also |
| 68 | + exercise `__tests__/main.test.ts`, which downloads a real SDK. |
| 69 | +- `npm run package` -- `@vercel/ncc` bundles `lib/main.js` into |
| 70 | + `dist/index.js` (with source map). |
| 71 | + |
| 72 | +The `build-test` workflow (`.github/workflows/test.yml`) runs the same |
| 73 | +chain on every PR and explicitly verifies that `dist/index.js` is up to |
| 74 | +date by checking that `git diff -aw HEAD -- ':(exclude)dist/index.js.map'` |
| 75 | +is empty after `npm run package`. Any push that changes `main.ts` or |
| 76 | +`src/` must therefore also include the regenerated `dist/index.js` (in |
| 77 | +its own follow-up commit, per the commit conventions below) before CI |
| 78 | +sees the tip, or CI fails. |
| 79 | + |
| 80 | +For Dependabot PRs, the `npm-run-package` workflow |
| 81 | +(`.github/workflows/npm-run-package.yml`) does the regeneration |
| 82 | +automatically and pushes a `npm run build && npm run package` commit |
| 83 | +back onto the dependabot branch. |
| 84 | + |
| 85 | +## Release model |
| 86 | + |
| 87 | +The repository uses floating release-train tags (`v0`, `v1`, `v2`, |
| 88 | +...) plus immutable point tags (`v2.0.0`, `v2.1.0`, ...). The |
| 89 | +`release-tag` workflow (`.github/workflows/release-tag.yml`) is |
| 90 | +triggered by pushing a `v*` point tag from `main`. It verifies the |
| 91 | +tag's GPG signature against `dscho`'s published keys, creates a |
| 92 | +GitHub Release, and fast-forwards the matching `v<N>` branch to the |
| 93 | +tagged commit. Consumers usually pin to a major-version branch: |
| 94 | + |
| 95 | +```yaml |
| 96 | +- uses: git-for-windows/setup-git-for-windows-sdk@v2 |
| 97 | +``` |
| 98 | +
|
| 99 | +## Input model: flavors and architectures |
| 100 | +
|
| 101 | +The Action supports four flavors of the SDK: |
| 102 | +
|
| 103 | +- `minimal` -- the smallest useful set for building and testing Git |
| 104 | + for Windows itself. `x86_64` only. |
| 105 | +- `makepkg-git` -- adds enough to package `mingw-w64-git`. `x86_64` |
| 106 | + only (can cross-package `i686`). |
| 107 | +- `build-installers` -- adds the tooling to assemble installers, |
| 108 | + Portable Git, MinGit, and friends. |
| 109 | +- `full` -- the complete SDK as a user would install it. The only |
| 110 | + flavor that exists for every architecture. |
| 111 | + |
| 112 | +The `architecture` input drives both the underlying `git-sdk-*` repo |
| 113 | +and the `MSYSTEM` / bin-path layout inside the SDK: |
| 114 | + |
| 115 | +| `architecture` | repo | MSYSTEM | mingw bin path | notes | |
| 116 | +| -------------- | --------------- | ------------ | ----------------- | -------------------------------------------------------------------------------------- | |
| 117 | +| `i686` | `git-sdk-32` | `MINGW32` | `/mingw32/bin` | only `build-installers` and `full` | |
| 118 | +| `x86_64` | `git-sdk-64` | `MINGW64` | `/mingw64/bin` | the default; fast path available for `minimal` | |
| 119 | +| `aarch64` | `git-sdk-arm64` | `CLANGARM64` | `/clangarm64/bin` | only `full` for now | |
| 120 | +| `ucrt64` | `git-sdk-64` | `UCRT64` | `/ucrt64/bin` | UCRT64 migration; cloned from the `ucrt64` branch of `git-sdk-64`; only `full` for now | |
| 121 | + |
| 122 | +The `ucrt64` axis is part of the larger UCRT64 migration tracked in |
| 123 | +https://github.com/git-for-windows/git-sdk-64/pull/117 and its |
| 124 | +follow-up comment |
| 125 | +https://github.com/git-for-windows/git-sdk-64/pull/117#issuecomment-4642726384. |
| 126 | +It shares the `git-sdk-64` repository with `x86_64` but is materialised |
| 127 | +from a different long-lived branch, so caches and on-disk directories |
| 128 | +must stay distinct (the artifact name is `git-sdk-ucrt64-<flavor>` |
| 129 | +rather than `git-sdk-64-<flavor>`). The `ci-artifacts` release of |
| 130 | +`git-sdk-64` contains no UCRT64 asset, so the CI-artifacts fast path |
| 131 | +is forcibly skipped for this axis; every flavor takes the |
| 132 | +`getViaGit` path. `build-extra`'s `please.sh create-sdk-artifact` does |
| 133 | +not yet understand `--architecture=ucrt64` either, so right now only |
| 134 | +`flavor: full` (which goes straight through `git worktree add`) |
| 135 | +produces a working SDK. The non-`full` flavors will start working once |
| 136 | +`build-extra` and the `ci-artifacts` pipeline catch up. |
| 137 | + |
| 138 | +## Relationship to other Git for Windows repositories |
| 139 | + |
| 140 | +- [git-for-windows/git-sdk-64](https://github.com/git-for-windows/git-sdk-64), |
| 141 | + [git-sdk-32](https://github.com/git-for-windows/git-sdk-32), |
| 142 | + [git-sdk-arm64](https://github.com/git-for-windows/git-sdk-arm64) -- |
| 143 | + the bare-repo SDKs themselves. Their `main` branch (and, for |
| 144 | + `git-sdk-64`, the `ucrt64` branch) is what `getViaGit` clones; |
| 145 | + their `ci-artifacts` release is what `getViaCIArtifacts` downloads |
| 146 | + (no UCRT64 asset there today). |
| 147 | +- [git-for-windows/build-extra](https://github.com/git-for-windows/build-extra) |
| 148 | + -- provides `please.sh create-sdk-artifact`, used by `getViaGit` to |
| 149 | + carve subset flavors (`minimal`, `makepkg-git`, `build-installers`) |
| 150 | + out of a full SDK clone. |
| 151 | +- [git-for-windows/git](https://github.com/git-for-windows/git), |
| 152 | + [git-for-windows/git-for-windows-automation](https://github.com/git-for-windows/git-for-windows-automation), |
| 153 | + [git-for-windows/MINGW-packages](https://github.com/git-for-windows/MINGW-packages), |
| 154 | + and most other component repositories consume this Action in their |
| 155 | + CI. Breaking changes here block their CI, so the v0/v1/v2 release |
| 156 | + trains exist to give consumers a stable pin. |
| 157 | + |
| 158 | +## Commit message conventions |
| 159 | + |
| 160 | +- Write flowing prose; no bullet points and no Markdown section |
| 161 | + headers in commit messages. |
| 162 | +- Stick to plain ASCII and English, avoid technical jargon unless |
| 163 | + necessary to bring across a specific aspect. |
| 164 | +- Lead with motivation (why), then non-obvious context, then |
| 165 | + intention. Only mention implementation details if the diff is not |
| 166 | + already obvious. References (PR/issue/discussion URLs) go at |
| 167 | + the end, not the top, and are full URLs, never GitHub abbreviations. |
| 168 | +- Cite external facts (release notes, upstream behavior, etc.) with |
| 169 | + inline URLs so each claim is self-contained. |
| 170 | +- Trailers come at the end in this order: first `Assisted-by:`, then |
| 171 | + `Signed-off-by:`. The `Assisted-by:` value names the AI model that |
| 172 | + helped, not the product or platform (e.g. `Assisted-by: Opus 4.7`, |
| 173 | + not `Assisted-by: Copilot CLI`). |
| 174 | +- Use one commit per logical change; do not bundle unrelated edits |
| 175 | + together even if they touch the same file. |
| 176 | +- Commit early, commit often. It is much easier to combine even |
| 177 | + incomplete commits into a complete, well-separated commit than to |
| 178 | + split morally-separate changes out from a messy commit. |
| 179 | +- Regenerated `dist/index.js` goes in a separate commit at the tip of |
| 180 | + the topic branch. It **never** goes into the same commit as the source |
| 181 | + change that necessitated it. The convention is the same as of the |
| 182 | + `npm-run-package` workflow, where the auto-generated subject is |
| 183 | + `npm run build && npm run package`. |
| 184 | + |
| 185 | +## Validating changes |
| 186 | + |
| 187 | +For any change to `action.yml`, `main.ts`, or `src/`: |
| 188 | + |
| 189 | +1. Run `npm run all` locally. It must pass cleanly. |
| 190 | +2. Verify `dist/index.js` is rebuilt (`git status` should show it |
| 191 | + modified) and commit it in a dedicated follow-up commit with |
| 192 | + subject `npm run build && npm run package`. |
| 193 | +3. The `build-test` workflow on the PR will re-run the full chain and |
| 194 | + re-verify the bundled artifact; the matrix workflow can be |
| 195 | + triggered manually (`workflow_dispatch`) to exercise the actual |
| 196 | + download paths on a Windows runner. |
| 197 | + |
| 198 | +Documentation-only changes (README, AGENTS) do not need the full |
| 199 | +chain, but `npm run format-check` should still pass. |
0 commit comments