Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ jobs:
| `working-directory` | Directory passed to `codex exec --cd`. Defaults to the repository root. | `""` |
| `sandbox` | Legacy sandbox mode. Prefer `permission-profile: ":workspace"` for new workflows. Mutually exclusive with `permission-profile`. | `""` |
| `permission-profile` | Built-in or configured [Codex permission profile](https://developers.openai.com/codex/permissions) selected through `default_permissions`. | `""` |
| `codex-version` | Version of `@openai/codex` to install. | `""` |
| `codex-version` | Version, tag, or range of `@openai/codex` to install. If unset, resolves the latest published version at run time; pin it for reproducible builds. | `""` |
| `codex-args` | Extra arguments forwarded to `codex exec`. Accepts JSON arrays (`["--flag", "value"]`) or shell-style strings. | `""` |
| `output-schema` | Inline schema contents written to a temp file and passed to `codex exec --output-schema`. Mutually exclusive with `output-schema-file`. | `""` |
| `output-schema-file` | Schema file forwarded to `codex exec --output-schema`. Leave empty to skip passing the option. | `""` |
Expand Down Expand Up @@ -185,6 +185,7 @@ See [Protecting your `OPENAI_API_KEY`](./docs/security.md#protecting-your-openai
| Name | Description |
| --------------- | --------------------------------------- |
| `final-message` | Final message returned by `codex exec`. |
| `codex-version` | Exact `@openai/codex` version installed for the run. |

As we saw in the example above, we took the `final-message` output of the `run_codex` step and made it an output of the `codex` job in the workflow:

Expand All @@ -194,6 +195,7 @@ jobs:
# ...
outputs:
final_message: ${{ steps.run_codex.outputs.final-message }}
codex_version: ${{ steps.run_codex.outputs.codex-version }}
```

## Additional tips
Expand Down
21 changes: 19 additions & 2 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ inputs:
required: false
default: ""
codex-version:
description: "Version of `@openai/codex` to install."
description: "Version, tag, or range of `@openai/codex` to install. Leave empty to resolve the latest published version at run time."
required: false
default: ""
codex-args:
Expand Down Expand Up @@ -124,6 +124,9 @@ outputs:
final-message:
description: "Raw output emitted by `codex exec`."
value: ${{ steps.run_codex.outputs['final-message'] }}
codex-version:
description: "Exact installed `@openai/codex` version resolved for this run."
value: ${{ steps.resolve_codex_version.outputs.codex-version }}
runs:
using: "composite"
steps:
Expand Down Expand Up @@ -161,10 +164,24 @@ runs:
--allow-users "$ALLOW_USERS"

- name: Install Codex CLI
id: resolve_codex_version
shell: bash
env:
CODEX_VERSION: ${{ inputs['codex-version'] }}
run: npm install -g "@openai/codex@${CODEX_VERSION}"
run: |
npm install -g "@openai/codex@${CODEX_VERSION}"

codex_root="$(npm root -g)"
resolved_codex_version="$(node -p 'require(process.argv[1]).version' "$codex_root/@openai/codex/package.json")"

echo "codex-version=$resolved_codex_version" >> "$GITHUB_OUTPUT"
echo "Installed Codex CLI version: $resolved_codex_version"
{
echo "### Codex CLI"
echo
echo "- Resolved version: \
\`$resolved_codex_version\`"
} >> "$GITHUB_STEP_SUMMARY"

- name: Install Codex Responses API proxy
shell: bash
Expand Down
21 changes: 21 additions & 0 deletions test/actionHardening.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,27 @@ test("Responses proxy replaces inherited Node options without exposing its API k
assert.doesNotMatch(step, /printenv PROXY_API_KEY\s*\|/);
});

test("action exposes the resolved codex version as an output", () => {
assert.match(
action,
/outputs:\n final-message:[\s\S]*\n codex-version:\n description: "Exact installed `@openai\/codex` version resolved for this run\."\n value: \$\{\{ steps\.resolve_codex_version\.outputs\.codex-version \}\}/
);
});

test("action reports the installed codex version without changing proxy resolution", () => {
const installCodexStep = actionStep("Install Codex CLI");
const installProxyStep = actionStep("Install Codex Responses API proxy");

assert.match(installCodexStep, /id: resolve_codex_version/);
assert.match(installCodexStep, /resolved_codex_version=.*@openai\/codex\/package\.json/);
assert.match(installCodexStep, /echo "codex-version=\$resolved_codex_version" >> "\$GITHUB_OUTPUT"/);
assert.match(installCodexStep, /GITHUB_STEP_SUMMARY/);
assert.match(
installProxyStep,
/CODEX_VERSION: \$\{\{ inputs\['codex-version'\] \}\}/
);
});

test(
"Responses proxy environment removes unsafe Node options and its API key",
{ skip: process.platform === "win32" },
Expand Down
Loading