fix(e2e): unblock onboarding agent's permissions, fix macOS timeout#97
Merged
Conversation
Second manual run (after the bash-3.2/XDG fix) got further - opencode resolved config/model correctly this time and started reading the README - but hit two more real bugs: - opencode's non-interactive `run` mode auto-REJECTS any permission request it can't ask about interactively, including reading paths outside the workdir (e.g. /etc/os-release) or running package managers. That's everything this test needs the agent to do. Add --auto (opencode's equivalent of claude-code's --dangerously-skip-permissions) so it can actually act. - macOS has no `timeout` binary (GNU coreutils only) and its BSD sleep rejects duration suffixes like "20m" - the macOS leg failed immediately with "timeout: command not found". Replace it with a small portable run_with_timeout() (background + sleep-then-kill watchdog + wait), and switch the timeout value to plain seconds so `sleep` works on both GNU and BSD. Verified against both a modern bash and the real bash:3.2 image, including the case where the wrapped command exits well before the timeout - an earlier draft of this wrapper toggled `set -e`/`set +e` globally inside the function, which leaked out and re-armed errexit before the caller could read $?, aborting the script early; fixed by capturing the status via `wait "$pid" || status=$?` instead. Signed-off-by: Niclas Hülsmann <niclas.huelsmann@tngtech.com>
…t flip the exit code Both OS legs of the third manual run actually succeeded end-to-end this time (agent installed omac, got doctor healthy, launched omac start, and wrote a real report) - but ubuntu-latest still reported red. Root cause: the agent's own (documented, README-driven) `go install` attempt populates the Go module cache under $DRIVER_HOME/go/pkg/mod, which Go deliberately makes read-only. The script's `trap 'rm -rf "$WORK"' EXIT` then fails with a wall of "Permission denied", and since that's the EXIT trap's own exit status, it silently overrides whatever exit code the script had already decided on - turning a real pass into a false failure. Reproduced and fixed locally: chmod everything writable before rm -rf. Signed-off-by: Niclas Hülsmann <niclas.huelsmann@tngtech.com>
Contributor
Author
|
Pushed one more fix and re-ran directly on this branch until both legs went green with real, substantive sessions:
The workflow is green and doing its intended job — real onboarding sessions, real README gaps surfaced, no false failures from the harness itself. Not merging without your go-ahead. |
This was referenced Jul 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Second round of fixes after re-running
e2e-readme-onboarding.ymlon main post-#96:runmode auto-rejects any permission request it can't ask about interactively, including reading paths outside the workdir (/etc/os-release) or invoking package managers — i.e. everything this test needs the agent to do.timeout: command not found— macOS ships no GNU coreutilstimeout, and its BSDsleepdoesn't accept duration suffixes like20meither.Why
--autois opencode's documented equivalent of claude-code's--dangerously-skip-permissions(opencode run --help: "auto-approve permissions that are not explicitly denied (dangerous!)") — same rationale as that flag inclaudeCodeConfig()(internal/e2e/harnesses.go), and inherent to this test's premise of giving the agent a genuinely normal, unrestricted shell.timeoutneeded a portable replacement since only Linux runners have it.How
--autoto theopencode runinvocation.timeout --signal=TERMwith a smallrun_with_timeout()bash function (background the command, race asleep+killwatchdog,wait), and switched the timeout value from a duration string (20m) to plain seconds sosleepworks identically under GNU and BSD.run_with_timeoutbefore it shipped: it toggledset -e/set +einside the function, but those are global, not function-scoped — it silently re-armed errexit right before returning, which would abort the whole script on a non-zero agent exit instead of letting the caller readagent_status. Fixed by capturing the status viawait "$pid" || status=$?instead of toggling errexit at all.Verification
shellcheckclean; syntax-checked on both a modern bash and the realbash:3.2image.run_with_timeoutdirectly against three cases (quick success, quick failure, real timeout-kill) on both bash versions, confirming correct exit-status propagation in each — including reproducing and then fixing theset -eleak bug above before it reached CI.--autoactually lets the agent complete a real install locally (that would mean running an unrestricted,--auto-approved agent session against this dev machine, which is out of scope — the whole point of--autois to remove guardrails, and that should only happen on the disposable CI runner this test targets). Confirming this requires another real workflow run.