Skip to content

Commit ddc5893

Browse files
committed
Merge branch 'main' into dev-container-ga
2 parents 18998b7 + 7a3a6d4 commit ddc5893

File tree

313 files changed

+10999
-11110
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

313 files changed

+10999
-11110
lines changed

.devcontainer/devcontainer.json

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,60 @@
11
{
22
"name": "Development environments on your infrastructure",
33
"image": "codercom/oss-dogfood:latest",
4-
54
"features": {
65
// See all possible options here https://github.com/devcontainers/features/tree/main/src/docker-in-docker
76
"ghcr.io/devcontainers/features/docker-in-docker:2": {
87
"moby": "false"
9-
}
8+
},
9+
"ghcr.io/coder/devcontainer-features/code-server:1": {
10+
"auth": "none",
11+
"port": 13337
12+
},
13+
"./filebrowser": {}
1014
},
1115
// SYS_PTRACE to enable go debugging
12-
"runArgs": ["--cap-add=SYS_PTRACE"],
16+
"runArgs": [
17+
"--cap-add=SYS_PTRACE"
18+
],
1319
"customizations": {
1420
"vscode": {
15-
"extensions": ["biomejs.biome"]
21+
"extensions": [
22+
"biomejs.biome"
23+
]
24+
},
25+
"coder": {
26+
"apps": [
27+
{
28+
"slug": "cursor",
29+
"displayName": "Cursor Desktop",
30+
"url": "cursor://coder.coder-remote/openDevContainer?owner=${localEnv:CODER_WORKSPACE_OWNER_NAME}&workspace=${localEnv:CODER_WORKSPACE_NAME}&agent=${localEnv:CODER_WORKSPACE_PARENT_AGENT_NAME}&url=${localEnv:CODER_URL}&token=$SESSION_TOKEN&devContainerName=${localEnv:CONTAINER_ID}&devContainerFolder=${containerWorkspaceFolder}",
31+
"external": true,
32+
"icon": "/icon/cursor.svg",
33+
"order": 1
34+
},
35+
{
36+
"slug": "windsurf",
37+
"displayName": "Windsurf Editor",
38+
"url": "windsurf://coder.coder-remote/openDevContainer?owner=${localEnv:CODER_WORKSPACE_OWNER_NAME}&workspace=${localEnv:CODER_WORKSPACE_NAME}&agent=${localEnv:CODER_WORKSPACE_PARENT_AGENT_NAME}&url=${localEnv:CODER_URL}&token=$SESSION_TOKEN&devContainerName=${localEnv:CONTAINER_ID}&devContainerFolder=${containerWorkspaceFolder}",
39+
"external": true,
40+
"icon": "/icon/windsurf.svg",
41+
"order": 4
42+
},
43+
{
44+
"slug": "zed",
45+
"displayName": "Zed Editor",
46+
"url": "zed://ssh/${localEnv:CODER_WORKSPACE_AGENT_NAME}.${localEnv:CODER_WORKSPACE_NAME}.${localEnv:CODER_WORKSPACE_OWNER_NAME}.coder/${containerWorkspaceFolder}",
47+
"external": true,
48+
"icon": "/icon/zed.svg",
49+
"order": 5
50+
}
51+
]
1652
}
17-
}
53+
},
54+
"mounts": [
55+
// Mount the entire home because conditional mounts are not supported.
56+
// See: https://github.com/devcontainers/spec/issues/132
57+
"source=${localEnv:HOME},target=/mnt/home/coder,type=bind,readonly"
58+
],
59+
"postCreateCommand": "./.devcontainer/postCreateCommand.sh"
1860
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
{
2+
"id": "filebrowser",
3+
"version": "0.0.1",
4+
"name": "File Browser",
5+
"description": "A web-based file browser for your development container",
6+
"options": {
7+
"port": {
8+
"type": "string",
9+
"default": "13339",
10+
"description": "The port to run filebrowser on"
11+
},
12+
// "folder": {
13+
// "type": "string",
14+
// "default": "${containerWorkspaceFolder}",
15+
// "description": "The root directory for filebrowser to serve"
16+
// },
17+
"auth": {
18+
"type": "string",
19+
"enum": [
20+
"none",
21+
"password"
22+
],
23+
"default": "none",
24+
"description": "Authentication method (none or password)"
25+
}
26+
},
27+
"entrypoint": "/usr/local/bin/filebrowser-entrypoint",
28+
"dependsOn": {
29+
"ghcr.io/devcontainers/features/common-utils:2": {}
30+
},
31+
"customizations": {
32+
"coder": {
33+
"apps": [
34+
{
35+
"slug": "filebrowser",
36+
"displayName": "File Browser",
37+
"url": "http://localhost:${localEnv:FEATURE_FILEBROWSER_OPTION_PORT:13339}",
38+
"icon": "/icon/filebrowser.svg",
39+
"order": 3,
40+
"subdomain": true,
41+
"healthcheck": {
42+
"url": "http://localhost:${localEnv:FEATURE_FILEBROWSER_OPTION_PORT:13339}/health",
43+
"interval": 5,
44+
"threshold": 6
45+
}
46+
}
47+
]
48+
}
49+
}
50+
}

