Skip to content

fix: join CheckForUpdatesAsync goroutine and eliminate time.After leak#47699

Merged
pelikhan merged 8 commits into
mainfrom
copilot/deep-report-join-checkforupdatesasync-goroutine
Jul 24, 2026
Merged

fix: join CheckForUpdatesAsync goroutine and eliminate time.After leak#47699
pelikhan merged 8 commits into
mainfrom
copilot/deep-report-join-checkforupdatesasync-goroutine

Conversation

Copilot AI commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

CheckForUpdatesAsync launched a fire-and-forget goroutine with no join mechanism, and used a bare time.After(100ms) that leaks a timer channel until GC'd.

Changes

  • Join point via buffered-channel-close — goroutine now closes a done chan struct{} on exit; CheckForUpdatesAsync returns a func() that blocks on <-done (or ctx.Done()), mirroring the StartCompileUpdateCheck pattern in compile_update_check.go
  • Timer leak fixed — replaced time.After(100ms) with time.NewTimer + defer timer.Stop() so the timer is released immediately when the select exits
  • Caller updatedvalidate_command.go captures and defers the join function
  • Tests — updated TestCheckForUpdatesAsync_ContextCancellation to call join() instead of time.Sleep; added TestCheckForUpdatesAsync_JoinsGoroutine to verify the join returns promptly
// Before
func CheckForUpdatesAsync(ctx context.Context, noCheckUpdate bool, verbose bool) {
    go func() { /* fire-and-forget */ }()
    select {
    case <-time.After(100 * time.Millisecond): // leaks
    case <-ctx.Done():
    }
}

// After
func CheckForUpdatesAsync(ctx context.Context, noCheckUpdate bool, verbose bool) func() {
    done := make(chan struct{})
    go func() {
        defer close(done) // observable join point
        // ...
    }()
    timer := time.NewTimer(100 * time.Millisecond)
    defer timer.Stop()
    select {
    case <-done:
    case <-timer.C:
    case <-ctx.Done():
    }
    return func() {
        select {
        case <-done:
        case <-ctx.Done():
        }
    }
}

Run: https://github.com/github/gh-aw/actions/runs/30074181699

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 10.1 AIC · ⌖ 7.6 AIC · ⊞ 7K ·
Comment /souschef to run again


Generated by 👨‍🍳 PR Sous Chef · gpt54 · 22 AIC · ⌖ 9.21 AIC · ⊞ 7K ·
Comment /souschef to run again


Generated by 👨‍🍳 PR Sous Chef · gpt54 · 11.4 AIC · ⌖ 7.3 AIC · ⊞ 7K ·
Comment /souschef to run again


Run: https://github.com/github/gh-aw/actions/runs/30087480557

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 19.1 AIC · ⌖ 8.14 AIC · ⊞ 7K ·
Comment /souschef to run again


Run: https://github.com/github/gh-aw/actions/runs/30091871574

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 16 AIC · ⌖ 5.98 AIC · ⊞ 7K ·
Comment /souschef to run again


Generated by 👨‍🍳 PR Sous Chef · gpt54 · 19.3 AIC · ⌖ 10 AIC · ⊞ 7K ·
Comment /souschef to run again

- Change CheckForUpdatesAsync to return a func() join function (mirrors
  the compile_update_check.go StartCompileUpdateCheck pattern)
- Add a buffered done channel closed by the goroutine via defer close(done),
  providing an observable join point
- Replace bare time.After(100ms) with time.NewTimer + defer timer.Stop()
  to eliminate the per-invocation timer leak
- Update validate_command.go caller to capture and defer the join function
- Update TestCheckForUpdatesAsync_ContextCancellation to use join()
- Add TestCheckForUpdatesAsync_JoinsGoroutine to verify join completes
- Update pkg/cli/README.md function signature entry

