mirror of
https://github.com/coder/registry.git
synced 2026-06-03 21:18:15 +00:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2b4f485d72 | |||
| 673caf2e95 | |||
| ab5ff4b4be | |||
| f5a68b500b | |||
| a5edad7f17 | |||
| fb657b875d | |||
| 016d4dc523 | |||
| c8d99cfba3 | |||
| 74c8698566 | |||
| 03333991a4 | |||
| 2b0dba4ed1 | |||
| 57c900b2c9 | |||
| 0ccee61192 | |||
| 494dc4b8a1 | |||
| 3b135ad4a4 | |||
| 258591833f | |||
| 3efc22c589 | |||
| 8ba4c323c2 |
@@ -29,7 +29,7 @@ jobs:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
- name: Authenticate with Google Cloud
|
||||
uses: google-github-actions/auth@140bb5113ffb6b65a7e9b937a81fa96cf5064462
|
||||
uses: google-github-actions/auth@b7593ed2efd1c1617e1b0254da33b86225adb2a5
|
||||
with:
|
||||
workload_identity_provider: projects/309789351055/locations/global/workloadIdentityPools/github-actions/providers/github
|
||||
service_account: registry-v2-github@coder-registry-1.iam.gserviceaccount.com
|
||||
|
||||
+16
-11
@@ -24,7 +24,7 @@ The Coder Registry is a collection of Terraform modules and templates for Coder
|
||||
|
||||
### Install Dependencies
|
||||
|
||||
Install Bun:
|
||||
Install Bun (for formatting and scripts):
|
||||
|
||||
```bash
|
||||
curl -fsSL https://bun.sh/install | bash
|
||||
@@ -124,19 +124,23 @@ This script generates:
|
||||
- Accurate description and usage examples
|
||||
- Correct icon path (usually `../../../../.icons/your-icon.svg`)
|
||||
- Proper tags that describe your module
|
||||
3. **Create `main.test.ts`** to test your module
|
||||
3. **Create at least one `.tftest.hcl`** to test your module with `terraform test`
|
||||
4. **Add any scripts** or additional files your module needs
|
||||
|
||||
### 4. Test and Submit
|
||||
|
||||
```bash
|
||||
# Test your module
|
||||
bun test -t 'module-name'
|
||||
# Test your module (from the module directory)
|
||||
terraform init -upgrade
|
||||
terraform test -verbose
|
||||
|
||||
# Or run all tests in the repo
|
||||
./scripts/terraform_test_all.sh
|
||||
|
||||
# Format code
|
||||
bun fmt
|
||||
bun run fmt
|
||||
|
||||
# Commit and create PR
|
||||
# Commit and create PR (do not push to main directly)
|
||||
git add .
|
||||
git commit -m "Add [module-name] module"
|
||||
git push origin your-branch
|
||||
@@ -335,11 +339,12 @@ coder templates push test-[template-name] -d .
|
||||
### 2. Test Your Changes
|
||||
|
||||
```bash
|
||||
# Test a specific module
|
||||
bun test -t 'module-name'
|
||||
# Test a specific module (from the module directory)
|
||||
terraform init -upgrade
|
||||
terraform test -verbose
|
||||
|
||||
# Test all modules
|
||||
bun test
|
||||
./scripts/terraform_test_all.sh
|
||||
```
|
||||
|
||||
### 3. Maintain Backward Compatibility
|
||||
@@ -388,7 +393,7 @@ Example: `https://github.com/coder/registry/compare/main...your-branch?template=
|
||||
### Every Module Must Have
|
||||
|
||||
- `main.tf` - Terraform code
|
||||
- `main.test.ts` - Working tests
|
||||
- One or more `.tftest.hcl` files - Working tests with `terraform test`
|
||||
- `README.md` - Documentation with frontmatter
|
||||
|
||||
### Every Template Must Have
|
||||
@@ -488,6 +493,6 @@ When reporting bugs, include:
|
||||
2. **No tests** or broken tests
|
||||
3. **Hardcoded values** instead of variables
|
||||
4. **Breaking changes** without defaults
|
||||
5. **Not running** `bun fmt` before submitting
|
||||
5. **Not running** formatting (`bun run fmt`) and tests (`terraform test`) before submitting
|
||||
|
||||
Happy contributing! 🚀
|
||||
|
||||
+52
-6
@@ -18,9 +18,9 @@ sudo apt install golang-go
|
||||
|
||||
Check that PRs have:
|
||||
|
||||
- [ ] All required files (`main.tf`, `main.test.ts`, `README.md`)
|
||||
- [ ] All required files (`main.tf`, `README.md`, at least one `.tftest.hcl`)
|
||||
- [ ] Proper frontmatter in README
|
||||
- [ ] Working tests (`bun test`)
|
||||
- [ ] Working tests (`terraform test`)
|
||||
- [ ] Formatted code (`bun run fmt`)
|
||||
- [ ] Avatar image for new namespaces (`avatar.png` or `avatar.svg` in `.images/`)
|
||||
|
||||
@@ -42,12 +42,58 @@ go build ./cmd/readmevalidation && ./readmevalidation
|
||||
|
||||
## Making a Release
|
||||
|
||||
### Create Release Tags
|
||||
### Automated Tag and Release Process
|
||||
|
||||
After merging a PR:
|
||||
After merging a PR, use the automated script to create and push release tags:
|
||||
|
||||
1. Get the new version from the PR (shown as `old → new`)
|
||||
2. Checkout the merge commit and create the tag:
|
||||
**Prerequisites:**
|
||||
|
||||
- Ensure all module versions are updated in their respective README files (the script uses this as the source of truth)
|
||||
- Make sure you have the necessary permissions to push tags to the repository
|
||||
|
||||
**Steps:**
|
||||
|
||||
1. **Checkout the merge commit:**
|
||||
|
||||
```bash
|
||||
git checkout MERGE_COMMIT_ID
|
||||
```
|
||||
|
||||
2. **Run the tag release script:**
|
||||
|
||||
```bash
|
||||
./scripts/tag_release.sh
|
||||
```
|
||||
|
||||
3. **Review and confirm:**
|
||||
- The script will automatically scan all modules in the registry
|
||||
- It will detect which modules need version bumps by comparing README versions to existing tags
|
||||
- A summary will be displayed showing which modules need tagging
|
||||
- Confirm the list is correct when prompted
|
||||
|
||||
4. **Automatic tagging:**
|
||||
- After confirmation, the script will automatically create all necessary release tags
|
||||
- Tags will be pushed to the remote repository
|
||||
- The script operates on the current checked-out commit
|
||||
|
||||
**Example output:**
|
||||
|
||||
```text
|
||||
🔍 Scanning all modules for missing release tags...
|
||||
|
||||
📦 coder/code-server: v4.1.2 (needs tag)
|
||||
✅ coder/dotfiles: v1.0.5 (already tagged)
|
||||
|
||||
## Tags to be created:
|
||||
- `release/coder/code-server/v4.1.2`
|
||||
|
||||
❓ Do you want to proceed with creating and pushing these release tags?
|
||||
Continue? [y/N]: y
|
||||
```
|
||||
|
||||
### Manual Process (Fallback)
|
||||
|
||||
If the automated script fails, you can manually tag and release modules:
|
||||
|
||||
```bash
|
||||
# Checkout the merge commit
|
||||
|
||||
@@ -336,12 +336,12 @@ func validateAllCoderResourceFilesOfType(resourceType string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Info(context.Background(), "rocessing README files", "num_files", len(allReadmeFiles))
|
||||
logger.Info(context.Background(), "processing README files", "num_files", len(allReadmeFiles))
|
||||
resources, err := parseCoderResourceReadmeFiles(resourceType, allReadmeFiles)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Info(context.Background(), "rocessed README files as valid Coder resources", "num_files", len(resources), "type", resourceType)
|
||||
logger.Info(context.Background(), "processed README files as valid Coder resources", "num_files", len(resources), "type", resourceType)
|
||||
|
||||
if err := validateCoderResourceRelativeURLs(resources); err != nil {
|
||||
return err
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
run "plan_with_required_vars" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
agent_id = "example-agent-id"
|
||||
}
|
||||
}
|
||||
|
||||
run "app_url_uses_port" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
agent_id = "example-agent-id"
|
||||
port = 19999
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = resource.coder_app.MODULE_NAME.url == "http://localhost:19999"
|
||||
error_message = "Expected MODULE_NAME app URL to include configured port"
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
"fmt": "bun x prettier --write **/*.sh **/*.ts **/*.md *.md && terraform fmt -recursive -diff",
|
||||
"fmt:ci": "bun x prettier --check **/*.sh **/*.ts **/*.md *.md && terraform fmt -check -recursive -diff",
|
||||
"terraform-validate": "./scripts/terraform_validate.sh",
|
||||
"test": "bun test",
|
||||
"test": "./scripts/terraform_test_all.sh",
|
||||
"update-version": "./update-version.sh"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -118,7 +118,6 @@ data "coder_workspace_preset" "default" {
|
||||
EOT
|
||||
"preview_port" = "4200"
|
||||
"container_image" = "codercom/example-universal:ubuntu"
|
||||
"jetbrains_ide" = "PY"
|
||||
}
|
||||
|
||||
# Pre-builds is a Coder Premium
|
||||
|
||||
@@ -16,7 +16,7 @@ The AgentAPI module is a building block for modules that need to run an AgentAPI
|
||||
```tf
|
||||
module "agentapi" {
|
||||
source = "registry.coder.com/coder/agentapi/coder"
|
||||
version = "1.0.2"
|
||||
version = "1.1.0"
|
||||
|
||||
agent_id = var.agent_id
|
||||
web_app_slug = local.app_slug
|
||||
|
||||
@@ -148,4 +148,92 @@ describe("agentapi", async () => {
|
||||
]);
|
||||
expect(respAgentAPI.exitCode).toBe(0);
|
||||
});
|
||||
|
||||
test("no-subdomain-base-path", async () => {
|
||||
const { id } = await setup({
|
||||
moduleVariables: {
|
||||
agentapi_subdomain: "false",
|
||||
},
|
||||
});
|
||||
|
||||
const respModuleScript = await execModuleScript(id);
|
||||
expect(respModuleScript.exitCode).toBe(0);
|
||||
|
||||
await expectAgentAPIStarted(id);
|
||||
const agentApiStartLog = await readFileContainer(
|
||||
id,
|
||||
"/home/coder/test-agentapi-start.log",
|
||||
);
|
||||
expect(agentApiStartLog).toContain("Using AGENTAPI_CHAT_BASE_PATH: /@default/default.foo/apps/agentapi-web/chat");
|
||||
});
|
||||
|
||||
test("validate-agentapi-version", async () => {
|
||||
const cases = [
|
||||
{
|
||||
moduleVariables: {
|
||||
agentapi_version: "v0.3.2",
|
||||
},
|
||||
shouldThrow: "",
|
||||
},
|
||||
{
|
||||
moduleVariables: {
|
||||
agentapi_version: "v0.3.3",
|
||||
},
|
||||
shouldThrow: "",
|
||||
},
|
||||
{
|
||||
moduleVariables: {
|
||||
agentapi_version: "v0.0.1",
|
||||
agentapi_subdomain: "false",
|
||||
},
|
||||
shouldThrow: "Running with subdomain = false is only supported by agentapi >= v0.3.3.",
|
||||
},
|
||||
{
|
||||
moduleVariables: {
|
||||
agentapi_version: "v0.3.2",
|
||||
agentapi_subdomain: "false",
|
||||
},
|
||||
shouldThrow: "Running with subdomain = false is only supported by agentapi >= v0.3.3.",
|
||||
},
|
||||
{
|
||||
moduleVariables: {
|
||||
agentapi_version: "v0.3.3",
|
||||
agentapi_subdomain: "false",
|
||||
},
|
||||
shouldThrow: "",
|
||||
},
|
||||
{
|
||||
moduleVariables: {
|
||||
agentapi_version: "v0.3.999",
|
||||
agentapi_subdomain: "false",
|
||||
},
|
||||
shouldThrow: "",
|
||||
},
|
||||
{
|
||||
moduleVariables: {
|
||||
agentapi_version: "v0.999.999",
|
||||
agentapi_subdomain: "false",
|
||||
},
|
||||
},
|
||||
{
|
||||
moduleVariables: {
|
||||
agentapi_version: "v999.999.999",
|
||||
agentapi_subdomain: "false",
|
||||
},
|
||||
},
|
||||
{
|
||||
moduleVariables: {
|
||||
agentapi_version: "arbitrary-string-bypasses-validation",
|
||||
},
|
||||
shouldThrow: "",
|
||||
}
|
||||
];
|
||||
for (const { moduleVariables, shouldThrow } of cases) {
|
||||
if (shouldThrow) {
|
||||
expect(setup({ moduleVariables: moduleVariables as Record<string, string> })).rejects.toThrow(shouldThrow);
|
||||
} else {
|
||||
expect(setup({ moduleVariables: moduleVariables as Record<string, string> })).resolves.toBeDefined();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -117,7 +117,7 @@ variable "install_agentapi" {
|
||||
variable "agentapi_version" {
|
||||
type = string
|
||||
description = "The version of AgentAPI to install."
|
||||
default = "v0.2.3"
|
||||
default = "v0.3.3"
|
||||
}
|
||||
|
||||
variable "agentapi_port" {
|
||||
@@ -126,6 +126,31 @@ variable "agentapi_port" {
|
||||
default = 3284
|
||||
}
|
||||
|
||||
locals {
|
||||
# agentapi_subdomain_false_min_version_expr matches a semantic version >= v0.3.3.
|
||||
# Initial support was added in v0.3.1 but configuration via environment variable
|
||||
# was added in v0.3.3.
|
||||
# This is unfortunately a regex because there is no builtin way to compare semantic versions in Terraform.
|
||||
# See: https://regex101.com/r/oHPyRa/1
|
||||
agentapi_subdomain_false_min_version_expr = "^v(0\\.(3\\.[3-9]|3.[1-9]\\d+|[4-9]\\.\\d+|[1-9]\\d+\\.\\d+)|[1-9]\\d*\\.\\d+\\.\\d+)$"
|
||||
}
|
||||
|
||||
variable "agentapi_subdomain" {
|
||||
type = bool
|
||||
description = "Whether to use a subdomain for AgentAPI."
|
||||
default = true
|
||||
validation {
|
||||
condition = var.agentapi_subdomain || (
|
||||
# If version doesn't look like a valid semantic version, just allow it.
|
||||
# Note that boolean operators do not short-circuit in Terraform.
|
||||
can(regex("^v\\d+\\.\\d+\\.\\d+$", var.agentapi_version)) ?
|
||||
can(regex(local.agentapi_subdomain_false_min_version_expr, var.agentapi_version)) :
|
||||
true
|
||||
)
|
||||
error_message = "Running with subdomain = false is only supported by agentapi >= v0.3.3."
|
||||
}
|
||||
}
|
||||
|
||||
variable "module_dir_name" {
|
||||
type = string
|
||||
description = "Name of the subdirectory in the home directory for module files."
|
||||
@@ -140,7 +165,14 @@ locals {
|
||||
encoded_post_install_script = var.post_install_script != null ? base64encode(var.post_install_script) : ""
|
||||
agentapi_start_script_b64 = base64encode(var.start_script)
|
||||
agentapi_wait_for_start_script_b64 = base64encode(file("${path.module}/scripts/agentapi-wait-for-start.sh"))
|
||||
main_script = file("${path.module}/scripts/main.sh")
|
||||
// Chat base path is only set if not using a subdomain.
|
||||
// NOTE:
|
||||
// - Initial support for --chat-base-path was added in v0.3.1 but configuration
|
||||
// via environment variable AGENTAPI_CHAT_BASE_PATH was added in v0.3.3.
|
||||
// - As CODER_WORKSPACE_AGENT_NAME is a recent addition we use agent ID
|
||||
// for backward compatibility.
|
||||
agentapi_chat_base_path = var.agentapi_subdomain ? "" : "/@${data.coder_workspace_owner.me.name}/${data.coder_workspace.me.name}.${var.agent_id}/apps/${var.web_app_slug}/chat"
|
||||
main_script = file("${path.module}/scripts/main.sh")
|
||||
}
|
||||
|
||||
resource "coder_script" "agentapi" {
|
||||
@@ -165,6 +197,7 @@ resource "coder_script" "agentapi" {
|
||||
ARG_WAIT_FOR_START_SCRIPT="$(echo -n '${local.agentapi_wait_for_start_script_b64}' | base64 -d)" \
|
||||
ARG_POST_INSTALL_SCRIPT="$(echo -n '${local.encoded_post_install_script}' | base64 -d)" \
|
||||
ARG_AGENTAPI_PORT='${var.agentapi_port}' \
|
||||
ARG_AGENTAPI_CHAT_BASE_PATH='${local.agentapi_chat_base_path}' \
|
||||
/tmp/main.sh
|
||||
EOT
|
||||
run_on_start = true
|
||||
@@ -178,7 +211,7 @@ resource "coder_app" "agentapi_web" {
|
||||
icon = var.web_app_icon
|
||||
order = var.web_app_order
|
||||
group = var.web_app_group
|
||||
subdomain = true
|
||||
subdomain = var.agentapi_subdomain
|
||||
healthcheck {
|
||||
url = "http://localhost:${var.agentapi_port}/status"
|
||||
interval = 3
|
||||
|
||||
@@ -13,6 +13,7 @@ START_SCRIPT="$ARG_START_SCRIPT"
|
||||
WAIT_FOR_START_SCRIPT="$ARG_WAIT_FOR_START_SCRIPT"
|
||||
POST_INSTALL_SCRIPT="$ARG_POST_INSTALL_SCRIPT"
|
||||
AGENTAPI_PORT="$ARG_AGENTAPI_PORT"
|
||||
AGENTAPI_CHAT_BASE_PATH="${ARG_AGENTAPI_CHAT_BASE_PATH:-}"
|
||||
set +o nounset
|
||||
|
||||
command_exists() {
|
||||
@@ -92,5 +93,7 @@ export LANG=en_US.UTF-8
|
||||
export LC_ALL=en_US.UTF-8
|
||||
|
||||
cd "${WORKDIR}"
|
||||
|
||||
export AGENTAPI_CHAT_BASE_PATH="${AGENTAPI_CHAT_BASE_PATH:-}"
|
||||
nohup "$module_path/scripts/agentapi-start.sh" true "${AGENTAPI_PORT}" &>"$module_path/agentapi-start.log" &
|
||||
"$module_path/scripts/agentapi-wait-for-start.sh" "${AGENTAPI_PORT}"
|
||||
|
||||
@@ -24,7 +24,16 @@ export const setupContainer = async ({
|
||||
});
|
||||
const coderScript = findResourceInstance(state, "coder_script");
|
||||
const id = await runContainer(image ?? "codercom/enterprise-node:latest");
|
||||
return { id, coderScript, cleanup: () => removeContainer(id) };
|
||||
return {
|
||||
id, coderScript, cleanup: async () => {
|
||||
if (process.env["DEBUG"] === "true" || process.env["DEBUG"] === "1" || process.env["DEBUG"] === "yes") {
|
||||
console.log(`Not removing container ${id} in debug mode`);
|
||||
console.log(`Run "docker rm -f ${id}" to remove it manually.`);
|
||||
} else {
|
||||
await removeContainer(id);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export const loadTestFile = async (
|
||||
|
||||
@@ -11,6 +11,12 @@ log_file_path="$module_path/agentapi.log"
|
||||
echo "using prompt: $use_prompt" >>/home/coder/test-agentapi-start.log
|
||||
echo "using port: $port" >>/home/coder/test-agentapi-start.log
|
||||
|
||||
AGENTAPI_CHAT_BASE_PATH="${AGENTAPI_CHAT_BASE_PATH:-}"
|
||||
if [ -n "$AGENTAPI_CHAT_BASE_PATH" ]; then
|
||||
echo "Using AGENTAPI_CHAT_BASE_PATH: $AGENTAPI_CHAT_BASE_PATH" >>/home/coder/test-agentapi-start.log
|
||||
export AGENTAPI_CHAT_BASE_PATH
|
||||
fi
|
||||
|
||||
agentapi server --port "$port" --term-width 67 --term-height 1190 -- \
|
||||
bash -c aiagent \
|
||||
>"$log_file_path" 2>&1
|
||||
|
||||
@@ -125,24 +125,7 @@ variable "ai_prompt" {
|
||||
locals {
|
||||
encoded_pre_install_script = var.experiment_pre_install_script != null ? base64encode(var.experiment_pre_install_script) : ""
|
||||
encoded_post_install_script = var.experiment_post_install_script != null ? base64encode(var.experiment_post_install_script) : ""
|
||||
# We need to use allowed tools to limit the context Amazon Q receives.
|
||||
# Amazon Q can't handle big contexts, and the `create_template_version` tool
|
||||
# has a description that's too long.
|
||||
mcp_json = <<EOT
|
||||
{
|
||||
"mcpServers": {
|
||||
"coder": {
|
||||
"command": "coder",
|
||||
"args": ["exp", "mcp", "server", "--allowed-tools", "coder_report_task"],
|
||||
"env": {
|
||||
"CODER_MCP_APP_STATUS_SLUG": "amazon-q"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
EOT
|
||||
encoded_mcp_json = base64encode(local.mcp_json)
|
||||
full_prompt = <<-EOT
|
||||
full_prompt = <<-EOT
|
||||
${var.system_prompt}
|
||||
|
||||
Your first task is:
|
||||
@@ -211,6 +194,12 @@ resource "coder_script" "amazon_q" {
|
||||
cd "$PREV_DIR"
|
||||
echo "Extracted auth tarball"
|
||||
|
||||
if [ "${var.experiment_report_tasks}" = "true" ]; then
|
||||
echo "Configuring Amazon Q to report tasks via Coder MCP..."
|
||||
q mcp add --name coder --command "coder" --args "exp,mcp,server,--allowed-tools,coder_report_task" --env "CODER_MCP_APP_STATUS_SLUG=amazon-q" --scope global --force
|
||||
echo "Added Coder MCP server to Amazon Q configuration"
|
||||
fi
|
||||
|
||||
if [ -n "${local.encoded_post_install_script}" ]; then
|
||||
echo "Running post-install script..."
|
||||
echo "${local.encoded_post_install_script}" | base64 -d > /tmp/post_install.sh
|
||||
@@ -218,13 +207,6 @@ resource "coder_script" "amazon_q" {
|
||||
/tmp/post_install.sh
|
||||
fi
|
||||
|
||||
if [ "${var.experiment_report_tasks}" = "true" ]; then
|
||||
echo "Configuring Amazon Q to report tasks via Coder MCP..."
|
||||
mkdir -p ~/.aws/amazonq
|
||||
echo "${local.encoded_mcp_json}" | base64 -d > ~/.aws/amazonq/mcp.json
|
||||
echo "Created the ~/.aws/amazonq/mcp.json configuration file"
|
||||
fi
|
||||
|
||||
if [ "${var.experiment_use_tmux}" = "true" ] && [ "${var.experiment_use_screen}" = "true" ]; then
|
||||
echo "Error: Both experiment_use_tmux and experiment_use_screen cannot be true simultaneously."
|
||||
echo "Please set only one of them to true."
|
||||
|
||||
@@ -13,7 +13,7 @@ Run the [Claude Code](https://docs.anthropic.com/en/docs/agents-and-tools/claude
|
||||
```tf
|
||||
module "claude-code" {
|
||||
source = "registry.coder.com/coder/claude-code/coder"
|
||||
version = "2.0.4"
|
||||
version = "2.0.6"
|
||||
agent_id = coder_agent.example.id
|
||||
folder = "/home/coder"
|
||||
install_claude_code = true
|
||||
@@ -84,7 +84,7 @@ resource "coder_agent" "main" {
|
||||
module "claude-code" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/claude-code/coder"
|
||||
version = "2.0.4"
|
||||
version = "2.0.6"
|
||||
agent_id = coder_agent.example.id
|
||||
folder = "/home/coder"
|
||||
install_claude_code = true
|
||||
@@ -102,7 +102,7 @@ Run Claude Code as a standalone app in your workspace. This will install Claude
|
||||
```tf
|
||||
module "claude-code" {
|
||||
source = "registry.coder.com/coder/claude-code/coder"
|
||||
version = "2.0.4"
|
||||
version = "2.0.6"
|
||||
agent_id = coder_agent.example.id
|
||||
folder = "/home/coder"
|
||||
install_claude_code = true
|
||||
|
||||
@@ -9,7 +9,6 @@ terraform {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
variable "agent_id" {
|
||||
type = string
|
||||
description = "The ID of a Coder agent."
|
||||
@@ -251,7 +250,7 @@ resource "coder_script" "claude_code" {
|
||||
resource "coder_app" "claude_code_web" {
|
||||
# use a short slug to mitigate https://github.com/coder/coder/issues/15178
|
||||
slug = local.claude_code_app_slug
|
||||
display_name = "Claude Code Webxz yoxy"
|
||||
display_name = "Claude Code Web"
|
||||
agent_id = var.agent_id
|
||||
url = "http://localhost:3284/"
|
||||
icon = var.icon
|
||||
|
||||
@@ -15,7 +15,7 @@ The devcontainers-cli module provides an easy way to install [`@devcontainers/cl
|
||||
```tf
|
||||
module "devcontainers-cli" {
|
||||
source = "registry.coder.com/coder/devcontainers-cli/coder"
|
||||
version = "1.0.31"
|
||||
version = "1.0.32"
|
||||
agent_id = coder_agent.example.id
|
||||
}
|
||||
```
|
||||
|
||||
@@ -45,6 +45,8 @@ const executeScriptInContainerWithPackageManager = async (
|
||||
|
||||
console.log(path);
|
||||
|
||||
await execContainer(id, [shell, "-c", "mkdir -p /tmp/coder-script-data"]);
|
||||
|
||||
const resp = await execContainer(
|
||||
id,
|
||||
[shell, "-c", instance.script],
|
||||
@@ -52,6 +54,8 @@ const executeScriptInContainerWithPackageManager = async (
|
||||
"--env",
|
||||
"CODER_SCRIPT_BIN_DIR=/tmp/coder-script-data/bin",
|
||||
"--env",
|
||||
"CODER_SCRIPT_DATA_DIR=/tmp/coder-script-data",
|
||||
"--env",
|
||||
`PATH=${path}:/tmp/coder-script-data/bin`,
|
||||
],
|
||||
);
|
||||
|
||||
Regular → Executable
+7
-1
@@ -1,5 +1,11 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# We want to cd into `$CODER_SCRIPT_DATA_DIR` as the current directory
|
||||
# might contain a `package.json` with `packageManager` set to something
|
||||
# other than the detected package manager. When this happens, it can
|
||||
# cause the installation to fail.
|
||||
cd "$CODER_SCRIPT_DATA_DIR"
|
||||
|
||||
# If @devcontainers/cli is already installed, we can skip
|
||||
if command -v devcontainer >/dev/null 2>&1; then
|
||||
echo "🥳 @devcontainers/cli is already installed into $(which devcontainer)!"
|
||||
@@ -34,7 +40,7 @@ install() {
|
||||
# so that the devcontainer command is available
|
||||
if [ -z "$PNPM_HOME" ]; then
|
||||
PNPM_HOME="$CODER_SCRIPT_BIN_DIR"
|
||||
export M_HOME
|
||||
export PNPM_HOME
|
||||
fi
|
||||
pnpm add -g @devcontainers/cli
|
||||
elif [ "$PACKAGE_MANAGER" = "yarn" ]; then
|
||||
|
||||
@@ -13,7 +13,7 @@ Run the [Goose](https://block.github.io/goose/) agent in your workspace to gener
|
||||
```tf
|
||||
module "goose" {
|
||||
source = "registry.coder.com/coder/goose/coder"
|
||||
version = "2.0.1"
|
||||
version = "2.1.0"
|
||||
agent_id = coder_agent.example.id
|
||||
folder = "/home/coder"
|
||||
install_goose = true
|
||||
@@ -79,7 +79,7 @@ resource "coder_agent" "main" {
|
||||
module "goose" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/goose/coder"
|
||||
version = "2.0.1"
|
||||
version = "2.1.0"
|
||||
agent_id = coder_agent.example.id
|
||||
folder = "/home/coder"
|
||||
install_goose = true
|
||||
|
||||
@@ -251,4 +251,21 @@ describe("goose", async () => {
|
||||
expect(prompt.exitCode).not.toBe(0);
|
||||
expect(prompt.stderr).toContain("No such file or directory");
|
||||
});
|
||||
|
||||
test("subdomain-false", async () => {
|
||||
const { id } = await setup({
|
||||
agentapiMockScript: await loadTestFile(
|
||||
import.meta.dir,
|
||||
"agentapi-mock-print-args.js",
|
||||
),
|
||||
moduleVariables: {
|
||||
subdomain: "false",
|
||||
},
|
||||
});
|
||||
|
||||
await execModuleScript(id);
|
||||
|
||||
const agentapiMockOutput = await readFileContainer(id, agentapiStartLog);
|
||||
expect(agentapiMockOutput).toContain("AGENTAPI_CHAT_BASE_PATH=/@default/default.foo/apps/goose/chat");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -26,7 +26,7 @@ variable "order" {
|
||||
|
||||
variable "group" {
|
||||
type = string
|
||||
description = "The name of a group that this app belongs to!"
|
||||
description = "The name of a group that this app belongs to."
|
||||
default = null
|
||||
}
|
||||
|
||||
@@ -63,7 +63,13 @@ variable "install_agentapi" {
|
||||
variable "agentapi_version" {
|
||||
type = string
|
||||
description = "The version of AgentAPI to install."
|
||||
default = "v0.2.3"
|
||||
default = "v0.3.3"
|
||||
}
|
||||
|
||||
variable "subdomain" {
|
||||
type = bool
|
||||
description = "Whether to use a subdomain for AgentAPI."
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "goose_provider" {
|
||||
@@ -133,7 +139,7 @@ EOT
|
||||
|
||||
module "agentapi" {
|
||||
source = "registry.coder.com/coder/agentapi/coder"
|
||||
version = "1.0.0"
|
||||
version = "1.1.0"
|
||||
|
||||
agent_id = var.agent_id
|
||||
web_app_slug = local.app_slug
|
||||
@@ -146,6 +152,7 @@ module "agentapi" {
|
||||
module_dir_name = local.module_dir_name
|
||||
install_agentapi = var.install_agentapi
|
||||
agentapi_version = var.agentapi_version
|
||||
agentapi_subdomain = var.subdomain
|
||||
pre_install_script = var.pre_install_script
|
||||
post_install_script = var.post_install_script
|
||||
start_script = local.start_script
|
||||
@@ -155,7 +162,7 @@ module "agentapi" {
|
||||
set -o pipefail
|
||||
|
||||
echo -n '${base64encode(local.install_script)}' | base64 -d > /tmp/install.sh
|
||||
chmod +x /tmp/install.sh
|
||||
chmod +x /tmp/install.sh
|
||||
|
||||
ARG_PROVIDER='${var.goose_provider}' \
|
||||
ARG_MODEL='${var.goose_model}' \
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
const http = require("http");
|
||||
const args = process.argv.slice(2);
|
||||
console.log(args);
|
||||
console.log(`AGENTAPI_CHAT_BASE_PATH=${process.env["AGENTAPI_CHAT_BASE_PATH"]}`);
|
||||
const port = 3284;
|
||||
|
||||
console.log(`starting server on port ${port}`);
|
||||
|
||||
@@ -14,7 +14,7 @@ This module adds JetBrains IDE buttons to launch IDEs directly from the dashboar
|
||||
module "jetbrains" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains/coder"
|
||||
version = "1.0.1"
|
||||
version = "1.0.2"
|
||||
agent_id = coder_agent.example.id
|
||||
folder = "/home/coder/project"
|
||||
}
|
||||
@@ -39,7 +39,7 @@ When `default` contains IDE codes, those IDEs are created directly without user
|
||||
module "jetbrains" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains/coder"
|
||||
version = "1.0.1"
|
||||
version = "1.0.2"
|
||||
agent_id = coder_agent.example.id
|
||||
folder = "/home/coder/project"
|
||||
default = ["PY", "IU"] # Pre-configure GoLand and IntelliJ IDEA
|
||||
@@ -52,7 +52,7 @@ module "jetbrains" {
|
||||
module "jetbrains" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains/coder"
|
||||
version = "1.0.1"
|
||||
version = "1.0.2"
|
||||
agent_id = coder_agent.example.id
|
||||
folder = "/home/coder/project"
|
||||
# Show parameter with limited options
|
||||
@@ -66,7 +66,7 @@ module "jetbrains" {
|
||||
module "jetbrains" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains/coder"
|
||||
version = "1.0.1"
|
||||
version = "1.0.2"
|
||||
agent_id = coder_agent.example.id
|
||||
folder = "/home/coder/project"
|
||||
default = ["IU", "PY"]
|
||||
@@ -81,7 +81,7 @@ module "jetbrains" {
|
||||
module "jetbrains" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains/coder"
|
||||
version = "1.0.1"
|
||||
version = "1.0.2"
|
||||
agent_id = coder_agent.example.id
|
||||
folder = "/workspace/project"
|
||||
|
||||
@@ -107,7 +107,7 @@ module "jetbrains" {
|
||||
module "jetbrains_pycharm" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/jetbrains/coder"
|
||||
version = "1.0.1"
|
||||
version = "1.0.2"
|
||||
agent_id = coder_agent.example.id
|
||||
folder = "/workspace/project"
|
||||
|
||||
|
||||
@@ -202,6 +202,7 @@ data "coder_parameter" "jetbrains_ides" {
|
||||
count = length(var.default) == 0 ? 1 : 0
|
||||
type = "list(string)"
|
||||
name = "jetbrains_ides"
|
||||
description = "Select which JetBrains IDEs to configure for use in this workspace."
|
||||
display_name = "JetBrains IDEs"
|
||||
icon = "/icon/jetbrains-toolbox.svg"
|
||||
mutable = true
|
||||
|
||||
+1
-1
@@ -247,8 +247,8 @@ export const runTerraformApply = async <TVars extends TerraformVariables>(
|
||||
"-compact-warnings",
|
||||
"-input=false",
|
||||
"-auto-approve",
|
||||
"-state",
|
||||
"-no-color",
|
||||
"-state",
|
||||
stateFile,
|
||||
],
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user