Install Codex on Linux too, from the ansible role - #17
Merged
Merged
Conversation
The Brewfile has had Codex since it was added, but inside `if OS.mac?` -- Homebrew publishes only a cask for it, and casks are macOS-only. Linux was left with a comment telling you to run npm yourself, which meant a freshly provisioned box did not have it. So the role installs it, the way it already installs Claude Code: as the account, followed by a task that runs the thing and checks it answers. npm is the route OpenAI document beside the cask and it ships the same version, so this is the same tool arriving another way. Global rather than into the home, because with the account's own Homebrew node that means the prefix, which the account owns outright -- and it is why this leans on the Brewfile, since npm arrives with node. dev_user_codex_version pins a release for the reason dev_user_claude_code_channel does; empty takes the latest. Claude-Session: https://claude.ai/code/session_01WtqyKhgRvif4j6BMzZMTkA
The install task carries a PATH because npm is in the prefix and no login shell has run. The check below it needs one for a different reason: what npm links into the prefix is a script whose shebang is `/usr/bin/env node`, so running it needs node found the same way. Written to the shape of the Claude Code check above, which gets away without a PATH because its installer leaves a native binary behind, it failed with `env: 'node': No such file or directory` and rc 127 on a box where the install had just succeeded — the verification working as intended, against itself. Found by running these two tasks on a Linux host, which is what the PR said it could not do. Claude-Session: https://claude.ai/code/session_01RnyoBGq5XfivVqbEWMzrmE
Owner
Author
|
Ran these two tasks on a Linux host (the Loom CI runner, brew prefix owned by the account) and the check task failed where the install succeeded: What npm links into the prefix is a script with a |
`ansible_env` is a top-level fact injected as a variable, and `INJECT_FACTS_AS_VARS` defaulting to true is deprecated: the injection goes away in 2.24 and the name with it. Every run of this role says so now, once per task that reaches for the prefix — three of them, the two that were already here and the Codex check added by this branch. `ansible_facts.env` is the same value under the name that stays. Verified by running the Codex tasks on a Linux host under ansible-core 2.21.3: the deprecation warning is gone and the role is still `ok=3 changed=0`. Claude-Session: https://claude.ai/code/session_01RnyoBGq5XfivVqbEWMzrmE
The tasks named a prefix and trusted the PATH to lead to the npm that fills it, which is true only where the Brewfile has run. The executed-role job runs with it off: the install found the runner's own npm, succeeded against a prefix somewhere else, and the check went looking in the Homebrew one and found nothing — `No such file or directory: /home/linuxbrew/.linuxbrew/bin/codex`, on a run whose install step had just reported success. The whole argument for this being safe is the account's own node — global means the prefix, and the account owns the prefix — so that is the npm named now, by `executable`, and a stat decides whether there is one. A box without the Brewfile is left alone rather than served by whatever npm the PATH turns up into a prefix the account may not own. Verified on a Linux host both ways: with the prefix, ok=4 and changed=0 on a second run; with it pointed at a path that has no npm, both tasks skip and nothing fails. Claude-Session: https://claude.ai/code/session_01RnyoBGq5XfivVqbEWMzrmE
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.
The Brewfile has had Codex since it was added, but inside
if OS.mac?— Homebrew publishes only a cask for it, and casks are macOS-only. Linux was left with a comment telling you to run npm yourself, which meant a freshly provisioned box did not have it.So the role installs it, the way it already installs Claude Code: as the account, followed by a task that runs the thing and checks it answers. npm is the route OpenAI document beside the cask and it ships the same version, so this is the same tool arriving another way.
Which npm matters, and it is named rather than found. The argument for a global install being safe here is entirely the account's own Homebrew node — global means the prefix, and the account owns the prefix outright — so the install passes
executable: {{ dev_user_brew_prefix }}/bin/npm, and a stat decides whether there is one to pass. A box whose prefix has no npm is left alone. Letting the PATH choose instead is what the executed-role job caught: it runs withdev_user_brewfile: false, the runner's own npm took the install, the package landed in a prefix somewhere else, and the check went looking in the Homebrew one and found nothing.The check needs the PATH for a reason the install does not: what npm links into the prefix is a script whose shebang is
/usr/bin/env node, so running it needs node found the same way. Claude Code's check escapes that only because its installer leaves a native binary behind — copying its shape is what producedenv: 'node': No such file or directoryon a box where the install had just succeeded.dev_user_codex_versionpins a release for the reasondev_user_claude_code_channeldoes; empty takes the latest.ansible_envbecameansible_facts.envat all three sites while here, since the injection behind the old name goes away in ansible-core 2.24 and every run of this role warns about it.Run against a Linux host — the Loom CI runner, brew prefix owned by the account — both ways: with the prefix,
ok=4andchanged=0on a second pass,codex-cli 0.149.0answering; with the prefix pointed at a path that has no npm, both tasks skip and nothing fails. The executed-role job takes the second of those, so it proves the pair is harmless on a Brewfile-less box rather than proving the install; that half has been shown only on the host above.https://claude.ai/code/session_01WtqyKhgRvif4j6BMzZMTkA