Closes #47609

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix timer leak in CheckForUpdatesAsync goroutine fix: join CheckForUpdatesAsync goroutine and eliminate time.After leak Jul 24, 2026
Copilot AI requested a review from pelikhan July 24, 2026 05:01
@pelikhan
pelikhan marked this pull request as ready for review July 24, 2026 05:02
Copilot AI review requested due to automatic review settings July 24, 2026 05:02
@github-actions

github-actions Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Design Decision Gate 🏗️ completed the design decision gate check.

No ADR enforcement needed: PR #47699 does not have the 'implementation' label and has ≤100 new lines of code in business logic directories (71 additions across 4 files).

@github-actions

github-actions Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

@github-actions

github-actions Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

@github-actions

github-actions Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Attempts to make update checks joinable and clean up their timeout timer.

Changes:

  • Returns a goroutine finisher from CheckForUpdatesAsync.
  • Replaces time.After with a stoppable timer.
  • Updates the caller, tests, and API documentation.
Show a summary per file
File Description
pkg/cli/validate_command.go Defers the update-check finisher.
pkg/cli/update_check.go Adds completion signaling and timer cleanup.
pkg/cli/update_check_test.go Updates cancellation tests and adds join coverage.
pkg/cli/README.md Documents the new return signature.

Review details

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 4/4 changed files
  • Comments generated: 3
  • Review effort level: Medium

Comment thread pkg/cli/update_check.go Outdated
Comment on lines +297 to +301
return func() {
select {
case <-done:
case <-ctx.Done():
}
Comment thread pkg/cli/update_check_test.go Outdated
Comment on lines +377 to +381
// Use a cancelled context to make the goroutine exit quickly
ctx, cancel := context.WithCancel(context.Background())
cancel()

join := CheckForUpdatesAsync(ctx, false, false)
Comment thread pkg/cli/update_check_test.go Outdated
Comment on lines +366 to +368
os.Unsetenv("GITHUB_ACTIONS")
os.Unsetenv("CONTINUOUS_INTEGRATION")
os.Unsetenv("GH_AW_MCP_SERVER")
@github-actions github-actions Bot mentioned this pull request Jul 24, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

Test Quality Score: 90/100 — Excellent

Analyzed 2 test(s): 2 design, 0 implementation, 0 violation(s).

📊 Metrics (2 tests)
Metric Value
Analyzed 2 (Go: 2, JS: 0)
✅ Design 2 (100%)
⚠️ Implementation 0 (0%)
Edge/error coverage 2 (100%)
Duplicate clusters 0
Inflation ⚠️ Yes (47 test / 20 prod = 2.35:1, minor)
🚨 Violations 0
Test File Classification Issues
TestCheckForUpdatesAsync_ContextCancellation (modified) update_check_test.go:341 design_test None — replaced time.Sleep with deterministic join()
TestCheckForUpdatesAsync_JoinsGoroutine (new) update_check_test.go:356 design_test None — deadline-guarded goroutine-join contract

Verdict

Passed. 0% implementation tests (threshold: 30%). Both tests verify behavioral contracts of the new API — context cancellation correctness and goroutine liveness — with no mocks, no happy-path-only coverage, and a proper build tag. The 2.35:1 test-to-prod line ratio is a minor flag; the extra test lines are justified by the goroutine-join liveness harness.

🧪 Test quality analysis by Test Quality Sentinel · sonnet46 · 29.9 AIC · ⌖ 7.72 AIC · ⊞ 7K ·
Comment /review to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Test Quality Sentinel: 90/100. 0% implementation tests (threshold: 30%). Both new/modified tests verify design-level behavioral contracts with no violations.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation is correct and well-structured.

  • defer close(done) / defer recover() ordering (LIFO) is intentional and correct: panic is recovered before the channel closes.
  • timer.Stop() is properly deferred at function scope, not inside the goroutine.
  • Join function mirrors the StartCompileUpdateCheck pattern, including graceful ctx-cancel fallback.
  • Tests are deterministic — no time.Sleep races.

No blocking issues found.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · sonnet46 · 10.8 AIC · ⌖ 4.48 AIC · ⊞ 5K

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

REQUEST_CHANGES — The central join guarantee is broken, the test that should catch it passes for the wrong reason, and the new test pollutes shared environment state.

### Blocking issues (3)
  1. join() exits on ctx.Done() without goroutine completing (update_check.go:297) — The returned closure selects on both <-done and <-ctx.Done(). On context cancellation (the normal shutdown path), it returns immediately while the goroutine may still be running. The fix is return func() { <-done } — the goroutine already exits promptly on cancellation internally.

  2. TestCheckForUpdatesAsync_JoinsGoroutine validates join() returns quickly, not that the goroutine finished (update_check_test.go:395) — Because the test uses a pre-cancelled context, join() returns via <-ctx.Done() instantly regardless of goroutine state. The test is a tautology that would pass even if join were func() {}. It needs to assert actual goroutine completion via a side-effect or a non-cancelled context with a controlled goroutine.

  3. Three env vars leaked in the new test (update_check_test.go:366) — GITHUB_ACTIONS, CONTINUOUS_INTEGRATION, GH_AW_MCP_SERVER are unset but never restored, silently altering the behavior of shouldCheckForUpdate in subsequent tests on CI runners where those vars are set. Use t.Setenv() or save-and-defer for all three.

🔎 Code quality review by PR Code Quality Reviewer · sonnet46 · 46 AIC · ⌖ 5.07 AIC · ⊞ 5.7K
Comment /review to run again

Comment thread pkg/cli/update_check.go
return
}

