mirror of
https://github.com/coder/registry.git
synced 2026-06-03 04:58:15 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 17705fac52 | |||
| 29743bf0da |
@@ -190,15 +190,6 @@ main() {
|
||||
|
||||
done <<< "$modules"
|
||||
|
||||
# Always run formatter to ensure consistent formatting
|
||||
echo "🔧 Running formatter to ensure consistent formatting..."
|
||||
if command -v bun >/dev/null 2>&1; then
|
||||
bun fmt >/dev/null 2>&1 || echo "⚠️ Warning: bun fmt failed, but continuing..."
|
||||
else
|
||||
echo "⚠️ Warning: bun not found, skipping formatting"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "📋 Summary:"
|
||||
echo "Bump Type: $bump_type"
|
||||
echo ""
|
||||
|
||||
@@ -3,8 +3,6 @@ name: Version Bump
|
||||
on:
|
||||
pull_request:
|
||||
types: [labeled]
|
||||
paths:
|
||||
- "registry/**/modules/**"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
@@ -15,9 +13,8 @@ jobs:
|
||||
if: github.event.label.name == 'version:patch' || github.event.label.name == 'version:minor' || github.event.label.name == 'version:major'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
contents: write
|
||||
pull-requests: write
|
||||
issues: write
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
@@ -25,96 +22,195 @@ jobs:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
bun-version: latest
|
||||
|
||||
- name: Set up Terraform
|
||||
uses: coder/coder/.github/actions/setup-tf@main
|
||||
|
||||
- name: Install dependencies
|
||||
run: bun install
|
||||
|
||||
- name: Extract bump type from label
|
||||
id: bump-type
|
||||
- name: Setup Git
|
||||
run: |
|
||||
case "${{ github.event.label.name }}" in
|
||||
"version:patch")
|
||||
echo "type=patch" >> $GITHUB_OUTPUT
|
||||
;;
|
||||
"version:minor")
|
||||
echo "type=minor" >> $GITHUB_OUTPUT
|
||||
;;
|
||||
"version:major")
|
||||
echo "type=major" >> $GITHUB_OUTPUT
|
||||
;;
|
||||
*)
|
||||
echo "Invalid version label: ${{ github.event.label.name }}"
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
- name: Detect version bump type
|
||||
id: version-type
|
||||
run: |
|
||||
if [[ "${{ github.event.label.name }}" == "version:patch" ]]; then
|
||||
echo "bump_type=patch" >> $GITHUB_OUTPUT
|
||||
elif [[ "${{ github.event.label.name }}" == "version:minor" ]]; then
|
||||
echo "bump_type=minor" >> $GITHUB_OUTPUT
|
||||
elif [[ "${{ github.event.label.name }}" == "version:major" ]]; then
|
||||
echo "bump_type=major" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "Invalid version label: ${{ github.event.label.name }}"
|
||||
exit 1
|
||||
fi
|
||||
- name: Detect modified modules
|
||||
id: detect-modules
|
||||
run: |
|
||||
CHANGED_FILES=$(git diff --name-only origin/main...HEAD)
|
||||
MODULES=$(echo "$CHANGED_FILES" | grep -E '^registry/[^/]+/modules/[^/]+/' | cut -d'/' -f1-4 | sort -u)
|
||||
|
||||
if [ -z "$MODULES" ]; then
|
||||
echo "No modules detected in changes"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Found modules:"
|
||||
echo "$MODULES"
|
||||
echo "modules<<EOF" >> $GITHUB_OUTPUT
|
||||
echo "$MODULES" >> $GITHUB_OUTPUT
|
||||
echo "EOF" >> $GITHUB_OUTPUT
|
||||
- name: Process version bumps
|
||||
id: process-bumps
|
||||
run: |
|
||||
BUMP_TYPE="${{ steps.version-type.outputs.bump_type }}"
|
||||
BUMPED_MODULES=""
|
||||
UPDATED_READMES=""
|
||||
UNTAGGED_MODULES=""
|
||||
|
||||
while IFS= read -r module_path; do
|
||||
if [ -z "$module_path" ]; then continue; fi
|
||||
|
||||
NAMESPACE=$(echo "$module_path" | cut -d'/' -f2)
|
||||
MODULE_NAME=$(echo "$module_path" | cut -d'/' -f4)
|
||||
|
||||
echo "Processing: $NAMESPACE/$MODULE_NAME"
|
||||
|
||||
LATEST_TAG=$(git tag -l "release/${NAMESPACE}/${MODULE_NAME}/v*" | sort -V | tail -1)
|
||||
README_PATH="$module_path/README.md"
|
||||
|
||||
if [ -z "$LATEST_TAG" ]; then
|
||||
# No tag found, check if README has version references
|
||||
if [ -f "$README_PATH" ] && grep -q 'version\s*=\s*"' "$README_PATH"; then
|
||||
# Extract version from README
|
||||
README_VERSION=$(grep 'version\s*=\s*"' "$README_PATH" | head -1 | sed 's/.*version\s*=\s*"\([^"]*\)".*/\1/')
|
||||
echo "No git tag found, but README shows version: $README_VERSION"
|
||||
|
||||
# Validate extracted version format
|
||||
if ! [[ "$README_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
echo "❌ Invalid README version format: '$README_VERSION'. Expected X.Y.Z format."
|
||||
echo "Starting from v1.0.0 instead"
|
||||
CURRENT_VERSION="1.0.0"
|
||||
else
|
||||
CURRENT_VERSION="$README_VERSION"
|
||||
UNTAGGED_MODULES="$UNTAGGED_MODULES\n- $NAMESPACE/$MODULE_NAME (README: v$README_VERSION)"
|
||||
fi
|
||||
else
|
||||
echo "No existing tags or version references found for $NAMESPACE/$MODULE_NAME, starting from v1.0.0"
|
||||
CURRENT_VERSION="1.0.0"
|
||||
fi
|
||||
else
|
||||
CURRENT_VERSION=$(echo "$LATEST_TAG" | sed 's/.*\/v//')
|
||||
echo "Found git tag: $LATEST_TAG (v$CURRENT_VERSION)"
|
||||
fi
|
||||
|
||||
echo "Current version: $CURRENT_VERSION"
|
||||
|
||||
# Validate version format (semantic versioning: X.Y.Z)
|
||||
if ! [[ "$CURRENT_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
echo "❌ Invalid version format: '$CURRENT_VERSION'. Expected X.Y.Z format."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
- name: Check version bump requirements
|
||||
id: version-check
|
||||
fi
|
||||
|
||||
IFS='.' read -r major minor patch <<< "$CURRENT_VERSION"
|
||||
|
||||
# Validate that components are numeric
|
||||
if ! [[ "$major" =~ ^[0-9]+$ ]] || ! [[ "$minor" =~ ^[0-9]+$ ]] || ! [[ "$patch" =~ ^[0-9]+$ ]]; then
|
||||
echo "❌ Version components must be numeric: major='$major' minor='$minor' patch='$patch'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "$BUMP_TYPE" in
|
||||
"patch")
|
||||
NEW_VERSION="$major.$minor.$((patch + 1))"
|
||||
;;
|
||||
"minor")
|
||||
NEW_VERSION="$major.$((minor + 1)).0"
|
||||
;;
|
||||
"major")
|
||||
NEW_VERSION="$((major + 1)).0.0"
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "New version: $NEW_VERSION"
|
||||
|
||||
if [ -f "$README_PATH" ]; then
|
||||
# Check if README contains version references for this specific module
|
||||
MODULE_SOURCE="registry.coder.com/${NAMESPACE}/${MODULE_NAME}/coder"
|
||||
if grep -q "source.*${MODULE_SOURCE}" "$README_PATH"; then
|
||||
echo "Updating version references for $NAMESPACE/$MODULE_NAME in $README_PATH"
|
||||
# Use awk to only update versions that follow the specific module source
|
||||
awk -v module_source="$MODULE_SOURCE" -v new_version="$NEW_VERSION" '
|
||||
/source.*=.*/ {
|
||||
if ($0 ~ module_source) {
|
||||
in_target_module = 1
|
||||
} else {
|
||||
in_target_module = 0
|
||||
}
|
||||
}
|
||||
/version.*=.*"/ {
|
||||
if (in_target_module) {
|
||||
gsub(/version[[:space:]]*=[[:space:]]*"[^"]*"/, "version = \"" new_version "\"")
|
||||
in_target_module = 0
|
||||
}
|
||||
}
|
||||
{ print }
|
||||
' "$README_PATH" > "${README_PATH}.tmp" && mv "${README_PATH}.tmp" "$README_PATH"
|
||||
UPDATED_READMES="$UPDATED_READMES\n- $NAMESPACE/$MODULE_NAME"
|
||||
elif grep -q 'version\s*=\s*"' "$README_PATH"; then
|
||||
echo "⚠️ Found version references but no module source match for $NAMESPACE/$MODULE_NAME"
|
||||
fi
|
||||
fi
|
||||
|
||||
BUMPED_MODULES="$BUMPED_MODULES\n- $NAMESPACE/$MODULE_NAME: v$CURRENT_VERSION → v$NEW_VERSION"
|
||||
|
||||
done <<< "${{ steps.detect-modules.outputs.modules }}"
|
||||
|
||||
echo "bumped_modules<<EOF" >> $GITHUB_OUTPUT
|
||||
echo -e "$BUMPED_MODULES" >> $GITHUB_OUTPUT
|
||||
echo "EOF" >> $GITHUB_OUTPUT
|
||||
|
||||
echo "updated_readmes<<EOF" >> $GITHUB_OUTPUT
|
||||
echo -e "$UPDATED_READMES" >> $GITHUB_OUTPUT
|
||||
echo "EOF" >> $GITHUB_OUTPUT
|
||||
|
||||
echo "untagged_modules<<EOF" >> $GITHUB_OUTPUT
|
||||
echo -e "$UNTAGGED_MODULES" >> $GITHUB_OUTPUT
|
||||
echo "EOF" >> $GITHUB_OUTPUT
|
||||
- name: Commit changes
|
||||
run: |
|
||||
output_file=$(mktemp)
|
||||
if ./.github/scripts/version-bump.sh "${{ steps.bump-type.outputs.type }}" origin/main > "$output_file" 2>&1; then
|
||||
echo "Script completed successfully"
|
||||
# Check if any README files were modified
|
||||
if git diff --quiet 'registry/*/modules/*/README.md'; then
|
||||
echo "No README changes to commit"
|
||||
else
|
||||
echo "Script failed"
|
||||
cat "$output_file"
|
||||
exit 1
|
||||
echo "Committing README changes..."
|
||||
git diff --name-only 'registry/*/modules/*/README.md'
|
||||
git add registry/*/modules/*/README.md
|
||||
git commit -m "chore: bump module versions (${{ steps.version-type.outputs.bump_type }})"
|
||||
git push
|
||||
fi
|
||||
|
||||
{
|
||||
echo "output<<EOF"
|
||||
cat "$output_file"
|
||||
echo "EOF"
|
||||
} >> $GITHUB_OUTPUT
|
||||
|
||||
cat "$output_file"
|
||||
|
||||
if git diff --quiet; then
|
||||
echo "versions_up_to_date=true" >> $GITHUB_OUTPUT
|
||||
echo "✅ All module versions are already up to date"
|
||||
else
|
||||
echo "versions_up_to_date=false" >> $GITHUB_OUTPUT
|
||||
echo "❌ Module versions need to be updated"
|
||||
echo "Files that would be changed:"
|
||||
git diff --name-only
|
||||
echo ""
|
||||
echo "Diff preview:"
|
||||
git diff
|
||||
|
||||
git checkout .
|
||||
git clean -fd
|
||||
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Comment on PR - Failure
|
||||
if: failure() && steps.version-check.outputs.versions_up_to_date == 'false'
|
||||
- name: Comment on PR
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
const output = `${{ steps.version-check.outputs.output }}`;
|
||||
const bumpType = `${{ steps.bump-type.outputs.type }}`;
|
||||
|
||||
let comment = `## ❌ Version Bump Validation Failed\n\n`;
|
||||
const bumpedModules = `${{ steps.process-bumps.outputs.bumped_modules }}`;
|
||||
const updatedReadmes = `${{ steps.process-bumps.outputs.updated_readmes }}`;
|
||||
const untaggedModules = `${{ steps.process-bumps.outputs.untagged_modules }}`;
|
||||
const bumpType = `${{ steps.version-type.outputs.bump_type }}`;
|
||||
|
||||
let comment = `## 🚀 Version Bump Summary\n\n`;
|
||||
comment += `**Bump Type:** \`${bumpType}\`\n\n`;
|
||||
comment += `Module versions need to be updated but haven't been bumped yet.\n\n`;
|
||||
comment += `**Required Actions:**\n`;
|
||||
comment += `1. Run the version bump script locally: \`./.github/scripts/version-bump.sh ${bumpType}\`\n`;
|
||||
comment += `2. Commit the changes: \`git add . && git commit -m "chore: bump module versions (${bumpType})"\`\n`;
|
||||
comment += `3. Push the changes: \`git push\`\n\n`;
|
||||
comment += `### Script Output:\n\`\`\`\n${output}\n\`\`\`\n\n`;
|
||||
comment += `> Please update the module versions and push the changes to continue.`;
|
||||
|
||||
comment += `**Modules Updated:**\n${bumpedModules}\n\n`;
|
||||
|
||||
if (updatedReadmes.trim()) {
|
||||
comment += `**READMEs Updated:**\n${updatedReadmes}\n\n`;
|
||||
}
|
||||
|
||||
if (untaggedModules.trim()) {
|
||||
comment += `⚠️ **Modules Without Git Tags:**\n${untaggedModules}\n\n`;
|
||||
comment += `> These modules were versioned based on README content. Consider creating proper release tags after merging.\n\n`;
|
||||
}
|
||||
|
||||
comment += `> Versions have been automatically updated in module READMEs where applicable.`;
|
||||
|
||||
github.rest.issues.createComment({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
body: comment
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,7 +14,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 = "1.4.0"
|
||||
version = "1.3.1"
|
||||
agent_id = coder_agent.example.id
|
||||
folder = "/home/coder"
|
||||
install_claude_code = true
|
||||
@@ -88,7 +88,7 @@ resource "coder_agent" "main" {
|
||||
module "claude-code" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/claude-code/coder"
|
||||
version = "1.4.0"
|
||||
version = "1.3.1"
|
||||
agent_id = coder_agent.example.id
|
||||
folder = "/home/coder"
|
||||
install_claude_code = true
|
||||
@@ -100,29 +100,6 @@ module "claude-code" {
|
||||
}
|
||||
```
|
||||
|
||||
## Session Persistence (Experimental)
|
||||
|
||||
Enable automatic session persistence to maintain Claude Code sessions across workspace restarts:
|
||||
|
||||
```tf
|
||||
module "claude-code" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/claude-code/coder"
|
||||
version = "1.4.0"
|
||||
agent_id = coder_agent.example.id
|
||||
folder = "/home/coder"
|
||||
install_claude_code = true
|
||||
|
||||
# Enable tmux with session persistence
|
||||
experiment_use_tmux = true
|
||||
experiment_tmux_session_persistence = true
|
||||
experiment_tmux_session_save_interval = "10" # Save every 10 minutes
|
||||
experiment_report_tasks = true
|
||||
}
|
||||
```
|
||||
|
||||
Session persistence automatically saves and restores your Claude Code environment, including working directory and command history.
|
||||
|
||||
## Run standalone
|
||||
|
||||
Run Claude Code as a standalone app in your workspace. This will install Claude Code and run it directly without using screen or any task reporting to the Coder UI.
|
||||
@@ -130,7 +107,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 = "1.4.0"
|
||||
version = "1.3.1"
|
||||
agent_id = coder_agent.example.id
|
||||
folder = "/home/coder"
|
||||
install_claude_code = true
|
||||
|
||||
@@ -84,18 +84,6 @@ variable "experiment_post_install_script" {
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "experiment_tmux_session_persistence" {
|
||||
type = bool
|
||||
description = "Whether to enable tmux session persistence across workspace restarts."
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "experiment_tmux_session_save_interval" {
|
||||
type = string
|
||||
description = "How often to save tmux sessions in minutes."
|
||||
default = "15"
|
||||
}
|
||||
|
||||
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) : ""
|
||||
@@ -110,28 +98,12 @@ resource "coder_script" "claude_code" {
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Function to check if a command exists
|
||||
command_exists() {
|
||||
command -v "$1" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
install_tmux() {
|
||||
echo "Installing tmux..."
|
||||
if command_exists apt-get; then
|
||||
sudo apt-get update && sudo apt-get install -y tmux
|
||||
elif command_exists yum; then
|
||||
sudo yum install -y tmux
|
||||
elif command_exists dnf; then
|
||||
sudo dnf install -y tmux
|
||||
elif command_exists pacman; then
|
||||
sudo pacman -S --noconfirm tmux
|
||||
elif command_exists apk; then
|
||||
sudo apk add tmux
|
||||
else
|
||||
echo "Error: Unable to install tmux automatically. Package manager not recognized."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Check if the specified folder exists
|
||||
if [ ! -d "${var.folder}" ]; then
|
||||
echo "Warning: The specified folder '${var.folder}' does not exist."
|
||||
echo "Creating the folder..."
|
||||
@@ -140,6 +112,8 @@ resource "coder_script" "claude_code" {
|
||||
mkdir -p "${var.folder}"
|
||||
echo "Folder created successfully."
|
||||
fi
|
||||
|
||||
# Run pre-install script if provided
|
||||
if [ -n "${local.encoded_pre_install_script}" ]; then
|
||||
echo "Running pre-install script..."
|
||||
echo "${local.encoded_pre_install_script}" | base64 -d > /tmp/pre_install.sh
|
||||
@@ -147,30 +121,11 @@ resource "coder_script" "claude_code" {
|
||||
/tmp/pre_install.sh
|
||||
fi
|
||||
|
||||
# Install Claude Code if enabled
|
||||
if [ "${var.install_claude_code}" = "true" ]; then
|
||||
if ! command_exists npm; then
|
||||
echo "npm not found, checking for Node.js installation..."
|
||||
if ! command_exists node; then
|
||||
echo "Node.js not found, installing Node.js via NVM..."
|
||||
export NVM_DIR="$HOME/.nvm"
|
||||
if [ ! -d "$NVM_DIR" ]; then
|
||||
mkdir -p "$NVM_DIR"
|
||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
|
||||
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
|
||||
else
|
||||
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
|
||||
fi
|
||||
|
||||
nvm install --lts
|
||||
nvm use --lts
|
||||
nvm alias default node
|
||||
|
||||
echo "Node.js installed: $(node --version)"
|
||||
echo "npm installed: $(npm --version)"
|
||||
else
|
||||
echo "Node.js is installed but npm is not available. Please install npm manually."
|
||||
exit 1
|
||||
fi
|
||||
echo "Error: npm is not installed. Please install Node.js and npm first."
|
||||
exit 1
|
||||
fi
|
||||
echo "Installing Claude Code..."
|
||||
npm install -g @anthropic-ai/claude-code@${var.claude_code_version}
|
||||
@@ -181,6 +136,7 @@ resource "coder_script" "claude_code" {
|
||||
coder exp mcp configure claude-code ${var.folder}
|
||||
fi
|
||||
|
||||
# Run post-install script if provided
|
||||
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
|
||||
@@ -188,97 +144,46 @@ resource "coder_script" "claude_code" {
|
||||
/tmp/post_install.sh
|
||||
fi
|
||||
|
||||
# Handle terminal multiplexer selection (tmux or screen)
|
||||
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."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${var.experiment_tmux_session_persistence}" = "true" ] && [ "${var.experiment_use_tmux}" != "true" ]; then
|
||||
echo "Error: Session persistence requires tmux to be enabled."
|
||||
echo "Please set experiment_use_tmux = true when using session persistence."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Run with tmux if enabled
|
||||
if [ "${var.experiment_use_tmux}" = "true" ]; then
|
||||
if ! command_exists tmux; then
|
||||
install_tmux
|
||||
fi
|
||||
|
||||
if [ "${var.experiment_tmux_session_persistence}" = "true" ]; then
|
||||
echo "Setting up tmux session persistence..."
|
||||
if ! command_exists git; then
|
||||
echo "Git not found, installing git..."
|
||||
if command_exists apt-get; then
|
||||
sudo apt-get update && sudo apt-get install -y git
|
||||
elif command_exists yum; then
|
||||
sudo yum install -y git
|
||||
elif command_exists dnf; then
|
||||
sudo dnf install -y git
|
||||
elif command_exists pacman; then
|
||||
sudo pacman -S --noconfirm git
|
||||
elif command_exists apk; then
|
||||
sudo apk add git
|
||||
else
|
||||
echo "Error: Unable to install git automatically. Package manager not recognized."
|
||||
echo "Please install git manually to enable session persistence."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
mkdir -p ~/.tmux/plugins
|
||||
if [ ! -d ~/.tmux/plugins/tpm ]; then
|
||||
git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
|
||||
fi
|
||||
|
||||
cat > ~/.tmux.conf << EOF
|
||||
# Claude Code tmux persistence configuration
|
||||
set -g @plugin 'tmux-plugins/tmux-resurrect'
|
||||
set -g @plugin 'tmux-plugins/tmux-continuum'
|
||||
|
||||
# Configure session persistence
|
||||
set -g @resurrect-processes ':all:'
|
||||
set -g @resurrect-capture-pane-contents 'on'
|
||||
set -g @resurrect-save-bash-history 'on'
|
||||
set -g @continuum-restore 'on'
|
||||
set -g @continuum-save-interval '${var.experiment_tmux_session_save_interval}'
|
||||
set -g @continuum-boot 'on'
|
||||
set -g @continuum-save-on 'on'
|
||||
|
||||
# Initialize plugin manager
|
||||
run '~/.tmux/plugins/tpm/tpm'
|
||||
EOF
|
||||
|
||||
~/.tmux/plugins/tpm/scripts/install_plugins.sh
|
||||
fi
|
||||
|
||||
echo "Running Claude Code in the background with tmux..."
|
||||
|
||||
# Check if tmux is installed
|
||||
if ! command_exists tmux; then
|
||||
echo "Error: tmux is not installed. Please install tmux manually."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
touch "$HOME/.claude-code.log"
|
||||
|
||||
export LANG=en_US.UTF-8
|
||||
export LC_ALL=en_US.UTF-8
|
||||
|
||||
if [ "${var.experiment_tmux_session_persistence}" = "true" ]; then
|
||||
sleep 3
|
||||
|
||||
if ! tmux has-session -t claude-code 2>/dev/null; then
|
||||
# Only create a new session if one doesn't exist
|
||||
tmux new-session -d -s claude-code -c ${var.folder} "claude --dangerously-skip-permissions \"$CODER_MCP_CLAUDE_TASK_PROMPT\""
|
||||
fi
|
||||
else
|
||||
if ! tmux has-session -t claude-code 2>/dev/null; then
|
||||
tmux new-session -d -s claude-code -c ${var.folder} "claude --dangerously-skip-permissions \"$CODER_MCP_CLAUDE_TASK_PROMPT\""
|
||||
fi
|
||||
fi
|
||||
# Create a new tmux session in detached mode
|
||||
tmux new-session -d -s claude-code -c ${var.folder} "claude --dangerously-skip-permissions \"$CODER_MCP_CLAUDE_TASK_PROMPT\""
|
||||
|
||||
fi
|
||||
|
||||
# Run with screen if enabled
|
||||
if [ "${var.experiment_use_screen}" = "true" ]; then
|
||||
echo "Running Claude Code in the background..."
|
||||
|
||||
# Check if screen is installed
|
||||
if ! command_exists screen; then
|
||||
echo "Error: screen is not installed. Please install screen manually."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
touch "$HOME/.claude-code.log"
|
||||
|
||||
# Ensure the screenrc exists
|
||||
if [ ! -f "$HOME/.screenrc" ]; then
|
||||
echo "Creating ~/.screenrc and adding multiuser settings..." | tee -a "$HOME/.claude-code.log"
|
||||
echo -e "multiuser on\nacladd $(whoami)" > "$HOME/.screenrc"
|
||||
@@ -293,7 +198,6 @@ EOF
|
||||
echo "Adding 'acladd $(whoami)' to ~/.screenrc..." | tee -a "$HOME/.claude-code.log"
|
||||
echo "acladd $(whoami)" >> "$HOME/.screenrc"
|
||||
fi
|
||||
|
||||
export LANG=en_US.UTF-8
|
||||
export LC_ALL=en_US.UTF-8
|
||||
|
||||
@@ -303,6 +207,7 @@ EOF
|
||||
exec bash
|
||||
'
|
||||
else
|
||||
# Check if claude is installed before running
|
||||
if ! command_exists claude; then
|
||||
echo "Error: Claude Code is not installed. Please enable install_claude_code or install it manually."
|
||||
exit 1
|
||||
@@ -326,10 +231,6 @@ resource "coder_app" "claude_code" {
|
||||
if [ "${var.experiment_use_tmux}" = "true" ]; then
|
||||
if tmux has-session -t claude-code 2>/dev/null; then
|
||||
echo "Attaching to existing Claude Code tmux session." | tee -a "$HOME/.claude-code.log"
|
||||
# If Claude isn't running in the session, start it without the prompt
|
||||
if ! tmux list-panes -t claude-code -F '#{pane_current_command}' | grep -q "claude"; then
|
||||
tmux send-keys -t claude-code "cd ${var.folder} && claude -c --dangerously-skip-permissions" C-m
|
||||
fi
|
||||
tmux attach-session -t claude-code
|
||||
else
|
||||
echo "Starting a new Claude Code tmux session." | tee -a "$HOME/.claude-code.log"
|
||||
|
||||
@@ -15,7 +15,7 @@ Automatically install [Visual Studio Code Server](https://code.visualstudio.com/
|
||||
module "vscode-web" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/vscode-web/coder"
|
||||
version = "1.3.0"
|
||||
version = "1.2.0"
|
||||
agent_id = coder_agent.example.id
|
||||
accept_license = true
|
||||
}
|
||||
@@ -31,7 +31,7 @@ module "vscode-web" {
|
||||
module "vscode-web" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/vscode-web/coder"
|
||||
version = "1.3.0"
|
||||
version = "1.2.0"
|
||||
agent_id = coder_agent.example.id
|
||||
install_prefix = "/home/coder/.vscode-web"
|
||||
folder = "/home/coder"
|
||||
@@ -45,7 +45,7 @@ module "vscode-web" {
|
||||
module "vscode-web" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/vscode-web/coder"
|
||||
version = "1.3.0"
|
||||
version = "1.2.0"
|
||||
agent_id = coder_agent.example.id
|
||||
extensions = ["github.copilot", "ms-python.python", "ms-toolsai.jupyter"]
|
||||
accept_license = true
|
||||
@@ -60,7 +60,7 @@ Configure VS Code's [settings.json](https://code.visualstudio.com/docs/getstarte
|
||||
module "vscode-web" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/vscode-web/coder"
|
||||
version = "1.3.0"
|
||||
version = "1.2.0"
|
||||
agent_id = coder_agent.example.id
|
||||
extensions = ["dracula-theme.theme-dracula"]
|
||||
settings = {
|
||||
@@ -78,7 +78,7 @@ By default, this module installs the latest. To pin a specific version, retrieve
|
||||
module "vscode-web" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/vscode-web/coder"
|
||||
version = "1.3.0"
|
||||
version = "1.2.0"
|
||||
agent_id = coder_agent.example.id
|
||||
commit_id = "e54c774e0add60467559eb0d1e229c6452cf8447"
|
||||
accept_license = true
|
||||
|
||||
@@ -121,12 +121,6 @@ variable "use_cached" {
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "disable_trust" {
|
||||
type = bool
|
||||
description = "Disables workspace trust protection for VS Code Web."
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "extensions_dir" {
|
||||
type = string
|
||||
description = "Override the directory to store extensions in."
|
||||
@@ -175,7 +169,6 @@ resource "coder_script" "vscode-web" {
|
||||
SETTINGS : replace(jsonencode(var.settings), "\"", "\\\""),
|
||||
OFFLINE : var.offline,
|
||||
USE_CACHED : var.use_cached,
|
||||
DISABLE_TRUST : var.disable_trust,
|
||||
EXTENSIONS_DIR : var.extensions_dir,
|
||||
FOLDER : var.folder,
|
||||
AUTO_INSTALL_EXTENSIONS : var.auto_install_extensions,
|
||||
|
||||
@@ -16,16 +16,10 @@ if [ -n "${SERVER_BASE_PATH}" ]; then
|
||||
SERVER_BASE_PATH_ARG="--server-base-path=${SERVER_BASE_PATH}"
|
||||
fi
|
||||
|
||||
# Set disable workspace trust
|
||||
DISABLE_TRUST_ARG=""
|
||||
if [ "${DISABLE_TRUST}" = true ]; then
|
||||
DISABLE_TRUST_ARG="--disable-workspace-trust"
|
||||
fi
|
||||
|
||||
run_vscode_web() {
|
||||
echo "👷 Running $VSCODE_WEB serve-local $EXTENSION_ARG $SERVER_BASE_PATH_ARG $DISABLE_TRUST_ARG --port ${PORT} --host 127.0.0.1 --accept-server-license-terms --without-connection-token --telemetry-level ${TELEMETRY_LEVEL} in the background..."
|
||||
echo "👷 Running $VSCODE_WEB serve-local $EXTENSION_ARG $SERVER_BASE_PATH_ARG --port ${PORT} --host 127.0.0.1 --accept-server-license-terms --without-connection-token --telemetry-level ${TELEMETRY_LEVEL} in the background..."
|
||||
echo "Check logs at ${LOG_PATH}!"
|
||||
"$VSCODE_WEB" serve-local "$EXTENSION_ARG" "$SERVER_BASE_PATH_ARG" "$DISABLE_TRUST_ARG" --port "${PORT}" --host 127.0.0.1 --accept-server-license-terms --without-connection-token --telemetry-level "${TELEMETRY_LEVEL}" > "${LOG_PATH}" 2>&1 &
|
||||
"$VSCODE_WEB" serve-local "$EXTENSION_ARG" "$SERVER_BASE_PATH_ARG" --port "${PORT}" --host 127.0.0.1 --accept-server-license-terms --without-connection-token --telemetry-level "${TELEMETRY_LEVEL}" > "${LOG_PATH}" 2>&1 &
|
||||
}
|
||||
|
||||
# Check if the settings file exists...
|
||||
|
||||
@@ -16,7 +16,7 @@ Enable Remote Desktop + a web based client on Windows workspaces, powered by [de
|
||||
module "windows_rdp" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/windows-rdp/coder"
|
||||
version = "1.2.1"
|
||||
version = "1.2.0"
|
||||
agent_id = resource.coder_agent.main.id
|
||||
resource_id = resource.aws_instance.dev.id
|
||||
}
|
||||
@@ -34,7 +34,7 @@ module "windows_rdp" {
|
||||
module "windows_rdp" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/windows-rdp/coder"
|
||||
version = "1.2.1"
|
||||
version = "1.2.0"
|
||||
agent_id = resource.coder_agent.main.id
|
||||
resource_id = resource.aws_instance.dev.id
|
||||
}
|
||||
@@ -46,7 +46,7 @@ module "windows_rdp" {
|
||||
module "windows_rdp" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/windows-rdp/coder"
|
||||
version = "1.2.1"
|
||||
version = "1.2.0"
|
||||
agent_id = resource.coder_agent.main.id
|
||||
resource_id = resource.google_compute_instance.dev[0].id
|
||||
}
|
||||
@@ -58,7 +58,7 @@ module "windows_rdp" {
|
||||
module "windows_rdp" {
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "registry.coder.com/coder/windows-rdp/coder"
|
||||
version = "1.2.1"
|
||||
version = "1.2.0"
|
||||
agent_id = resource.coder_agent.main.id
|
||||
resource_id = resource.aws_instance.dev.id
|
||||
devolutions_gateway_version = "2025.1.6" # Specify a specific version
|
||||
|
||||
@@ -16,11 +16,6 @@ function Configure-RDP {
|
||||
New-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' -Name "SecurityLayer" -Value 1 -PropertyType DWORD -Force
|
||||
# Enable RDP through Windows Firewall
|
||||
Enable-NetFirewallRule -DisplayGroup "Remote Desktop"
|
||||
|
||||
# Disable UDP. It doesn't work via `coder port-forward` and is broken due to MTU issues in Coder Connect.
|
||||
# Requires a restart to take effect. c.f. https://github.com/coder/internal/issues/608#issuecomment-2965923672
|
||||
New-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services' -Name "SelectTransport" -Value 1 -PropertyType DWORD -Force
|
||||
Restart-Service -Name "TermService" -Force
|
||||
}
|
||||
|
||||
function Install-DevolutionsGateway {
|
||||
|
||||
Reference in New Issue
Block a user