mirror of
https://github.com/coder/registry.git
synced 2026-06-03 04:58:15 +00:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e30d56bd63 | |||
| 8795bc399e | |||
| 3109fe6719 | |||
| fd4784cdcc | |||
| 358ca6804b | |||
| 94203b2c8b |
@@ -93,7 +93,7 @@ jobs:
|
||||
- name: Validate formatting
|
||||
run: bun fmt:ci
|
||||
- name: Check for typos
|
||||
uses: crate-ci/typos@7b04f660f4ee4f048d18fd341887cf28dfbedfe2 # v1.46.3
|
||||
uses: crate-ci/typos@f8a58b6b53f2279f71eb605f03a4ae4d10608f45 # v1.47.0
|
||||
with:
|
||||
config: .github/typos.toml
|
||||
validate-readme-files:
|
||||
|
||||
@@ -13,14 +13,14 @@ Install and configure the [Codex CLI](https://github.com/openai/codex) in your w
|
||||
```tf
|
||||
module "codex" {
|
||||
source = "registry.coder.com/coder-labs/codex/coder"
|
||||
version = "5.0.0"
|
||||
version = "5.1.0"
|
||||
agent_id = coder_agent.main.id
|
||||
openai_api_key = var.openai_api_key
|
||||
}
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> If upgrading from v4.x.x of this module: v5 is a major refactor that drops support for [Coder Tasks](https://coder.com/docs/ai-coder/tasks) and [Boundary](https://coder.com/docs/ai-coder/agent-firewall). v5 also assumes npm is pre-installed; it no longer bootstraps Node.js. Keep using v4.x.x if you depend on them. See the [PR description](https://github.com/coder/registry/pull/879) for a full migration guide.
|
||||
> If upgrading from v4.x.x of this module: v5 is a major refactor that drops support for [Coder Tasks](https://coder.com/docs/ai-coder/tasks) and [Boundary](https://coder.com/docs/ai-coder/agent-firewall). Keep using v4.x.x if you depend on them. See the [PR description](https://github.com/coder/registry/pull/879) for a full migration guide.
|
||||
|
||||
## Examples
|
||||
|
||||
@@ -33,7 +33,7 @@ locals {
|
||||
|
||||
module "codex" {
|
||||
source = "registry.coder.com/coder-labs/codex/coder"
|
||||
version = "5.0.0"
|
||||
version = "5.1.0"
|
||||
agent_id = coder_agent.main.id
|
||||
workdir = local.codex_workdir
|
||||
openai_api_key = var.openai_api_key
|
||||
@@ -64,7 +64,7 @@ resource "coder_app" "codex" {
|
||||
```tf
|
||||
module "codex" {
|
||||
source = "registry.coder.com/coder-labs/codex/coder"
|
||||
version = "5.0.0"
|
||||
version = "5.1.0"
|
||||
agent_id = coder_agent.main.id
|
||||
workdir = "/home/coder/project"
|
||||
enable_ai_gateway = true
|
||||
@@ -88,7 +88,7 @@ When `enable_ai_gateway = true`, the module configures Codex to use the `aigatew
|
||||
```tf
|
||||
module "codex" {
|
||||
source = "registry.coder.com/coder-labs/codex/coder"
|
||||
version = "5.0.0"
|
||||
version = "5.1.0"
|
||||
agent_id = coder_agent.main.id
|
||||
workdir = "/home/coder/project"
|
||||
openai_api_key = var.openai_api_key
|
||||
@@ -117,7 +117,7 @@ The module exposes the `scripts` output: an ordered list of `coder exp sync` nam
|
||||
```tf
|
||||
module "codex" {
|
||||
source = "registry.coder.com/coder-labs/codex/coder"
|
||||
version = "5.0.0"
|
||||
version = "5.1.0"
|
||||
agent_id = coder_agent.main.id
|
||||
openai_api_key = var.openai_api_key
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ describe("codex", async () => {
|
||||
});
|
||||
|
||||
test("install-codex-version", async () => {
|
||||
const version = "0.10.0";
|
||||
const version = "0.134.0";
|
||||
const { id, coderEnvVars, scripts } = await setup({
|
||||
skipCodexMock: true,
|
||||
moduleVariables: {
|
||||
|
||||
@@ -137,7 +137,7 @@ locals {
|
||||
EOF
|
||||
install_script = templatefile("${path.module}/scripts/install.sh.tftpl", {
|
||||
ARG_INSTALL = tostring(var.install_codex)
|
||||
ARG_CODEX_VERSION = var.codex_version != "" ? base64encode(var.codex_version) : ""
|
||||
ARG_CODEX_VERSION = var.codex_version
|
||||
ARG_WORKDIR = local.workdir != "" ? base64encode(local.workdir) : ""
|
||||
ARG_BASE_CONFIG_TOML = var.base_config_toml != "" ? base64encode(var.base_config_toml) : ""
|
||||
ARG_MCP = var.mcp != "" ? base64encode(var.mcp) : ""
|
||||
|
||||
@@ -9,7 +9,7 @@ command_exists() {
|
||||
}
|
||||
|
||||
ARG_INSTALL='${ARG_INSTALL}'
|
||||
ARG_CODEX_VERSION=$(echo -n '${ARG_CODEX_VERSION}' | base64 -d)
|
||||
ARG_CODEX_VERSION='${ARG_CODEX_VERSION}'
|
||||
ARG_WORKDIR=$(echo -n '${ARG_WORKDIR}' | base64 -d)
|
||||
ARG_BASE_CONFIG_TOML=$(echo -n '${ARG_BASE_CONFIG_TOML}' | base64 -d)
|
||||
ARG_MCP=$(echo -n '${ARG_MCP}' | base64 -d)
|
||||
@@ -51,8 +51,6 @@ function ensure_codex_in_path() {
|
||||
local CODEX_BIN=""
|
||||
if command -v codex > /dev/null 2>&1; then
|
||||
CODEX_BIN=$(command -v codex)
|
||||
elif [ -x "$HOME/.npm-global/bin/codex" ]; then
|
||||
CODEX_BIN="$HOME/.npm-global/bin/codex"
|
||||
fi
|
||||
|
||||
if [ -z "$${CODEX_BIN}" ] || [ ! -x "$${CODEX_BIN}" ]; then
|
||||
@@ -78,35 +76,9 @@ function install_codex() {
|
||||
return
|
||||
fi
|
||||
|
||||
if [ -s "$HOME/.nvm/nvm.sh" ]; then
|
||||
export NVM_DIR="$HOME/.nvm"
|
||||
. "$NVM_DIR/nvm.sh"
|
||||
fi
|
||||
|
||||
# Detect a package manager for global installs.
|
||||
if command_exists npm; then
|
||||
PKG_INSTALL="npm install -g"
|
||||
if ! command_exists nvm; then
|
||||
mkdir -p "$HOME/.npm-global"
|
||||
npm config set prefix "$HOME/.npm-global"
|
||||
export PATH="$HOME/.npm-global/bin:$PATH"
|
||||
fi
|
||||
elif command_exists pnpm; then
|
||||
PKG_INSTALL="pnpm add -g"
|
||||
elif command_exists bun; then
|
||||
PKG_INSTALL="bun add -g"
|
||||
else
|
||||
echo "Error: npm, pnpm, or bun is required to install Codex. Install one of them first or set install_codex = false."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
printf "%s Installing Codex CLI\n" "$${BOLD}"
|
||||
|
||||
if [ -n "$${ARG_CODEX_VERSION}" ]; then
|
||||
$PKG_INSTALL "@openai/codex@$${ARG_CODEX_VERSION}"
|
||||
else
|
||||
$PKG_INSTALL "@openai/codex"
|
||||
fi
|
||||
curl -fsSL https://chatgpt.com/codex/install.sh | CODEX_RELEASE="$${ARG_CODEX_VERSION}" CODEX_NON_INTERACTIVE=1 sh
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
printf "%s Installed Codex CLI: %s\n" "$${BOLD}" "$(codex --version)"
|
||||
ensure_codex_in_path
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ Under the hood, this module uses the [coder dotfiles](https://coder.com/docs/v2/
|
||||
module "dotfiles" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/dotfiles/coder"
|
||||
version = "1.4.1"
|
||||
version = "1.4.2"
|
||||
agent_id = coder_agent.example.id
|
||||
}
|
||||
```
|
||||
@@ -31,7 +31,7 @@ module "dotfiles" {
|
||||
module "dotfiles" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/dotfiles/coder"
|
||||
version = "1.4.1"
|
||||
version = "1.4.2"
|
||||
agent_id = coder_agent.example.id
|
||||
}
|
||||
```
|
||||
@@ -42,7 +42,7 @@ module "dotfiles" {
|
||||
module "dotfiles" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/dotfiles/coder"
|
||||
version = "1.4.1"
|
||||
version = "1.4.2"
|
||||
agent_id = coder_agent.example.id
|
||||
user = "root"
|
||||
}
|
||||
@@ -54,14 +54,14 @@ module "dotfiles" {
|
||||
module "dotfiles" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/dotfiles/coder"
|
||||
version = "1.4.1"
|
||||
version = "1.4.2"
|
||||
agent_id = coder_agent.example.id
|
||||
}
|
||||
|
||||
module "dotfiles-root" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/dotfiles/coder"
|
||||
version = "1.4.1"
|
||||
version = "1.4.2"
|
||||
agent_id = coder_agent.example.id
|
||||
user = "root"
|
||||
dotfiles_uri = module.dotfiles.dotfiles_uri
|
||||
@@ -90,7 +90,7 @@ You can set a default dotfiles repository for all users by setting the `default_
|
||||
module "dotfiles" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/dotfiles/coder"
|
||||
version = "1.4.1"
|
||||
version = "1.4.2"
|
||||
agent_id = coder_agent.example.id
|
||||
default_dotfiles_uri = "https://github.com/coder/dotfiles"
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { describe, expect, it } from "bun:test";
|
||||
import {
|
||||
findResourceInstance,
|
||||
runTerraformApply,
|
||||
runTerraformInit,
|
||||
testRequiredVariables,
|
||||
} from "~test";
|
||||
import { readableStreamToText, spawn } from "bun";
|
||||
|
||||
describe("dotfiles", async () => {
|
||||
await runTerraformInit(import.meta.dir);
|
||||
@@ -34,6 +36,24 @@ describe("dotfiles", async () => {
|
||||
dotfiles_uri: url,
|
||||
});
|
||||
expect(state.outputs.dotfiles_uri.value).toBe(url);
|
||||
|
||||
// Run the rendered shell script to verify the shell-side URI
|
||||
// validation also accepts the URL. The script will fail later
|
||||
// (no coder binary available), but it must not fail at the
|
||||
// URI validation step.
|
||||
const instance = findResourceInstance(state, "coder_script");
|
||||
const proc = spawn(["bash", "-c", instance.script], {
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
});
|
||||
const stderr = await readableStreamToText(proc.stderr);
|
||||
await proc.exited;
|
||||
expect(stderr).not.toContain(
|
||||
"ERROR: DOTFILES_URI contains invalid characters",
|
||||
);
|
||||
expect(stderr).not.toContain(
|
||||
"ERROR: DOTFILES_URI must be a valid repository URL",
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ DOTFILES_BRANCH="${DOTFILES_BRANCH}"
|
||||
# Validate DOTFILES_URI to prevent command injection (defense in depth)
|
||||
if [ -n "$DOTFILES_URI" ]; then
|
||||
# shellcheck disable=SC2250
|
||||
if [[ "$DOTFILES_URI" =~ [^a-zA-Z0-9._/:@-] ]]; then
|
||||
if [[ "$DOTFILES_URI" =~ [^a-zA-Z0-9._/:@~-] ]]; then
|
||||
echo "ERROR: DOTFILES_URI contains invalid characters" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user