return func() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

join() does not actually wait for the goroutine — it exits early on context cancellation.

💡 Details and suggested fix

The returned join function selects on both <-done and <-ctx.Done(). When the context is cancelled (the common case when a command is exiting), join() returns via <-ctx.Done() without waiting for the goroutine to finish. The goroutine can still be alive — making HTTP calls or writing files — after join() has returned, defeating the stated contract.

// Current (broken): exits early when context is done
return func() {
    select {
    case <-done:
    case <-ctx.Done(): // returns without goroutine completing
    }
}

// Fix: always wait for goroutine (it exits promptly on ctx.Done internally)
return func() {
    <-done
}

The goroutine body already checks ctx.Err() and exits promptly on cancellation. The ctx.Done() arm in the join closure is a safety-valve that masks a goroutine leak rather than curing it.

Comment thread pkg/cli/update_check_test.go Outdated

// Ensure we're not in CI mode so that shouldCheckForUpdate returns true
os.Unsetenv("CI")
os.Unsetenv("GITHUB_ACTIONS")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test pollutes shared environment: GITHUB_ACTIONS, CONTINUOUS_INTEGRATION, and GH_AW_MCP_SERVER are unset but never restored.

💡 Details and fix

TestCheckForUpdatesAsync_JoinsGoroutine saves only CI and getLastCheckFilePathFunc, then unsets three other env vars without saving their originals. On a real CI runner all three are typically set, and other tests running in the same process after this one will observe them missing, altering shouldCheckForUpdate / IsRunningInCI results.

// Current (broken)
os.Unsetenv("CI")
os.Unsetenv("GITHUB_ACTIONS")           // not restored
os.Unsetenv("CONTINUOUS_INTEGRATION")   // not restored
os.Unsetenv("GH_AW_MCP_SERVER")         // not restored

// Fix: save and restore all
origGHA  := os.Getenv("GITHUB_ACTIONS")
origCI2  := os.Getenv("CONTINUOUS_INTEGRATION")
origMCP  := os.Getenv("GH_AW_MCP_SERVER")
defer func() {
    os.Setenv("GITHUB_ACTIONS", origGHA)
    os.Setenv("CONTINUOUS_INTEGRATION", origCI2)
    os.Setenv("GH_AW_MCP_SERVER", origMCP)
}()

Or use t.Setenv() (Go 1.17+) which restores automatically and is safe with parallel tests.

// goroutine joined successfully
case <-time.After(2 * time.Second):
t.Fatal("join function did not return within 2 seconds")
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New test validates the wrong invariant — it passes for the wrong reason due to the join() bug.

💡 Details

