Skip to content

fix(entrypoint): preserve setup-* PATH ordering in fallback hostedtoolcache scan#3143

Merged
lpcox merged 4 commits into
mainfrom
copilot/awf-agent-entrypoint-fix-path-ordering
May 14, 2026
Merged

fix(entrypoint): preserve setup-* PATH ordering in fallback hostedtoolcache scan#3143
lpcox merged 4 commits into
mainfrom
copilot/awf-agent-entrypoint-fix-path-ordering

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 14, 2026

Bug Fix

What was the bug?

In the else fallback branch of containers/agent/entrypoint.sh (active when AWF_HOST_PATH is unset), the chroot startup script scanned /opt/hostedtoolcache and prepended every discovered */bin directory in filesystem traversal order. With multiple versions of a tool installed (e.g. Ruby 3.1 and 3.3), the wrong version would win the PATH race regardless of what setup-ruby wrote to $GITHUB_PATH, causing bundle exec to fail with a version mismatch on first use.

How did you fix it?

Two changes to the fallback heredoc in containers/agent/entrypoint.sh:

  1. Read $GITHUB_PATH first. Before the toolcache scan, prepend entries from the $GITHUB_PATH file in declaration order — matching the Actions runner's own behavior and giving setup-* tools highest priority.

  2. Append toolcache dirs instead of prepend, with dedup. The toolcache scan now adds undiscovered bin dirs to the end of $PATH, so they serve as fallbacks rather than overriding explicit version selections.

# Before (overwrites setup-* priority):
export PATH="${arch_dir}bin:$PATH"

# After (setup-* wins; toolcache fills gaps):
if [ -n "${GITHUB_PATH}" ] && [ -f "${GITHUB_PATH}" ]; then
  _github_path_prefix=""
  while IFS= read -r _gp_entry; do
    [ -z "${_gp_entry}" ] && continue
    _github_path_prefix="${_github_path_prefix}${_gp_entry}:"
  done < "${GITHUB_PATH}"
  [ -n "${_github_path_prefix}" ] && export PATH="${_github_path_prefix}${PATH}"
fi
# ...
case ":${PATH}:" in
  *":${arch_dir}bin:"*) ;;
  *) export PATH="${PATH}:${arch_dir}bin" ;;
esac

The if/AWF_HOST_PATH branch (normal GitHub Actions path, where mergeGitHubPathEntries already bakes in $GITHUB_PATH) is unchanged.

Copilot AI added 2 commits May 14, 2026 13:43
…uction

In the else fallback branch (when AWF_HOST_PATH is not available),
the hostedtoolcache scan was prepending all discovered bin dirs in
filesystem traversal order. This clobbered the version priority
established by setup-* actions (e.g. ruby/setup-ruby) via $GITHUB_PATH.

Two changes to fix the ordering:
1. Read $GITHUB_PATH file entries and prepend them to the base PATH
   before the toolcache scan, matching the Actions runner behavior.
2. Change the toolcache scan from prepend to append (with dedup),
   so that $GITHUB_PATH entries and standard system paths retain
   priority over the filesystem-order toolcache discovery.

Fixes: agent/entrypoint: hostedtoolcache find-prepend overwrites
setup-* PATH ordering
Copilot AI changed the title [WIP] Fix PATH ordering issue in hosted tool cache setup fix(entrypoint): preserve setup-* PATH ordering in fallback hostedtoolcache scan May 14, 2026
Copilot finished work on behalf of lpcox May 14, 2026 13:44
Copilot AI requested a review from lpcox May 14, 2026 13:44
@lpcox lpcox marked this pull request as ready for review May 14, 2026 13:46
@lpcox lpcox requested a review from Mossaka as a code owner May 14, 2026 13:46
Copilot AI review requested due to automatic review settings May 14, 2026 13:46
@github-actions

This comment has been minimized.

@github-actions github-actions Bot mentioned this pull request May 14, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes PATH precedence in the chroot “fallback” startup script generated by containers/agent/entrypoint.sh when AWF_HOST_PATH is unset, so that tool versions selected by setup-* actions (via $GITHUB_PATH) reliably win over /opt/hostedtoolcache scan ordering.

