Skip to content

Commit a7a4ae4

Browse files
authored
Merge branch 'main' into aws-cli-module
2 parents be4dc93 + 73a92be commit a7a4ae4

File tree

11 files changed

+116
-32
lines changed

11 files changed

+116
-32
lines changed

.github/workflows/ci.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ jobs:
8282
- name: Validate formatting
8383
run: bun fmt:ci
8484
- name: Check for typos
85-
uses: crate-ci/typos@v1.39.0
85+
uses: crate-ci/typos@v1.39.2
8686
with:
8787
config: .github/typos.toml
8888
validate-readme-files:

registry/coder/modules/claude-code/README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Run the [Claude Code](https://docs.anthropic.com/en/docs/agents-and-tools/claude
1313
```tf
1414
module "claude-code" {
1515
source = "registry.coder.com/coder/claude-code/coder"
16-
version = "4.0.1"
16+
version = "4.2.0"
1717
agent_id = coder_agent.example.id
1818
workdir = "/home/coder/project"
1919
claude_api_key = "xxxx-xxxxx-xxxx"
@@ -70,7 +70,7 @@ data "coder_parameter" "ai_prompt" {
7070
7171
module "claude-code" {
7272
source = "registry.coder.com/coder/claude-code/coder"
73-
version = "4.0.1"
73+
version = "4.2.0"
7474
agent_id = coder_agent.example.id
7575
workdir = "/home/coder/project"
7676
@@ -106,7 +106,7 @@ Run and configure Claude Code as a standalone CLI in your workspace.
106106
```tf
107107
module "claude-code" {
108108
source = "registry.coder.com/coder/claude-code/coder"
109-
version = "4.0.1"
109+
version = "4.2.0"
110110
agent_id = coder_agent.example.id
111111
workdir = "/home/coder"
112112
install_claude_code = true
@@ -129,7 +129,7 @@ variable "claude_code_oauth_token" {
129129
130130
module "claude-code" {
131131
source = "registry.coder.com/coder/claude-code/coder"
132-
version = "4.0.1"
132+
version = "4.2.0"
133133
agent_id = coder_agent.example.id
134134
workdir = "/home/coder/project"
135135
claude_code_oauth_token = var.claude_code_oauth_token
@@ -202,7 +202,7 @@ resource "coder_env" "bedrock_api_key" {
202202
203203
module "claude-code" {
204204
source = "registry.coder.com/coder/claude-code/coder"
205-
version = "4.0.1"
205+
version = "4.2.0"
206206
agent_id = coder_agent.example.id
207207
workdir = "/home/coder/project"
208208
model = "global.anthropic.claude-sonnet-4-5-20250929-v1:0"
@@ -259,7 +259,7 @@ resource "coder_env" "google_application_credentials" {
259259
260260
module "claude-code" {
261261
source = "registry.coder.com/coder/claude-code/coder"
262-
version = "4.0.1"
262+
version = "4.2.0"
263263
agent_id = coder_agent.example.id
264264
workdir = "/home/coder/project"
265265
model = "claude-sonnet-4@20250514"

registry/coder/modules/claude-code/main.tf

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,12 @@ variable "claude_code_version" {
114114
default = "latest"
115115
}
116116

117+
variable "disable_autoupdater" {
118+
type = bool
119+
description = "Disable Claude Code automatic updates. When true, Claude Code will stay on the installed version."
120+
default = false
121+
}
122+
117123
variable "claude_api_key" {
118124
type = string
119125
description = "The API key to use for the Claude Code server."
@@ -240,6 +246,12 @@ variable "boundary_pprof_port" {
240246
default = "6067"
241247
}
242248

249+
variable "compile_boundary_from_source" {
250+
type = bool
251+
description = "Whether to compile boundary from source instead of using the official install script"
252+
default = false
253+
}
254+
243255
resource "coder_env" "claude_code_md_path" {
244256
count = var.claude_md_path == "" ? 0 : 1
245257

@@ -268,6 +280,14 @@ resource "coder_env" "claude_api_key" {
268280
value = var.claude_api_key
269281
}
270282

283+
resource "coder_env" "disable_autoupdater" {
284+
count = var.disable_autoupdater ? 1 : 0
285+
286+
agent_id = var.agent_id
287+
name = "DISABLE_AUTOUPDATER"
288+
value = "1"
289+
}
290+
271291
locals {
272292
# we have to trim the slash because otherwise coder exp mcp will
273293
# set up an invalid claude config
@@ -357,6 +377,7 @@ module "agentapi" {
357377
ARG_BOUNDARY_PROXY_PORT='${var.boundary_proxy_port}' \
358378
ARG_ENABLE_BOUNDARY_PPROF='${var.enable_boundary_pprof}' \
359379
ARG_BOUNDARY_PPROF_PORT='${var.boundary_pprof_port}' \
380+
ARG_COMPILE_FROM_SOURCE='${var.compile_boundary_from_source}' \
360381
ARG_CODER_HOST='${local.coder_host}' \
361382
/tmp/start.sh
362383
EOT

registry/coder/modules/claude-code/scripts/start.sh

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ ARG_BOUNDARY_LOG_LEVEL=${ARG_BOUNDARY_LOG_LEVEL:-"WARN"}
2828
ARG_BOUNDARY_PROXY_PORT=${ARG_BOUNDARY_PROXY_PORT:-"8087"}
2929
ARG_ENABLE_BOUNDARY_PPROF=${ARG_ENABLE_BOUNDARY_PPROF:-false}
3030
ARG_BOUNDARY_PPROF_PORT=${ARG_BOUNDARY_PPROF_PORT:-"6067"}
31+
ARG_COMPILE_FROM_SOURCE=${ARG_COMPILE_FROM_SOURCE:-false}
3132
ARG_CODER_HOST=${ARG_CODER_HOST:-}
3233

3334
echo "--------------------------------"
@@ -45,6 +46,7 @@ printf "ARG_BOUNDARY_VERSION: %s\n" "$ARG_BOUNDARY_VERSION"
4546
printf "ARG_BOUNDARY_LOG_DIR: %s\n" "$ARG_BOUNDARY_LOG_DIR"
4647
printf "ARG_BOUNDARY_LOG_LEVEL: %s\n" "$ARG_BOUNDARY_LOG_LEVEL"
4748
printf "ARG_BOUNDARY_PROXY_PORT: %s\n" "$ARG_BOUNDARY_PROXY_PORT"
49+
printf "ARG_COMPILE_FROM_SOURCE: %s\n" "$ARG_COMPILE_FROM_SOURCE"
4850
printf "ARG_CODER_HOST: %s\n" "$ARG_CODER_HOST"
4951

5052
echo "--------------------------------"
@@ -63,11 +65,25 @@ case $session_cleanup_exit_code in
6365
esac
6466

6567
function install_boundary() {
66-
# Install boundary from public github repo
67-
git clone https://github.com/coder/boundary
68-
cd boundary
69-
git checkout $ARG_BOUNDARY_VERSION
70-
go install ./cmd/...
68+
if [ "${ARG_COMPILE_FROM_SOURCE:-false}" = "true" ]; then
69+
# Install boundary by compiling from source
70+
echo "Compiling boundary from source (version: $ARG_BOUNDARY_VERSION)"
71+
git clone https://github.com/coder/boundary.git
72+
cd boundary
73+
git checkout "$ARG_BOUNDARY_VERSION"
74+
75+
# Build the binary
76+
make build
77+
78+
# Install binary and wrapper script (optional)
79+
sudo cp boundary /usr/local/bin/
80+
sudo cp scripts/boundary-wrapper.sh /usr/local/bin/boundary-run
81+
sudo chmod +x /usr/local/bin/boundary-run
82+
else
83+
# Install boundary using official install script
84+
echo "Installing boundary using official install script (version: $ARG_BOUNDARY_VERSION)"
85+
curl -fsSL https://raw.githubusercontent.com/coder/boundary/main/install.sh | bash -s -- --version "$ARG_BOUNDARY_VERSION"
86+
fi
7187
}
7288

7389
function validate_claude_installation() {
@@ -209,9 +225,8 @@ function start_agentapi() {
209225
BOUNDARY_ARGS+=(--pprof-port ${ARG_BOUNDARY_PPROF_PORT})
210226
fi
211227

212-
agentapi server --allowed-hosts="*" --type claude --term-width 67 --term-height 1190 -- \
213-
sudo -E env PATH=$PATH setpriv --reuid=$(id -u) --regid=$(id -g) --clear-groups \
214-
--inh-caps=+net_admin --ambient-caps=+net_admin --bounding-set=+net_admin boundary "${BOUNDARY_ARGS[@]}" -- \
228+
agentapi server --type claude --term-width 67 --term-height 1190 -- \
229+
boundary-run "${BOUNDARY_ARGS[@]}" -- \
215230
claude "${ARGS[@]}"
216231
else
217232
agentapi server --type claude --term-width 67 --term-height 1190 -- claude "${ARGS[@]}"

registry/coder/modules/jfrog-oauth/README.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Install the JF CLI and authenticate package managers with Artifactory using OAut
1616
module "jfrog" {
1717
count = data.coder_workspace.me.start_count
1818
source = "registry.coder.com/coder/jfrog-oauth/coder"
19-
version = "1.2.0"
19+
version = "1.2.2"
2020
agent_id = coder_agent.example.id
2121
jfrog_url = "https://example.jfrog.io"
2222
username_field = "username" # If you are using GitHub to login to both Coder and Artifactory, use username_field = "username"
@@ -39,6 +39,15 @@ module "jfrog" {
3939

4040
This module is usable by JFrog self-hosted (on-premises) Artifactory as it requires configuring a custom integration. This integration benefits from Coder's [external-auth](https://coder.com/docs/v2/latest/admin/external-auth) feature and allows each user to authenticate with Artifactory using an OAuth flow and issues user-scoped tokens to each user. For configuration instructions, see this [guide](https://coder.com/docs/v2/latest/guides/artifactory-integration#jfrog-oauth) on the Coder documentation.
4141

42+
## Username Handling
43+
44+
The module automatically extracts your JFrog username directly from the OAuth token's JWT payload. This preserves special characters like dots (`.`), hyphens (`-`), and accented characters that Coder normalizes in usernames.
45+
46+
**Priority order:**
47+
48+
1. **JWT extraction** (default) - Extracts username from OAuth token, preserving special characters
49+
2. **Fallback to `username_field`** - If JWT extraction fails, uses Coder username or email
50+
4251
## Examples
4352

4453
Configure the Python pip package manager to fetch packages from Artifactory while mapping the Coder email to the Artifactory username.
@@ -47,7 +56,7 @@ Configure the Python pip package manager to fetch packages from Artifactory whil
4756
module "jfrog" {
4857
count = data.coder_workspace.me.start_count
4958
source = "registry.coder.com/coder/jfrog-oauth/coder"
50-
version = "1.2.0"
59+
version = "1.2.2"
5160
agent_id = coder_agent.example.id
5261
jfrog_url = "https://example.jfrog.io"
5362
username_field = "email"
@@ -76,7 +85,7 @@ The [JFrog extension](https://open-vsx.org/extension/JFrog/jfrog-vscode-extensio
7685
module "jfrog" {
7786
count = data.coder_workspace.me.start_count
7887
source = "registry.coder.com/coder/jfrog-oauth/coder"
79-
version = "1.2.0"
88+
version = "1.2.2"
8089
agent_id = coder_agent.example.id
8190
jfrog_url = "https://example.jfrog.io"
8291
username_field = "username" # If you are using GitHub to login to both Coder and Artifactory, use username_field = "username"

registry/coder/modules/jfrog-oauth/main.test.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,9 +159,13 @@ EOF`;
159159

160160
const coderScript = findResourceInstance(state, "coder_script");
161161

162-
expect(coderScript.script).toContain(
163-
'jf mvnc --global --repo-resolve "central"',
164-
);
162+
expect(coderScript.script).toContain("jf mvnc --global");
163+
expect(coderScript.script).toContain('--server-id-resolve="0"');
164+
expect(coderScript.script).toContain('--repo-resolve-releases "central"');
165+
expect(coderScript.script).toContain('--repo-resolve-snapshots "central"');
166+
expect(coderScript.script).toContain('--server-id-deploy="0"');
167+
expect(coderScript.script).toContain('--repo-deploy-releases "central"');
168+
expect(coderScript.script).toContain('--repo-deploy-snapshots "central"');
165169

166170
expect(coderScript.script).toContain("<servers>");
167171
expect(coderScript.script).toContain("<id>central</id>");

registry/coder/modules/jfrog-oauth/main.tf

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,27 @@ variable "package_managers" {
7676
}
7777

7878
locals {
79-
# The username field to use for artifactory
80-
username = var.username_field == "email" ? data.coder_workspace_owner.me.email : data.coder_workspace_owner.me.name
79+
jwt_parts = try(split(".", data.coder_external_auth.jfrog.access_token), [])
80+
jwt_payload = try(local.jwt_parts[1], "")
81+
payload_padding = local.jwt_payload == "" ? "" : (
82+
length(local.jwt_payload) % 4 == 0 ? "" :
83+
length(local.jwt_payload) % 4 == 2 ? "==" :
84+
length(local.jwt_payload) % 4 == 3 ? "=" :
85+
""
86+
)
87+
88+
jwt_username = try(
89+
regex(
90+
"/users/([^/]+)",
91+
jsondecode(base64decode("${local.jwt_payload}${local.payload_padding}"))["sub"]
92+
)[0],
93+
""
94+
)
95+
96+
username = coalesce(
97+
local.jwt_username != "" ? local.jwt_username : null,
98+
var.username_field == "email" ? data.coder_workspace_owner.me.email : data.coder_workspace_owner.me.name
99+
)
81100
jfrog_host = split("://", var.jfrog_url)[1]
82101
common_values = {
83102
JFROG_URL = var.jfrog_url

registry/coder/modules/jfrog-oauth/run.sh

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,13 @@ if [ -z "${HAS_MAVEN}" ]; then
9999
not_configured maven
100100
else
101101
echo "☕ Configuring maven..."
102-
jf mvnc --global --repo-resolve "${REPOSITORY_MAVEN}"
102+
jf mvnc --global \
103+
--server-id-resolve="${JFROG_SERVER_ID}" \
104+
--repo-resolve-releases "${REPOSITORY_MAVEN}" \
105+
--repo-resolve-snapshots "${REPOSITORY_MAVEN}" \
106+
--server-id-deploy="${JFROG_SERVER_ID}" \
107+
--repo-deploy-releases "${REPOSITORY_MAVEN}" \
108+
--repo-deploy-snapshots "${REPOSITORY_MAVEN}"
103109
# Create Maven config directory if it doesn't exist
104110
mkdir -p ~/.m2
105111
cat << EOF > ~/.m2/settings.xml

registry/coder/modules/jfrog-token/README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Install the JF CLI and authenticate package managers with Artifactory using Arti
1313
```tf
1414
module "jfrog" {
1515
source = "registry.coder.com/coder/jfrog-token/coder"
16-
version = "1.2.0"
16+
version = "1.2.1"
1717
agent_id = coder_agent.example.id
1818
jfrog_url = "https://XXXX.jfrog.io"
1919
artifactory_access_token = var.artifactory_access_token
@@ -42,7 +42,7 @@ For detailed instructions, please see this [guide](https://coder.com/docs/v2/lat
4242
```tf
4343
module "jfrog" {
4444
source = "registry.coder.com/coder/jfrog-token/coder"
45-
version = "1.2.0"
45+
version = "1.2.1"
4646
agent_id = coder_agent.example.id
4747
jfrog_url = "https://YYYY.jfrog.io"
4848
artifactory_access_token = var.artifactory_access_token # An admin access token
@@ -81,7 +81,7 @@ The [JFrog extension](https://open-vsx.org/extension/JFrog/jfrog-vscode-extensio
8181
```tf
8282
module "jfrog" {
8383
source = "registry.coder.com/coder/jfrog-token/coder"
84-
version = "1.2.0"
84+
version = "1.2.1"
8585
agent_id = coder_agent.example.id
8686
jfrog_url = "https://XXXX.jfrog.io"
8787
artifactory_access_token = var.artifactory_access_token
@@ -101,7 +101,7 @@ data "coder_workspace" "me" {}
101101
102102
module "jfrog" {
103103
source = "registry.coder.com/coder/jfrog-token/coder"
104-
version = "1.2.0"
104+
version = "1.2.1"
105105
agent_id = coder_agent.example.id
106106
jfrog_url = "https://XXXX.jfrog.io"
107107
artifactory_access_token = var.artifactory_access_token

registry/coder/modules/jfrog-token/main.test.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -197,9 +197,13 @@ EOF`;
197197

198198
const coderScript = findResourceInstance(state, "coder_script");
199199

200-
expect(coderScript.script).toContain(
201-
'jf mvnc --global --repo-resolve "central"',
202-
);
200+
expect(coderScript.script).toContain("jf mvnc --global");
201+
expect(coderScript.script).toContain('--server-id-resolve="0"');
202+
expect(coderScript.script).toContain('--repo-resolve-releases "central"');
203+
expect(coderScript.script).toContain('--repo-resolve-snapshots "central"');
204+
expect(coderScript.script).toContain('--server-id-deploy="0"');
205+
expect(coderScript.script).toContain('--repo-deploy-releases "central"');
206+
expect(coderScript.script).toContain('--repo-deploy-snapshots "central"');
203207

204208
expect(coderScript.script).toContain("<servers>");
205209
expect(coderScript.script).toContain("<id>central</id>");

0 commit comments

Comments
 (0)