Conversation
- Add Windows Defender exclusion for gh CLI dir before extension install - Add per-step timeout-minutes: 4 to fail fast instead of hitting job ceiling - Add GH_DEBUG=api on Windows to trace which API/subprocess call stalls - Capture before/after process list to confirm orphan gh-aw hypothesis - Wrap gh extension install in 90s timeout in install-gh-aw.sh on Windows so the direct-download fallback kicks in instead of hanging indefinitely - Add install-gh-aw.sh to the workflow trigger paths Agent-Logs-Url: https://github.com/github/gh-aw/sessions/413284b6-4038-4bce-91bd-a3603ae37c98 Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
…ease repos The `gh extension upgrade --force` retry was failing with "unable to retrieve latest version for extension 'aw'" because the gh CLI uses /releases/latest internally, which returns 404 for prerelease-only repos. Change the retry to use `gh extension remove` + `gh extension install --pin VERSION` which calls fetchReleaseFromTag (not fetchLatestRelease) and works with any tag. Also extract `extensionRepo` constant to avoid duplicating "github/gh-aw". Agent-Logs-Url: https://github.com/github/gh-aw/sessions/fac75fb6-53df-4321-bf1a-374951416e41 Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Analyzed the new run (25036209433). Two separate issues were found and fixed: Issue 1 (install hang) — fixed in previous commit Issue 2 (upgrade retry failure) — fixed in commit Fix: Changed the retry path in The first attempt (buffered) still uses Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
There was a problem hiding this comment.
Pull request overview
This PR addresses two Windows-specific failures in the Extension Upgrade Test workflow: a hang during gh extension install (likely due to Defender scanning) and a retry-path failure during gh aw upgrade when /releases/latest returns 404 for prerelease-only repositories.
Changes:
- Updates the self-upgrade retry path to remove and reinstall the extension pinned to an exact version instead of re-running
gh extension upgrade --force. - Adds Windows-focused diagnostics, Defender exclusion, and a shorter install step timeout in the upgrade test workflow.
- Wraps
gh extension installwith a bounded timeout in installation scripts to avoid long hangs and trigger fallback behavior.
Show a summary per file
| File | Description |
|---|---|
pkg/cli/update_extension_check.go |
Changes the rename+retry logic to remove + reinstall pinned to the target version; centralizes the repo slug via a constant. |
install-gh-aw.sh |
Adds a Windows-only bounded timeout around gh extension install to prevent indefinite hangs. |
actions/setup-cli/install.sh |
Mirrors the same Windows timeout behavior used by the standalone installer script. |
.github/workflows/upgrade-test.yml |
Adds Windows diagnostics, Defender exclusion, API debug logging, step timeout, and orphan-process capture. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 4/4 changed files
- Comments generated: 3
| // Note: the backup file lives inside the extension directory, so if the | ||
| // remove step succeeds the backup is also gone; we clear backupPath to | ||
| // avoid a misleading restore attempt on subsequent failures. | ||
| removeCmd := exec.Command("gh", "extension", "remove", extensionRepo) | ||
| removeCmd.Stdout = os.Stderr |
There was a problem hiding this comment.
The retry path removes the extension directory before reinstalling, which also deletes the renamed backup binary (the ..bak file) because it lives alongside the executable inside the extension dir. If the subsequent gh extension install --pin ... fails (e.g., network/API error), the user is left without a working gh-aw binary and there is nothing to restore. Consider keeping the backup outside the extension directory (e.g., temp dir) or deferring deletion of the original until the pinned reinstall has succeeded, so rollback is always possible.
| // Retry path: remove + reinstall at the exact target version. | ||
| // | ||
| // Using "gh extension upgrade --force" again would call fetchLatestRelease | ||
| // (/releases/latest) internally, which returns 404 for prerelease-only repos | ||
| // and causes "unable to retrieve latest version for extension" errors. |
There was a problem hiding this comment.
The new remove+reinstall retry logic is significant behavior change (it changes how failures are handled and which gh subcommands run), but there are no tests exercising this path. Consider adding coverage for the rename+retry branch (including the remove/install sequence and rollback behavior) by abstracting gh command execution behind a stub-able helper or by adding an integration test that simulates failures.
| # Fix strategy (this PR): | ||
| # A. Disable Windows Defender real-time scanning for the gh CLI data | ||
| # directory *before* the install so the scan cannot block execution. | ||
| # B. Add a per-step timeout of 3 min so failures are caught fast rather |
There was a problem hiding this comment.
Comment says the per-step timeout is "3 min", but the actual timeout-minutes configured on the install step is 4. Please align the comment with the configuration (or adjust the timeout) to avoid confusion when debugging workflow timeouts.
| # B. Add a per-step timeout of 3 min so failures are caught fast rather | |
| # B. Add a per-step timeout of 4 min so failures are caught fast rather |
There was a problem hiding this comment.
Agreed! The comment says 3 min but timeout-minutes is 4. A suggestion code block was already included - hope the author picks it up!
📰 BREAKING: Report filed by Smoke Copilot · ● 814.5K
|
|
|
|
|
📰 BREAKING: Smoke Copilot is now investigating this pull request. Sources say the story is developing... |
|
✨ The prophecy is fulfilled... Smoke Codex has completed its mystical journey. The stars align. 🌟 |
|
🎬 THE END — Smoke Claude MISSION: ACCOMPLISHED! The hero saves the day! ✨ |
|
🚀 Smoke OpenCode MISSION COMPLETE! OpenCode delivered. 🔥 |
Agent Container Tool Check
Result: 11/12 tools available Overall Status: FAIL —
|
|
Smoke test overall: FAIL Warning Firewall blocked 2 domainsThe following domains were blocked by the firewall during workflow execution:
network:
allowed:
- defaults
- "ab.chatgpt.com"
- "chatgpt.com"See Network Configuration for more information.
|
|
🛠️ Agentic Maintenance updated this pull request branch. |
|
The smoke test agent was here! All systems nominal. May your NextCursor never be empty!
|
|
Smoke test #25044466983 results for PR #28860 by
Overall: PASS ✅
|
There was a problem hiding this comment.
Smoke test agent reviewed this PR. The Windows Defender fix and timeout approach look sound. Two minor inline notes added.
📰 BREAKING: Report filed by Smoke Copilot · ● 814.5K
| updateExtensionCheckLog.Printf("Could not remove extension before reinstall (will attempt install anyway): %v", removeErr) | ||
| } | ||
|
|
||
| retryCmd := exec.Command("gh", "extension", "install", extensionRepo, "--pin", latestVersion) |
There was a problem hiding this comment.
removeCmd.Stdout is set to os.Stderr here - intentional for interleaving remove output with error output, but worth a comment explaining why stdout goes to stderr.
| install_result=${PIPESTATUS[0]} | ||
| fi | ||
|
|
There was a problem hiding this comment.
The SC2086 disable comment is needed here, but consider using an array instead: declare the timeout as an array (GH_INSTALL_CMD_TIMEOUT=() or GH_INSTALL_CMD_TIMEOUT=(timeout 90)) so it expands safely without shellcheck suppression.
|
📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤 |
🧪 Smoke Test Results — Run 25044466924
Overall:
|
There was a problem hiding this comment.
💥 Automated smoke test review - all systems nominal! (Run 25044466924)
💥 [THE END] — Illustrated by Smoke Claude · ● 211K
| // manifest in place the install command takes the "already installed" code | ||
| // path and does nothing; removing the extension clears that guard. | ||
| // | ||
| // Note: the backup file lives inside the extension directory, so if the |
There was a problem hiding this comment.
Smoke Test Review Comment — The remove+reinstall retry logic correctly handles the prerelease-only repo limitation. Clearing backupPath after successful removal prevents misleading restore attempts on subsequent failures. Well done.
| # C. Capture `GH_DEBUG=api` on Windows to trace exactly which API call | ||
| # or binary invocation causes the stall if Defender is not the cause. | ||
| # ────────────────────────────────────────────────────────────────────────── | ||
|
|
There was a problem hiding this comment.
Smoke Test Review Comment — The Windows Defender exclusion step (Add-MpPreference -ExclusionPath) is targeted and appropriate. Logging the current exclusion list after adding helps verify the step succeeded. Good diagnostic approach.
Problem
The Extension Upgrade Test workflow on
windows-latesthad two separate failures:gh extension installhang (~10 min): Consistently hit the job timeout with zero output. See job 73303392593.gh aw upgraderetry failure: After fixing the install hang, a second issue was revealed — the self-upgrade retry path failed withunable to retrieve latest version for extension "aw".Root cause — install hang
The
ghCLI executes the newly downloadedgh-aw.exeas part of installation. On Windows, Windows Defender Real-Time Protection intercepts the new executable before allowing it to run, blocking the process indefinitely. Evidence: the runner always reportsTerminate orphan process: pid (NNNN) (gh-aw)at cleanup.Root cause — upgrade retry failure
The rename+retry path in
upgradeExtensionIfOutdatedre-rangh extension upgrade --force, which calls the/releases/latestGitHub API endpoint internally. This endpoint returns 404 for prerelease-only repos, causingLatestVersion()to return""and the"unable to retrieve latest version"error.Changes
pkg/cli/update_extension_check.gogh extension upgrade --forcetogh extension remove+gh extension install --pin EXACT_VERSION. Theinstall --pinpath usesfetchReleaseFromTag(notfetchLatestRelease) and works with any tag — stable or prerelease.extensionRepoconstant ("github/gh-aw") to avoid duplicating the string across remove, install, and upgrade invocations..github/workflows/upgrade-test.ymlghversion, Defender status, existing extension dir, and runninggh*processes before the install.Add-MpPreference -ExclusionPath "$env:LOCALAPPDATA\GitHub CLI"so Defender cannot block the newly downloaded binary.timeout-minutes: 4on the install step: fails fast with a clear error instead of silently consuming the 10-minute job budget.GH_DEBUG=apion Windows: captures verbose HTTP/API trace to pinpoint exactly which call or subprocess invocation hangs if Defender is not the sole cause.gh-aw.exeis still alive after the step.install-gh-aw.shto the pull_request path triggers.install-gh-aw.shgh extension installin a 90-secondtimeouton Windows so that, if the Defender-scan hang occurs in this script too, the existing direct-download fallback is triggered instead of hanging indefinitely.How to validate
Trigger the workflow manually (
workflow_dispatch) or open a PR that touchesinstall-gh-aw.shor.github/workflows/upgrade-test.yml. The Windows job should now complete successfully across both the install and upgrade steps.✨ PR Review Safe Output Test - Run 25044466924