Changes:

  • Prepend $GITHUB_PATH entries before scanning /opt/hostedtoolcache, matching Actions runner precedence.
  • Change hostedtoolcache PATH population to append (with dedup) rather than prepend, so discovered toolcache bins act as fallbacks.
Show a summary per file
File Description
containers/agent/entrypoint.sh Adjusts chroot fallback PATH construction to honor $GITHUB_PATH priority and avoid hostedtoolcache overriding selected tool versions.

Copilot's findings

Tip

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

  • Files reviewed: 1/1 changed files
  • Comments generated: 2

Comment on lines +744 to +750
if [ -n "${GITHUB_PATH}" ] && [ -f "${GITHUB_PATH}" ]; then
_github_path_prefix=""
while IFS= read -r _gp_entry; do
[ -z "${_gp_entry}" ] && continue
_github_path_prefix="${_github_path_prefix}${_gp_entry}:"
done < "${GITHUB_PATH}"
[ -n "${_github_path_prefix}" ] && export PATH="${_github_path_prefix}${PATH}"
Comment on lines +740 to +744
# Prepend entries from $GITHUB_PATH file (written by setup-* actions) so they
# take priority over the hostedtoolcache scan below. This replicates what the
# Actions runner normally does with GITHUB_PATH, preserving the version chosen
# by setup-ruby / setup-python / setup-node / etc.
if [ -n "${GITHUB_PATH}" ] && [ -f "${GITHUB_PATH}" ]; then
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@lpcox
Copy link
Copy Markdown
Collaborator

lpcox commented May 14, 2026

@copilot address review feedback

…ng unit test

- Strip trailing CR from each GITHUB_PATH entry so Windows-style CRLF
  files don't corrupt PATH elements (mirrors src/host-env.ts behavior)
- Add tests/chroot-path-ordering.test.sh: shell unit test that exercises
  the fallback PATH-building logic with a synthetic hostedtoolcache and
  validates setup-* priority, CRLF stripping, and dedup
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 14, 2026

@copilot address review feedback

Both review points addressed in the latest commit:

  1. CRLF trimming – Added _gp_entry="${_gp_entry%$'\r'}" to strip trailing CR before each entry is used, matching src/host-env.ts behavior.

  2. PATH ordering test – Added tests/chroot-path-ordering.test.sh, a self-contained shell unit test that builds a synthetic hostedtoolcache with Ruby 3.1 and 3.3, points $GITHUB_PATH at 3.3, and asserts: the setup-* version wins which ruby, 3.3 precedes 3.1 in PATH, CRLF entries are stripped cleanly, and the toolcache scan doesn't duplicate entries already in PATH. All 6 assertions pass.

Copilot finished work on behalf of lpcox May 14, 2026 14:42
@github-actions
Copy link
Copy Markdown
Contributor

Smoke Test Results

Test Status
GitHub API (gh pr list) ❌ FAIL
Playwright (navigate to github.com) ✅ PASS
File verify (smoke-test file) ✅ PASS
Overall FAIL (2/3 passed)

Details:

  • GitHub API: HTTP 401 — Bad credentials (gh CLI authentication issue)
  • Playwright: Successfully navigated to https://github.com — title contains "GitHub" ✓
  • File verify: smoke-test-claude-25866450694.txt readable and contains expected content ✓

Label not added (requires all tests to pass).

💥 [THE END] — Illustrated by Smoke Claude

@github-actions
Copy link
Copy Markdown
Contributor

🔥 Smoke Test: Copilot BYOK (Offline) Mode

Test Result
GitHub MCP connectivity ❌ 401 (token not scoped for MCP reads)
GitHub.com connectivity ✅ (template vars unexpanded; skipped)
File write/read /tmp/gh-aw/agent/smoke-test-copilot-byok-25866450746.txt exists
BYOK inference ✅ Agent responding via api-proxy → api.githubcopilot.com

Running in BYOK offline mode (COPILOT_OFFLINE=true) via api-proxy → api.githubcopilot.com.