TestCheckForUpdatesAsync_JoinsGoroutine verifies that join() returns within 2 seconds when the context is already cancelled. Because join() selects on <-ctx.Done() (which is already closed), it returns immediately regardless of whether the goroutine has finished. The test therefore passes even with a completely broken join implementation such as return func() {}.

To make this test meaningful, assert that the goroutine has actually completed by checking a side-effect (e.g., the done channel is closed) after join() returns, or restructure the test to use an uncancelled context with a goroutine that signals completion:

// After join() returns, verify the internal goroutine is done
// by trying to receive on a separate sentinel, or assert file side-effects.
// Simply checking join() returned is not sufficient.

As written the test gives false confidence in goroutine cleanup.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skills-Based Review 🧠

Applied /diagnosing-bugs — the structural change is good, but there are two issues that undermine the correctness of the fix.

📋 Key Themes

Issues

  1. Join function exits early on ctx cancellation (update_check.go line 297–301): The returned func() selects on ctx.Done() in addition to done, so if the context is already cancelled (common at shutdown), join() returns without waiting for the goroutine to call close(done). This is the same goroutine leak the PR is trying to fix. The goroutine internally already exits promptly on context cancellation, so the join function only needs to <-done.

  2. New test validates the wrong path (update_check_test.go line 354–398): TestCheckForUpdatesAsync_JoinsGoroutine pre-cancels the context before calling CheckForUpdatesAsync. The test's join() will exit via the ctx.Done() arm immediately — it never waits for the goroutine's done channel. The test passes regardless of whether the goroutine has exited, giving false confidence.

Positive Highlights

  • time.Aftertime.NewTimer + defer timer.Stop() is the correct fix for the timer channel leak
  • ✅ Buffered channel done with defer close(done) is idiomatic Go for observable join points
  • validate_command.go correctly captures and defers the join function
  • ✅ README updated to reflect the new signature
  • TestCheckForUpdatesAsync_ContextCancellation updated to use join() instead of time.Sleep — this is a clear improvement

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · sonnet46 · 36.3 AIC · ⌖ 4.86 AIC · ⊞ 6.7K
Comment /matt to run again

Comment thread pkg/cli/update_check.go Outdated
select {
case <-done:
case <-ctx.Done():
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/diagnosing-bugs] The join function exits on ctx.Done() before the goroutine has closed done, creating the same goroutine leak the PR set out to fix: if the context is already cancelled at the time the caller defers join(), the function returns immediately while the goroutine is still running.

💡 Suggested fix

The goroutine already respects ctx cancellation internally (it exits promptly when ctx is cancelled). Simply wait only on done:

return func() {
    <-done // goroutine always closes done; safe to block here
}

If a hard timeout is preferred for defense-in-depth:

return func() {
    t := time.NewTimer(2 * time.Second)
    defer t.Stop()
    select {
    case <-done:
    case <-t.C:
    }
}

@copilot please address this.

ctx, cancel := context.WithCancel(context.Background())
cancel()

join := CheckForUpdatesAsync(ctx, false, false)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/diagnosing-bugs] TestCheckForUpdatesAsync_JoinsGoroutine pre-cancels the context before calling CheckForUpdatesAsync, so join() returns via the ctx.Done() arm rather than the done arm — it never actually tests that the goroutine has finished running.

💡 Suggested approach

Use a context that stays live during the test, instrument the goroutine's completion with a side-effect (e.g. write a file or set an atomic), and assert that side-effect is observed after join() returns:

ctx := context.Background() // NOT pre-cancelled
var goroutineRan atomic.Bool
// inject a hook that sets goroutineRan = true at the end of checkForUpdatesWithContext
join := CheckForUpdatesAsync(ctx, false, false)
join()
assert.True(t, goroutineRan.Load(), "goroutine should have completed before join returned")

The current test only proves the join function itself doesn't hang — not that the goroutine has exited.

@copilot please address this.

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot run pr-finisher skill

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

@copilot run pr-finisher skill