.devcontainer/filebrowser/install.sh

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
5+
BOLD='\033[0;1m'
6+
7+
printf "%sInstalling filebrowser\n\n" "${BOLD}"
8+
9+
# Check if filebrowser is installed.
10+
if ! command -v filebrowser &>/dev/null; then
11+
curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash
12+
fi
13+
14+
printf "🥳 Installation complete!\n\n"
15+
16+
# Create run script.
17+
cat >/usr/local/bin/filebrowser-entrypoint <<EOF
18+
#!/bin/bash
19+
20+
printf "🛠️ Configuring filebrowser\n\n"
21+
22+
AUTH="${AUTH}"
23+
PORT="${PORT}"
24+
FOLDER="$(pwd)"
25+
LOG_PATH=/tmp/filebrowser.log
26+
export FB_DATABASE="/tmp/filebrowser.db"
27+
28+
# Check if filebrowser db exists.
29+
if [[ ! -f "\${FB_DATABASE}" ]]; then
30+
filebrowser config init
31+
if [[ "\$AUTH" == "password" ]]; then
32+
filebrowser users add admin admin --perm.admin=true --viewMode=mosaic
33+
fi
34+
fi
35+
36+
# Configure filebrowser.
37+
if [[ "\$AUTH" == "none" ]]; then
38+
filebrowser config set --port="\${PORT}" --auth.method=noauth --root="\${FOLDER}"
39+
else
40+
filebrowser config set --port="\${PORT}" --auth.method=json --root="\${FOLDER}"
41+
fi
42+
43+
set -euo pipefail
44+
45+
printf "👷 Starting filebrowser...\n\n"
46+
printf "📂 Serving \${FOLDER} at http://localhost:\${PORT}\n\n"
47+
48+
filebrowser >>\${LOG_PATH} 2>&1 &
49+
50+
printf "📝 Logs at \${LOG_PATH}\n\n"
51+
EOF
52+
53+
chmod +x /usr/local/bin/filebrowser-entrypoint
54+
55+
printf "✅ File Browser installed!\n\n"
56+
printf "🚀 Run 'filebrowser-entrypoint' to start the service\n\n"

.devcontainer/postCreateCommand.sh

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#!/bin/sh
2+
3+
install_ssh_config() {
4+
echo "🔑 Installing SSH configuration..."
5+
rsync -a /mnt/home/coder/.ssh/ ~/.ssh/
6+
chmod 0700 ~/.ssh
7+
}
8+
9+
install_git_config() {
10+
echo "📂 Installing Git configuration..."
11+
if [ -f /mnt/home/coder/git/config ]; then
12+
rsync -a /mnt/home/coder/git/ ~/.config/git/
13+
elif [ -d /mnt/home/coder/.gitconfig ]; then
14+
rsync -a /mnt/home/coder/.gitconfig ~/.gitconfig
15+
else
16+
echo "⚠️ Git configuration directory not found."
17+
fi
18+
}
19+
20+
install_dotfiles() {
21+
if [ ! -d /mnt/home/coder/.config/coderv2/dotfiles ]; then
22+
echo "⚠️ Dotfiles directory not found."
23+
return
24+
fi
25+
26+
cd /mnt/home/coder/.config/coderv2/dotfiles || return
27+
for script in install.sh install bootstrap.sh bootstrap script/bootstrap setup.sh setup script/setup; do
28+
if [ -x $script ]; then
29+
echo "📦 Installing dotfiles..."
30+
./$script || {
31+
echo "❌ Error running $script. Please check the script for issues."
32+
return
33+
}
34+
echo "✅ Dotfiles installed successfully."
35+
return
36+
fi
37+
done
38+
echo "⚠️ No install script found in dotfiles directory."
39+
}
40+
41+
personalize() {
42+
# Allow script to continue as Coder dogfood utilizes a hack to
43+
# synchronize startup script execution.
44+
touch /tmp/.coder-startup-script.done
45+
46+
if [ -x /mnt/home/coder/personalize ]; then
47+
echo "🎨 Personalizing environment..."
48+
/mnt/home/coder/personalize
49+
fi
50+
}
51+
52+
install_ssh_config
53+
install_dotfiles
54+
personalize