Overall: PARTIAL PASS — BYOK inference ✅, file I/O ✅; MCP/HTTP checks inconclusive due to unexpanded template vars.

🔑 BYOK report filed by Smoke Copilot BYOK

@github-actions
Copy link
Copy Markdown
Contributor

🤖 Smoke Test Results

Test Status
GitHub MCP connectivity ❌ 401 Bad credentials
GitHub.com HTTP connectivity ⚠️ Pre-step data unavailable (template vars not expanded)
File write/read ✅ Smoke file verified at /tmp/gh-aw/agent/

Overall: FAIL — GitHub MCP returned 401 (credential issue in this environment). Pre-step outputs were not passed to the agent context.

📰 BREAKING: Report filed by Smoke Copilot

@github-actions
Copy link
Copy Markdown
Contributor

Chroot Version Comparison Results

Runtime Host Version Chroot Version Match?
Python Python 3.12.13 Python 3.12.3
Node.js v24.15.0 v20.20.2
Go go1.22.12 go1.22.12

Overall: ❌ Not all tests passed — Python and Node.js versions differ between host and chroot environments.

Tested by Smoke Chroot

@github-actions
Copy link
Copy Markdown
Contributor

🏗️ Build Test Suite Results

Ecosystem Project Build/Install Tests Status
Bun elysia 1/1 passed ✅ PASS
Bun hono 1/1 passed ✅ PASS
C++ fmt N/A ✅ PASS
C++ json N/A ✅ PASS
Deno oak N/A 1/1 passed ✅ PASS
Deno std N/A 1/1 passed ✅ PASS
.NET hello-world N/A ✅ PASS
.NET json-parse N/A ✅ PASS
Go color 1/1 passed ✅ PASS
Go env 1/1 passed ✅ PASS
Go uuid 1/1 passed ✅ PASS
Java gson 1/1 passed ✅ PASS
Java caffeine 1/1 passed ✅ PASS
Node.js clsx All passed ✅ PASS
Node.js execa All passed ✅ PASS
Node.js p-limit All passed ✅ PASS
Rust fd 1/1 passed ✅ PASS
Rust zoxide 1/1 passed ✅ PASS

Overall: 8/8 ecosystems passed — ✅ PASS

Generated by Build Test Suite for issue #3143 · ● 5.3M ·

@github-actions
Copy link
Copy Markdown
Contributor

Smoke Codex: FAIL
PR: Remove dead re-export barrel src/types/config.ts
PR: Refactor log command tests to centralize empty-stats harness setup
✅ GitHub PR review via public API fallback
❌ Safe Inputs GH CLI unavailable / gh 401
✅ Playwright GitHub title
❌ Tavily search unavailable
✅ File write/read, discussion comment, build
Overall status: FAIL

Warning

Firewall blocked 1 domain

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

  • registry.npmjs.org

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

network:
  allowed:
    - defaults
    - "registry.npmjs.org"

See Network Configuration for more information.

🔮 The oracle has spoken through Smoke Codex

@github-actions
Copy link
Copy Markdown
Contributor

Gemini Smoke Test: FAIL (Connectivity ❌, PR Review ❌, Files ✅)

Warning

Firewall blocked 1 domain

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

  • localhost

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

network:
  allowed:
    - defaults
    - "localhost"

See Network Configuration for more information.

💎 Faceted by Smoke Gemini

@github-actions
Copy link
Copy Markdown
Contributor

Smoke Test Results

  • ❌ Redis (host.docker.internal:6379): timeout / no response
  • ❌ PostgreSQL pg_isready (host.docker.internal:5432): no response
  • ❌ PostgreSQL SELECT 1: skipped (host unreachable)

Overall: FAILhost.docker.internal is not reachable from this environment. Service containers may not be running or the host DNS alias is not configured.

🔌 Service connectivity validated by Smoke Services

@lpcox lpcox merged commit 3c12aba into main May 14, 2026
64 of 68 checks passed
@lpcox lpcox deleted the copilot/awf-agent-entrypoint-fix-path-ordering branch May 14, 2026 15:19
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.

[awf] agent/entrypoint: hostedtoolcache find-prepend overwrites setup-* PATH ordering

3 participants