Completed a pr-finisher pass and pushed the fixes in 0c938ba. The update-check finisher now cancels a child context and always waits for goroutine completion, and the join test now verifies blocking/unblocking behavior with proper env restoration via t.Setenv.

@github-actions

Copy link
Copy Markdown
Contributor

Great work on this goroutine lifecycle fix! 🎯

This PR does excellent work eliminating the fire-and-forget goroutine pattern and the time.After timer leak in CheckForUpdatesAsync. The implementation is clean, mirrors the established StartCompileUpdateCheck pattern, and includes solid test coverage for both the context cancellation path and the new join mechanism.

What looks good:

  • ✅ Focused change — fixes exactly one issue across 4 files
  • ✅ Tests included — updated existing test and added new join verification test
  • ✅ Clear description — shows before/after code and explains the fix strategy
  • ✅ Proper cleanup — timer leak fixed with defer timer.Stop(), goroutine has observable join point

The PR is ready for review.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • patchdiff.githubusercontent.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "patchdiff.githubusercontent.com"

See Network Configuration for more information.

Generated by ✅ Contribution Check · sonnet46 · 58.2 AIC · ⌖ 10.4 AIC · ⊞ 6.2K ·

Copilot AI commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

@copilot please run the pr-finisher skill, update this branch, and confirm the remaining blocking review feedback is fully addressed before rerunning checks.

...

Verified on HEAD 0b29b72 that the blocking github-actions[bot] feedback is already addressed:

  • pkg/cli/update_check.go: join closure cancels child context and waits on <-done.
  • pkg/cli/update_check_test.go: TestCheckForUpdatesAsync_JoinsGoroutine uses a live context + controlled blocker to prove join blocks/unblocks on worker completion.
  • pkg/cli/update_check_test.go: env setup uses t.Setenv (including GH_AW_MCP_SERVER) to avoid leakage.

I reran checks in this pass:

  • make fmt
  • make lint
  • make test-unit ✅ (after unshallowing and fetching origin/main)
  • go test ./pkg/cli -run 'TestCheckForUpdatesAsync_(ContextCancellation|JoinsGoroutine)$'
  • make test ❌ pre-existing unrelated failures remain (pkg/workflow action pin version drift and wasm golden tests)
  • make recompile

No further code changes were needed in this pass.

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot please run the pr-finisher skill, address unresolved review comments, and rerun checks once the branch is up to date.

Unresolved review feedback:

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 19.1 AIC · ⌖ 8.14 AIC · ⊞ 7K ·
Comment /souschef to run again

Copilot AI commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

@copilot please run the pr-finisher skill, address unresolved review comments, and rerun checks once the branch is up to date.

Unresolved review feedback:...

Checked on HEAD 0b29b72 after confirming the branch is up to date with origin/main (ahead/behind: 0/6). The unresolved review items you linked are from older commits and are already satisfied in current code:

  • /home/runner/work/gh-aw/gh-aw/pkg/cli/update_check.go: join cancels child context and waits on <-done.
  • /home/runner/work/gh-aw/gh-aw/pkg/cli/update_check_test.go: join test uses a live context with controlled blocking/unblocking.
  • /home/runner/work/gh-aw/gh-aw/pkg/cli/update_check_test.go: env vars use t.Setenv restoration.

Reran checks after the up-to-date verification:

  • make fmt
  • make lint
  • make test-unit
  • go test ./pkg/cli -run 'TestCheckForUpdatesAsync_(ContextCancellation|JoinsGoroutine)$'
  • make test ❌ (pre-existing unrelated failures in pkg/workflow: action pin version drift + wasm golden tests)
  • make recompile

No additional code changes were needed in this pass.

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot please run the pr-finisher skill, confirm the remaining unresolved review items are fully addressed on the current head, and rerun checks once the branch is up to date.

Unresolved review feedback:

Generated by 👨🍳 PR Sous Chef

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 16 AIC · ⌖ 5.98 AIC · ⊞ 7K ·
Comment /souschef to run again

Copilot AI commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