.github/.linkspector.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,6 @@ ignorePatterns:
2424
- pattern: "mutagen.io"
2525
- pattern: "docs.github.com"
2626
- pattern: "claude.ai"
27+
- pattern: "splunk.com"
2728
aliveStatusCodes:
2829
- 200
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: "Download Embedded Postgres Cache"
2+
description: |
3+
Downloads the embedded postgres cache and outputs today's cache key.
4+
A PR job can use a cache if it was created by its base branch, its current
5+
branch, or the default branch.
6+
https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/caching-dependencies-to-speed-up-workflows#restrictions-for-accessing-a-cache
7+
outputs:
8+
cache-key:
9+
description: "Today's cache key"
10+
value: ${{ steps.vars.outputs.cache-key }}
11+
inputs:
12+
key-prefix:
13+
description: "Prefix for the cache key"
14+
required: true
15+
cache-path:
16+
description: "Path to the cache directory"
17+
required: true
18+
runs:
19+
using: "composite"
20+
steps:
21+
- name: Get date values and cache key
22+
id: vars
23+
shell: bash
24+
run: |
25+
export YEAR_MONTH=$(date +'%Y-%m')
26+
export PREV_YEAR_MONTH=$(date -d 'last month' +'%Y-%m')
27+
export DAY=$(date +'%d')
28+
echo "year-month=$YEAR_MONTH" >> $GITHUB_OUTPUT
29+
echo "prev-year-month=$PREV_YEAR_MONTH" >> $GITHUB_OUTPUT
30+
echo "cache-key=${{ inputs.key-prefix }}-${YEAR_MONTH}-${DAY}" >> $GITHUB_OUTPUT
31+
32+
# By default, depot keeps caches for 14 days. This is plenty for embedded
33+
# postgres, which changes infrequently.
34+
# https://depot.dev/docs/github-actions/overview#cache-retention-policy
35+
- name: Download embedded Postgres cache
36+
uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
37+
with:
38+
path: ${{ inputs.cache-path }}
39+
key: ${{ steps.vars.outputs.cache-key }}
40+
# > If there are multiple partial matches for a restore key, the action returns the most recently created cache.
41+
# https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/caching-dependencies-to-speed-up-workflows#matching-a-cache-key
42+
# The second restore key allows non-main branches to use the cache from the previous month.
43+
# This prevents PRs from rebuilding the cache on the first day of the month.
44+
# It also makes sure that once a month, the cache is fully reset.
45+
restore-keys: |
46+
${{ inputs.key-prefix }}-${{ steps.vars.outputs.year-month }}-
47+
${{ github.ref != 'refs/heads/main' && format('{0}-{1}-', inputs.key-prefix, steps.vars.outputs.prev-year-month) || '' }}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
name: "Upload Embedded Postgres Cache"
2+
description: Uploads the embedded Postgres cache. This only runs on the main branch.
3+
inputs:
4+
cache-key:
5+
description: "Cache key"
6+
required: true
7+
cache-path:
8+
description: "Path to the cache directory"
9+
required: true
10+
runs:
11+
using: "composite"
12+
steps:
13+
- name: Upload Embedded Postgres cache
14+
if: ${{ github.ref == 'refs/heads/main' }}
15+
uses: actions/cache/save@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
16+
with:
17+
path: ${{ inputs.cache-path }}
18+
key: ${{ inputs.cache-key }}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: "Setup Embedded Postgres Cache Paths"
2+
description: Sets up a path for cached embedded postgres binaries.
3+
outputs:
4+
embedded-pg-cache:
5+
description: "Value of EMBEDDED_PG_CACHE_DIR"
6+
value: ${{ steps.paths.outputs.embedded-pg-cache }}
7+
cached-dirs:
8+
description: "directories that should be cached between CI runs"
9+
value: ${{ steps.paths.outputs.cached-dirs }}
10+
runs:
11+
using: "composite"
12+
steps:
13+
- name: Override Go paths
14+
id: paths
15+
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
16+
with:
17+
script: |
18+
const path = require('path');
19+
20+
// RUNNER_TEMP should be backed by a RAM disk on Windows if
21+
// coder/setup-ramdisk-action was used
22+
const runnerTemp = process.env.RUNNER_TEMP;
23+
const embeddedPgCacheDir = path.join(runnerTemp, 'embedded-pg-cache');
24+
core.exportVariable('EMBEDDED_PG_CACHE_DIR', embeddedPgCacheDir);
25+
core.setOutput('embedded-pg-cache', embeddedPgCacheDir);
26+
const cachedDirs = `${embeddedPgCacheDir}`;
27+
core.setOutput('cached-dirs', cachedDirs);
28+
29+
- name: Create directories
30+
shell: bash
31+
run: |
32+
set -e
33+
mkdir -p "$EMBEDDED_PG_CACHE_DIR"

