-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathintegration_test.sh
More file actions
executable file
Β·263 lines (226 loc) Β· 8.52 KB
/
integration_test.sh
File metadata and controls
executable file
Β·263 lines (226 loc) Β· 8.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
#!/usr/bin/env bash
set -euo pipefail
# Enable VERBOSE mode for troubleshooting: VERBOSE=1 ./setup-coder.sh
if [[ "${VERBOSE:-}" == "1" ]]; then
set -x
fi
SKIP_CLEANUP="${SKIP_CLEANUP:-}"
REPO_ROOT=$(git rev-parse --show-toplevel)
# Configuration with defaults
CODER_IMAGE="${CODER_IMAGE:-ghcr.io/coder/coder}"
CODER_VERSION="${CODER_VERSION:-latest}"
CODER_PORT="${CODER_PORT:-7080}"
DOCKER_GID="${DOCKER_GID:-}"
CONTAINER_NAME="coder-integration-test"
CODER_USERNAME="testuser"
CODER_EMAIL="test@example.com"
CODER_PASSWORD="testpassword123"
GITHUB_USER_ID="123456789" # Test GitHub user ID
# Use well-known postgres credentials for testing
POSTGRES_PORT="5433"
POSTGRES_PASSWORD="test-password-$(date +%s)"
# Detect Docker socket path from context
DOCKER_HOST=$(docker context inspect --format '{{.Endpoints.docker.Host}}' 2>/dev/null || echo "unix:///var/run/docker.sock")
# Extract path from unix:// URL
DOCKER_SOCKET="${DOCKER_HOST#unix://}"
# Setup postgres configuration for embedded database
# We need to pre-configure postgres port and password so we can:
# 1. Connect to the database from outside the container (for linking GitHub user ID)
# 2. Avoid random port assignment which would make connection harder
# Coder reads port/password from ~/.config/coderv2/postgres/{port,password}
# Note: Using repo directory instead of /tmp to avoid issues with Colima and similar setups
POSTGRES_CONFIG_DIR="${REPO_ROOT}/.integration.tmp"
if ! command -v curl; then
echo "curl is required to run this script"
exit 1
elif ! command -v docker; then
echo "Docker is required to run this script"
exit 1
elif ! command -v act; then
echo "nektos/act is required to run this script"
exit 1
elif ! command -v psql; then
echo "psql is required to run this script"
exit 1
fi
cleanup() {
if [[ "${SKIP_CLEANUP}" == "1" ]]; then
echo "Skipping cleanup, leaving it up to you!"
else
now=$(date +%Y%m%d%H%M%S)
log_dest="./integration_test.${now}.log"
echo "Writing Coder logs to ${log_dest}"
docker logs "${CONTAINER_NAME}" > "${log_dest}" 2>&1
docker rm -f coder-testuser-integration-test-1
docker rm -f "${CONTAINER_NAME}"
rm -rfv "${POSTGRES_CONFIG_DIR}"
fi
}
trap cleanup EXIT
echo "π Setting up ephemeral Coder deployment for integration tests"
echo " Image: ${CODER_IMAGE}:${CODER_VERSION}"
echo " Port: ${CODER_PORT}"
echo " Docker socket: ${DOCKER_SOCKET}"
# Detect Docker socket group ID
detect_docker_gid() {
if [[ -S "${DOCKER_SOCKET}" ]]; then
# Linux uses -c, macOS/BSD uses -f
stat -c '%g' "${DOCKER_SOCKET}" 2>/dev/null || \
stat -f '%g' "${DOCKER_SOCKET}" 2>/dev/null || \
echo ""
fi
}
# Use provided DOCKER_GID or auto-detect
if [[ -z "${DOCKER_GID}" ]]; then
DOCKER_GID=$(detect_docker_gid)
fi
mkdir -p "${POSTGRES_CONFIG_DIR}"
echo "${POSTGRES_PORT}" > "${POSTGRES_CONFIG_DIR}/port"
echo "${POSTGRES_PASSWORD}" > "${POSTGRES_CONFIG_DIR}/password"
echo " Postgres port: ${POSTGRES_PORT}"
echo " Postgres password: (generated)"
# Write a custom entrypoint script to write the port and password to the config directory
# This needs to be done before the container starts so that the port and password are available to the container.
# Mounting the files in directly leads to permission issues.
cat <<EOF > "${POSTGRES_CONFIG_DIR}/entrypoint.sh"
#!/bin/bash
set -euo pipefail
mkdir -p /home/coder/.config/coderv2/postgres
cp /tmp/postgres-port /home/coder/.config/coderv2/postgres/port
cp /tmp/postgres-password /home/coder/.config/coderv2/postgres/password
exec coder server "\${@}"
EOF
chmod +x "${POSTGRES_CONFIG_DIR}/entrypoint.sh"
# Pull the image and log the digest for reproducibility
echo ""
echo "π₯ Pulling Coder image..."
FULL_IMAGE="${CODER_IMAGE}:${CODER_VERSION}"
docker pull "${FULL_IMAGE}"
# Build a custom Coder image with the psql client
echo "Building custom Coder image with psql client..."
printf 'FROM %s\nUSER root\nRUN apk update && apk add postgresql-client\nUSER coder' "${FULL_IMAGE}" | docker build -t "${FULL_IMAGE}-psql" -f - .
# Get and log the image digest
IMAGE_DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' "${FULL_IMAGE}" 2>/dev/null || echo "unknown")
echo "β
Image pulled: ${FULL_IMAGE}"
echo " Digest: ${IMAGE_DIGEST}"
# Build docker run command
DOCKER_RUN_ARGS=(
--name "${CONTAINER_NAME}"
--rm -d
-p "${CODER_PORT}:7080"
-p "${POSTGRES_PORT}:${POSTGRES_PORT}"
-e CODER_HTTP_ADDRESS=0.0.0.0:7080
-e CODER_ACCESS_URL="http://localhost:${CODER_PORT}"
-e CODER_TELEMETRY_ENABLE=false
-e CODER_VERBOSE=1
-v "${DOCKER_SOCKET}:/var/run/docker.sock"
-v "${POSTGRES_CONFIG_DIR}/port:/tmp/postgres-port"
-v "${POSTGRES_CONFIG_DIR}/password:/tmp/postgres-password"
-v "${POSTGRES_CONFIG_DIR}/entrypoint.sh:/entrypoint.sh"
--entrypoint /bin/bash
)
# Add group_add if we have a Docker GID
if [[ -n "$DOCKER_GID" ]]; then
echo " Docker socket group: ${DOCKER_GID}"
DOCKER_RUN_ARGS+=(--group-add "$DOCKER_GID")
else
echo " β οΈ Could not detect Docker socket group, container may lack Docker access"
fi
# Check for a pre-existing container
if docker ps -a --format '{{.Names}}' | grep -q "${CONTAINER_NAME}"; then
echo " β οΈ Container already exists, please remove it before starting a new one"
echo " docker rm ${CONTAINER_NAME}"
exit 1
fi
# Start Coder container
echo ""
echo "π¦ Starting Coder container..."
docker run "${DOCKER_RUN_ARGS[@]}" "${FULL_IMAGE}-psql" /entrypoint.sh
# Wait for Coder to be healthy
CODER_URL="http://localhost:${CODER_PORT}"
echo ""
echo "β³ Waiting for Coder to be ready..."
MAX_ATTEMPTS=30
ATTEMPT=0
while [[ $ATTEMPT -lt $MAX_ATTEMPTS ]]; do
if curl -sSf "${CODER_URL}/healthz" >/dev/null 2>&1; then
echo "β
Coder is ready!"
break
fi
ATTEMPT=$((ATTEMPT + 1))
echo -n "."
sleep 2
done
if [[ $ATTEMPT -eq $MAX_ATTEMPTS ]]; then
echo ""
echo "β Coder failed to start within timeout"
docker logs "${CONTAINER_NAME}"
docker stop "${CONTAINER_NAME}" 2>/dev/null || true
exit 1
fi
# Create first user
echo ""
echo "π€ Creating first user..."
# Create first user and log in using coder CLI inside container
docker exec "${CONTAINER_NAME}" coder login "${CODER_URL}" \
--first-user-username "${CODER_USERNAME}" \
--first-user-email "${CODER_EMAIL}" \
--first-user-password "${CODER_PASSWORD}"
if [[ $? -ne 0 ]]; then
echo "β Failed to create user or login"
docker logs "${CONTAINER_NAME}" | tail -20
docker stop "${CONTAINER_NAME}" 2>/dev/null || true
exit 1
fi
echo "β
User created: ${CODER_USERNAME}"
# Extract session token from container
CODER_TOKEN=$(docker exec "${CONTAINER_NAME}" sh -c 'cat $HOME/.config/coderv2/session' | tr -d '\n')
if [[ -z "$CODER_TOKEN" ]]; then
echo "β Failed to extract session token from container"
docker stop "${CONTAINER_NAME}" 2>/dev/null || true
exit 1
fi
# Link GitHub user ID by updating database directly
echo ""
echo "π Linking GitHub user ID ${GITHUB_USER_ID}..."
# Update the user's github_com_user_id in the database
# Using email as the identifier since it's unique and we know it
POSTGRES_URL="postgres://coder@localhost:5433/coder?sslmode=disable&password=${POSTGRES_PASSWORD}"
echo "UPDATE users SET github_com_user_id = ${GITHUB_USER_ID} WHERE email = '${CODER_EMAIL}';" | docker exec -i "${CONTAINER_NAME}" psql "${POSTGRES_URL}"
if [[ $? -eq 0 ]]; then
echo "β
GitHub user linked"
else
echo "β οΈ Warning: Could not link GitHub user ID"
exit 1
fi
# Import template
echo ""
echo "π Importing Docker template..."
TEMPLATE_NAME="tasks-docker"
docker exec "${CONTAINER_NAME}" sh -c "
mkdir -p ./${TEMPLATE_NAME} && cd ./${TEMPLATE_NAME}
coder templates init --id ${TEMPLATE_NAME} .
terraform init
coder templates push ${TEMPLATE_NAME} --yes --directory .
"
if [[ $? -ne 0 ]]; then
echo "β Template import failed"
docker logs "${CONTAINER_NAME}" | tail -20
docker stop "${CONTAINER_NAME}" 2>/dev/null || true
exit 1
fi
echo "β
Template created: ${TEMPLATE_NAME}"
echo "Running act..."
cd "${REPO_ROOT}" && \
act issues \
--secret "CODER_URL=${CODER_URL}" \
--secret "CODER_TOKEN=${CODER_TOKEN}" \
--secret "CODER_USERNAME=${CODER_USERNAME}" \
--secret "CODER_ORGANIZATION=default" \
--secret "GITHUB_USER_ID=${GITHUB_USER_ID}" \
--secret "GITHUB_TOKEN=fake-token-for-testing" \
--workflows ./test-workflow.yml \
--eventpath ./test-event.json
if [[ $? -ne 0 ]]; then
echo "Integration test failed"
fi