From 1ed63e5de4cfa09a46ea8ef810523902613e0caa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Tue, 28 Jul 2026 09:53:25 +0200 Subject: [PATCH 1/2] Record upstream tracking and the concrete follow-up for the Copilot CLI install failure The "Known transient failures" section documented the `detection` job's `Install GitHub Copilot CLI` failure and correctly concluded there is no repo-side fix, but it left the reader without a way to know when that stops being true. Add a "Tracking the upstream fix" subsection recording the two upstream items: github/gh-aw#48358 (the DefaultCopilotVersion / compat.json drift) and github/gh-aw#48519 (honor `engine.version` for the copilot engine). #48519 is the unblocking change. It does not restore compat-matrix resolution (an explicit version still skips it), but `find_cached_copilot_bin` already short-circuits on an exact toolcache match before the cache-TTL check, so once `engine.version` is honored, pinning it to the version the hosted runner image caches removes both CLI downloads. The follow-up steps and the verification signal to look for in the run log are spelled out. Also refresh the version facts: gh-aw v0.83.4 is out and bumps DefaultCopilotVersion to 1.0.75, while this repo's lock files are compiled on v0.83.1 / 1.0.73; install_copilot_cli.sh itself is unchanged since v0.83.1. Refs #10203 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 47ebbbd3-1ddc-4dc2-8f1d-51f8d0460eac --- .github/workflows/README.md | 60 ++++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 4 deletions(-) diff --git a/.github/workflows/README.md b/.github/workflows/README.md index 6f94a1f3db..f0fa0af78e 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -190,13 +190,16 @@ already ships. Every agentic workflow run therefore downloads the CLI twice — job, once in the `detection` job — and each download is a chance to hit a transient GitHub CDN 5xx. The gap is structural, not a stale-image problem: `github/gh-aw-actions`'s `compat.json` caps `max-agent` at `1.0.56` (exactly what the runner image caches), while `DefaultCopilotVersion` is -already `1.0.73` on gh-aw v0.83.1 and `1.0.75` on `main` — so bumping gh-aw *widens* the gap. +`1.0.73` on the gh-aw v0.83.1 compiler this repo's lock files are pinned to, and `1.0.75` as of +gh-aw v0.83.4 — so bumping gh-aw *widens* the gap. -**There is no repo-side fix.** All of the following were evaluated and rejected: +**There is no repo-side fix *today*.** All of the following were evaluated and rejected: - `engine.version` is silently ignored for the Copilot engine — gh-aw overwrites it with - `DefaultCopilotVersion` (`pkg/workflow/copilot_engine_installation.go`, still the case on `main`). - `gh aw compile --strict` reports no error, and the regenerated lock keeps the pinned version. + `DefaultCopilotVersion` (`pkg/workflow/copilot_engine_installation.go`, still the case in + v0.83.4). `gh aw compile --strict` reports no error, and the regenerated lock keeps the pinned + version. This is the one rejected option upstream is actively changing — see + [Tracking the upstream fix](#tracking-the-upstream-fix). - Hand-editing a `.lock.yml` (older pin, extra retries) is overwritten on the next `gh aw compile`. - `engine.command:` pointed at `/opt/hostedtoolcache/copilot-cli//x64/bin/copilot` bypasses the install step, but hardcodes a path that rotates with runner images and skips the `.copilot` @@ -215,6 +218,53 @@ version the hosted runner toolcache is expected to contain (in practice the `com when a version is pinned. Merely choosing a default somewhere inside the compat window still downloads unless that exact version is cached. +#### Tracking the upstream fix + +The drift is filed upstream as [github/gh-aw#48358][gh-aw-48358] — *"DefaultCopilotVersion drifts +past compat.json max-agent, forcing a network install on every job and disabling the toolcache +path"*. It is still open, and nothing in gh-aw v0.83.2 – v0.83.4 touches the install path: +v0.83.4 only bumps `DefaultCopilotVersion` to `1.0.75`, and `install_copilot_cli.sh` is byte-for-byte +unchanged since v0.83.1 (both curls already carry `--retry 3 --retry-delay 5`, which is the retry +budget the failing run exhausted). + +The unblocking change is [github/gh-aw#48519][gh-aw-48519] — *"honor `engine.version` for +copilot"*, open against `main`. It makes the compiler emit `install_copilot_cli.sh ` +instead of always substituting `DefaultCopilotVersion`. That alone does **not** restore compat-matrix +resolution — an explicit version still skips it — but it hands us the lever we currently lack, +because `find_cached_copilot_bin` already short-circuits on an exact match: + +```text +Found candidate: /opt/hostedtoolcache/copilot-cli/1.0.56/x64/bin/copilot (version: 1.0.56, arch: x64) +Exact version match found: /opt/hostedtoolcache/copilot-cli/1.0.56/x64/bin/copilot +``` + +That branch returns *before* the cache-TTL check, so pinning the version the runner image already +caches skips both downloads outright — which is precisely what today's `range: none..none` lookup +cannot do. + +**Once #48519 ships in a gh-aw release**, the repo-side follow-up is: + +1. Bump the pinned gh-aw toolchain, recompile with `gh aw compile --strict`, review the `.lock.yml` + diff, and run `python .github/scripts/check_action_pins.py` (see + [Compile on the pinned toolchain](#compile-on-the-pinned-toolchain-and-check-the-pins-afterwards)). +2. Pin the engine to the version the hosted runner caches: + + ```yaml + engine: + id: copilot + version: "1.0.56" # == compat.json max-agent == hosted-runner toolcache entry + ``` + + No workflow here declares `engine:` today, so this is new frontmatter. Check whether gh-aw's + frontmatter merging lets a `shared/` import carry it before adding the block to all ~30 + workflows individually. +3. Verify a run logs `Exact version match found:` instead of `No compatible toolcache entry found` + followed by `-> Downloading ...`. + +Re-check *both* the `compat.json` `max-agent` value and the version the runner image actually caches +before choosing the pin — if they diverge, follow the toolcache, not the matrix, since only an exact +match avoids the download. + ## Catalog ### Agentic workflows @@ -312,3 +362,5 @@ Reusable agentic-workflow snippets imported via `imports:` in workflow frontmatt - **Minimal permissions.** Workflows declare the least privilege they need; write capabilities flow through gh-aw `safe-outputs:` rather than direct `permissions: write-all`. [gh-aw]: https://github.com/github/gh-aw +[gh-aw-48358]: https://github.com/github/gh-aw/issues/48358 +[gh-aw-48519]: https://github.com/github/gh-aw/pull/48519 From fe2f4b3d86c6069a6a8c0f1cbb84ef6e8d1f6da1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Tue, 28 Jul 2026 10:08:11 +0200 Subject: [PATCH 2/2] Never pin the Copilot CLI past the compat.json ceiling to chase a cache hit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The follow-up guidance told the reader to "follow the toolcache, not the matrix" when the cached CLI and the compat window diverge. That is wrong and unsafe: `max-agent` is the supported compatibility ceiling, so pinning to a cached version outside `min-agent`..`max-agent` would run every agentic workflow on an unsupported Copilot CLI just to save a download. Require the pin to satisfy both constraints — inside the compat window *and* present in the toolcache — and keep paying for the download when they diverge. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 47ebbbd3-1ddc-4dc2-8f1d-51f8d0460eac --- .github/workflows/README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/README.md b/.github/workflows/README.md index f0fa0af78e..8540b4dd72 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -261,9 +261,12 @@ cannot do. 3. Verify a run logs `Exact version match found:` instead of `No compatible toolcache entry found` followed by `-> Downloading ...`. -Re-check *both* the `compat.json` `max-agent` value and the version the runner image actually caches -before choosing the pin — if they diverge, follow the toolcache, not the matrix, since only an exact -match avoids the download. +Re-check *both* the `compat.json` window and the version the runner image actually caches before +choosing the pin, and only pin a version that satisfies both: it must sit inside +`min-agent`..`max-agent` *and* exist in the toolcache (`1.0.56` is both today). If they diverge — +the image caches something outside the compat window — stay on a compat-sanctioned version and keep +paying for the download. `max-agent` is the supported ceiling; pinning past it to chase a cache hit +would run every agentic workflow on an unsupported CLI. ## Catalog