Skip to content
11 changes: 6 additions & 5 deletions actions/setup/sh/install_copilot_cli.sh
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,8 @@ find_cached_copilot_bin() {
return 1
}

# Make a cached Copilot CLI available both to the current shell and later GitHub Actions steps.
# Make a cached Copilot CLI available to the current shell, later GitHub Actions steps,
# and absolute-path invocations used by the containerized harness.
activate_cached_copilot_bin() {
local cached_copilot_bin="$1"
local cached_copilot_dir=""
Expand All @@ -491,12 +492,12 @@ activate_cached_copilot_bin() {
if [ -n "${GITHUB_PATH:-}" ]; then
echo " Exporting ${cached_copilot_dir} to GITHUB_PATH (${GITHUB_PATH})"
echo "$cached_copilot_dir" >> "${GITHUB_PATH}"
return 0
fi

# Outside GitHub Actions there is no GITHUB_PATH file, so install a small wrapper
# instead of symlinking or copying the cached script and risking broken relative paths.
echo " GITHUB_PATH not set — installing wrapper at ${INSTALL_DIR}/copilot"
# Install a small wrapper instead of symlinking or copying the cached script and
# risking broken relative paths. The wrapper is still needed when GITHUB_PATH is
# set because the AWF container invokes ${INSTALL_DIR}/copilot by absolute path.
echo " Installing wrapper at ${INSTALL_DIR}/copilot"
wrapper_path="${TEMP_DIR}/copilot"
cat > "$wrapper_path" <<EOF
#!/usr/bin/env bash
Expand Down
43 changes: 42 additions & 1 deletion pkg/cli/install_copilot_cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,29 @@ func TestInstallCopilotCLIScriptUsesToolcacheBeforeDownload(t *testing.T) {
require.NoError(t, os.MkdirAll(fakeBinDir, 0o755))

curlLog := filepath.Join(tempDir, "curl.log")
installLog := filepath.Join(tempDir, "install.log")
installedWrapper := filepath.Join(tempDir, "installed-copilot")
sudoScript := filepath.Join(fakeBinDir, "sudo")
curlScript := filepath.Join(fakeBinDir, "curl")

require.NoError(t, os.WriteFile(sudoScript, []byte(`#!/usr/bin/env bash
if [ "${1:-}" = "chown" ]; then
exit 0
fi
if [ "${1:-}" = "install" ]; then
shift
mode=""
if [ "${1:-}" = "-m" ]; then
mode="$2"
shift 2
fi
src="$1"
dest="$2"
echo "install:${mode}:${dest}" >> "`+installLog+`"
cp "$src" "`+installedWrapper+`"
chmod "$mode" "`+installedWrapper+`"
exit 0

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.

[/tdd] The sudo install stub is duplicated across three test functions. Not a blocker, but a shared helper would reduce future maintenance burden if the install invocation signature changes.

💡 Suggestion

Extract a fakeSudoScript(installLog, installedWrapper string) string helper and reference it from all three tests.

@copilot please address this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 3a7203a by extracting the shared fakeSudoScript(...) helper and reusing it across the cached-install test setups.

fi
exec "$@"
`), 0o755))
require.NoError(t, os.WriteFile(curlScript, []byte(`#!/usr/bin/env bash
Expand All @@ -62,6 +78,13 @@ exit 97
githubPathContent, err := os.ReadFile(githubPath)
require.NoError(t, err, "Expected the script to append the cached bin dir to GITHUB_PATH")
assert.Contains(t, string(githubPathContent), toolcacheBin, "cached Copilot bin directory should be exported for later steps")

installLogContent, err := os.ReadFile(installLog)
require.NoError(t, err, "Expected cached toolcache activation to install the absolute-path wrapper")
assert.Contains(t, string(installLogContent), "install:0755:/usr/local/bin/copilot")
wrapperContent, err := os.ReadFile(installedWrapper)
require.NoError(t, err, "Expected wrapper content to be copied by fake sudo install")
assert.Contains(t, string(wrapperContent), `exec "`+cachedCopilot+`" "$@"`)
}

func TestInstallCopilotCLIScriptResolvesCompatVersionBeforeToolcacheLookup(t *testing.T) {
Expand Down Expand Up @@ -100,13 +123,22 @@ func TestInstallCopilotCLIScriptResolvesCompatVersionBeforeToolcacheLookup(t *te
require.NoError(t, os.MkdirAll(fakeBinDir, 0o755))

curlLog := filepath.Join(tempDir, "curl.log")
installedWrapper := filepath.Join(tempDir, "installed-copilot")
sudoScript := filepath.Join(fakeBinDir, "sudo")
curlScript := filepath.Join(fakeBinDir, "curl")

require.NoError(t, os.WriteFile(sudoScript, []byte(`#!/usr/bin/env bash
if [ "${1:-}" = "chown" ]; then
exit 0
fi
if [ "${1:-}" = "install" ]; then
shift
if [ "${1:-}" = "-m" ]; then
shift 2
fi
cp "$1" "`+installedWrapper+`"
exit 0
fi
exec "$@"
`), 0o755))
require.NoError(t, os.WriteFile(curlScript, []byte(`#!/usr/bin/env bash
Expand Down Expand Up @@ -231,7 +263,7 @@ exit 99
require.NoError(t, err, "install_copilot_cli.sh should succeed in rootless mode with toolcache and no sudo: %s", output)

assert.Contains(t, string(output), "Using cached GitHub Copilot CLI", "script should use cached copilot CLI")
assert.Contains(t, string(output), "GITHUB_PATH not set — installing wrapper at "+filepath.Join(homeDir, ".local", "bin", "copilot"))
assert.Contains(t, string(output), "Installing wrapper at "+filepath.Join(homeDir, ".local", "bin", "copilot"))
assert.FileExists(t, filepath.Join(homeDir, ".local", "bin", "copilot"))
assert.NoFileExists(t, sudoLog, "sudo should not be called in rootless mode")
})
Expand Down Expand Up @@ -273,13 +305,22 @@ func TestInstallCopilotCLIScriptFallsBackToBakedInDefaultWhenCompatUnavailable(t
require.NoError(t, os.MkdirAll(fakeBinDir, 0o755))

curlLog := filepath.Join(tempDir, "curl.log")
installedWrapper := filepath.Join(tempDir, "installed-copilot")
sudoScript := filepath.Join(fakeBinDir, "sudo")
curlScript := filepath.Join(fakeBinDir, "curl")

require.NoError(t, os.WriteFile(sudoScript, []byte(`#!/usr/bin/env bash
if [ "${1:-}" = "chown" ]; then
exit 0
fi
if [ "${1:-}" = "install" ]; then
shift
if [ "${1:-}" = "-m" ]; then
shift 2
fi
cp "$1" "`+installedWrapper+`"
exit 0
fi
exec "$@"
`), 0o755))
require.NoError(t, os.WriteFile(curlScript, []byte(`#!/usr/bin/env bash
Expand Down
Loading