.github/workflows/ci.yaml

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,17 @@ jobs:
473473
with:
474474
key-prefix: test-go-pg-${{ runner.os }}-${{ runner.arch }}
475475

476+
- name: Setup Embedded Postgres Cache Paths
477+
id: embedded-pg-cache
478+
uses: ./.github/actions/setup-embedded-pg-cache-paths
479+
480+
- name: Download Embedded Postgres Cache
481+
id: download-embedded-pg-cache
482+
uses: ./.github/actions/embedded-pg-cache/download
483+
with:
484+
key-prefix: embedded-pg-${{ runner.os }}-${{ runner.arch }}
485+
cache-path: ${{ steps.embedded-pg-cache.outputs.cached-dirs }}
486+
476487
- name: Normalize File and Directory Timestamps
477488
shell: bash
478489
# Normalize file modification timestamps so that go test can use the
@@ -497,12 +508,12 @@ jobs:
497508
# Create a temp dir on the R: ramdisk drive for Windows. The default
498509
# C: drive is extremely slow: https://github.com/actions/runner-images/issues/8755
499510
mkdir -p "R:/temp/embedded-pg"
500-
go run scripts/embedded-pg/main.go -path "R:/temp/embedded-pg"
511+
go run scripts/embedded-pg/main.go -path "R:/temp/embedded-pg" -cache "${EMBEDDED_PG_CACHE_DIR}"
501512
elif [ "${{ runner.os }}" == "macOS" ]; then
502513
# Postgres runs faster on a ramdisk on macOS too
503514
mkdir -p /tmp/tmpfs
504515
sudo mount_tmpfs -o noowners -s 8g /tmp/tmpfs
505-
go run scripts/embedded-pg/main.go -path /tmp/tmpfs/embedded-pg
516+
go run scripts/embedded-pg/main.go -path /tmp/tmpfs/embedded-pg -cache "${EMBEDDED_PG_CACHE_DIR}"
506517
elif [ "${{ runner.os }}" == "Linux" ]; then
507518
make test-postgres-docker
508519
fi
@@ -571,6 +582,14 @@ jobs:
571582
with:
572583
cache-key: ${{ steps.download-cache.outputs.cache-key }}
573584

585+
- name: Upload Embedded Postgres Cache
586+
uses: ./.github/actions/embedded-pg-cache/upload
587+
# We only use the embedded Postgres cache on macOS and Windows runners.
588+
if: runner.OS == 'macOS' || runner.OS == 'Windows'
589+
with:
590+
cache-key: ${{ steps.download-embedded-pg-cache.outputs.cache-key }}
591+
cache-path: "${{ steps.embedded-pg-cache.outputs.embedded-pg-cache }}"
592+
574593
- name: Upload test stats to Datadog
575594
timeout-minutes: 1
576595
continue-on-error: true

.github/workflows/dogfood.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,11 @@ jobs:
3535
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
3636

3737
- name: Setup Nix
38-
uses: nixbuild/nix-quick-install-action@889f3180bb5f064ee9e3201428d04ae9e41d54ad # v31
38+
uses: nixbuild/nix-quick-install-action@63ca48f939ee3b8d835f4126562537df0fee5b91 # v32
39+
with:
40+
# Pinning to 2.28 here, as Nix gets a "error: [json.exception.type_error.302] type must be array, but is string"
41+
# on version 2.29 and above.
42+
nix_version: "2.28.4"
3943

4044
- uses: nix-community/cache-nix-action@135667ec418502fa5a3598af6fb9eb733888ce6a # v6.1.3
4145
with:

0 commit comments

Comments
 (0)