@copilot please run the pr-finisher skill, confirm the remaining unresolved review items are fully addressed on the current head, and rerun checks once the branch is up to date.

Unresolved review f...

Confirmed on current HEAD 0b29b72 (branch is up to date with origin/main, behind 0 / ahead 6) that the unresolved review items are already fully addressed:

  • /home/runner/work/gh-aw/gh-aw/pkg/cli/update_check.go: join now cancels child context and waits for goroutine completion (<-done).
  • /home/runner/work/gh-aw/gh-aw/pkg/cli/update_check_test.go: join test uses a live context with controlled blocking/unblocking to prove real goroutine completion.
  • /home/runner/work/gh-aw/gh-aw/pkg/cli/update_check_test.go: test env setup uses t.Setenv (including GH_AW_MCP_SERVER) so state is restored.

Reran checks in this pass:

  • make fmt
  • make lint
  • make test-unit
  • make test ❌ (pre-existing unrelated failures in pkg/workflow: action pin drift + wasm golden mismatches)
  • make recompile

Also checked prior CI run logs via GitHub MCP; no failed jobs were reported for the referenced PR Sous Chef run. No additional code changes were needed in this pass.

@github-actions

Copy link
Copy Markdown
Contributor

🤖 PR Triage

Field Value
Category bug
Risk medium
Priority Score 62/100
Score Breakdown Impact: 30 · Urgency: 18 · Quality: 14
Recommended Action fast_track
CI ✅ passing

Rationale: Goroutine leak + timer leak fix in update check path. 4 files +93/-21, well-described, CI green. Non-trivial concurrency change warrants human review but low surface area.

Generated by 🔧 PR Triage Agent · sonnet46 · 32.4 AIC · ⌖ 5.13 AIC · ⊞ 5.7K ·

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot merge main and make wasm golden test suite for reliable

…deep-report-join-checkforupdatesasync-goroutine

Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>

Copilot AI commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

@copilot please run the pr-finisher skill, confirm all unresolved review feedback is fully addressed on the current head, and rerun checks once the branch is up to date.

Unresolved review feedback:...

Completed in 39cbc4d.

  • Branch is now up to date with origin/main (merged latest main into this branch).
  • Confirmed all listed unresolved review items are already addressed on current HEAD:
    • /home/runner/work/gh-aw/gh-aw/pkg/cli/update_check.go: join cancels child context and waits for goroutine completion (<-done).
    • /home/runner/work/gh-aw/gh-aw/pkg/cli/update_check_test.go: join test uses a live context with controlled blocking/unblocking.
    • /home/runner/work/gh-aw/gh-aw/pkg/cli/update_check_test.go: env setup uses t.Setenv (including GH_AW_MCP_SERVER) to avoid leakage.

Reran checks after branch update:

  • make fmt
  • make lint
  • make test-unit
  • make test ❌ (pre-existing unrelated failures in pkg/workflow: action pin drift + wasm golden mismatches)
  • make recompile

CI log triage for the provided run (30102818328) via GitHub MCP reported no failed jobs.

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot review failed wasm golden test https://github.com/github/gh-aw/actions/runs/30105142160/job/89520942095?pr=47699 and try to fix to make the test more resilient.

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

@copilot merge main and make wasm golden test suite for reliable

Merged origin/main is already present on this branch (current head was up to date), and I pushed c74c091024 to make the wasm golden suite reliable. The fix normalizes volatile actions/checkout pinned SHA/version in pkg/workflow/wasm_golden_test.go, so routine pin bumps no longer break golden comparisons. Re-ran go test ./pkg/workflow -run '^TestWasmGolden_' -count=1 and it passes.

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
@pelikhan
pelikhan merged commit 7784b12 into main Jul 24, 2026
18 of 19 checks passed
@pelikhan
pelikhan deleted the copilot/deep-report-join-checkforupdatesasync-goroutine branch July 24, 2026 16:09
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.83.3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[deep-report] Join the CheckForUpdatesAsync goroutine and drop its time.After timer leak

4 participants