Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.
| Mission control counts people's direct pushes to the default branch | 1 | #!/usr/bin/env bash |
| 2 | # End-to-end check of a self-hosted g1t: sign up, confirm the email, make a | |
| 3 | # workspace and a repository, push and clone over HTTP, open an issue, and | |
| Merge branch 'worktree-agent-aaf03bdceac799c89' | 4 | # read the code back through the site. Then the API on its own port (REST, |
| Merge branch 'worktree-agent-af58ac8933b0dd125' | 5 | # OAuth metadata and MCP, with an access token), an npm package published to |
| 6 | # the installation's registry and installed back, pull requests from a branch | |
| Merge branch 'worktree-agent-aaf03bdceac799c89' | 7 | # and from a fork merged onto main, the merge queue taking a pull request |
| 8 | # and giving it back, and every cron handler the scheduler runs. | |
| Mission control counts people's direct pushes to the default branch | 9 | # |
| 10 | # ./smoke.sh # against the compose stack's defaults | |
| 11 | # G1T_URL=http://localhost:8787 MAIL_LOG=wrangler.log ./smoke.sh | |
| 12 | # | |
| 13 | # The confirmation link is read from Mailpit (MAILPIT_URL, the default) or, | |
| Merge branch 'worktree-agent-aaf03bdceac799c89' | 14 | # with MAIL_LOG set, from a log the mail Worker printed it to. API_URL and |
| 15 | # MCP_URL are where the API is (default: G1T_URL's host on port 8789). | |
| 16 | # SCHEDULER_ONCE is the command that runs every cron once (scheduler.mjs | |
| 17 | # --once, inside the g1t container); unset, that step is skipped: | |
| 18 | # | |
| 19 | # SCHEDULER_ONCE="docker compose -f deploy/self-host/docker-compose.yml exec -T g1t \ | |
| 20 | # node deploy/self-host/scheduler.mjs --once /data/generated/schedules.json" ./smoke.sh | |
| 21 | # | |
| 22 | # (In Git Bash on Windows, start the command with `env MSYS_NO_PATHCONV=1` | |
| 23 | # so /data is not rewritten into a Windows path.) | |
| 24 | # PACK_CACHE=off skips the check that a second clone is served from the | |
| Merge branch 'worktree-agent-af58ac8933b0dd125' | 25 | # clone pack cache. PACKAGES=off skips publishing an npm package to the |
| 26 | # installation's registry and installing it back. | |
| Merge branch 'worktree-agent-aaf03bdceac799c89' | 27 | # |
| Merge branch 'worktree-agent-af58ac8933b0dd125' | 28 | # Needs curl, git and node (to read JSON), and npm for the package. |
| Mission control counts people's direct pushes to the default branch | 29 | set -euo pipefail |
| 30 | ||
| 31 | G1T_URL="${G1T_URL:-http://localhost:8787}" | |
| Merge branch 'worktree-agent-aaf03bdceac799c89' | 32 | API_URL="${API_URL:-$(node -e 'const u = new URL(process.argv[1]); u.port = "8789"; console.log(u.origin)' "$G1T_URL")}" |
| 33 | MCP_URL="${MCP_URL:-$API_URL/mcp}" | |
| Mission control counts people's direct pushes to the default branch | 34 | MAILPIT_URL="${MAILPIT_URL:-http://localhost:8025}" |
| 35 | MAIL_LOG="${MAIL_LOG:-}" | |
| Merge branch 'worktree-agent-aaf03bdceac799c89' | 36 | SCHEDULER_ONCE="${SCHEDULER_ONCE:-}" |
| 37 | # off: this installation keeps no clone packs (no PACK_STORE), so a second | |
| 38 | # clone is not checked for a kept one. | |
| 39 | PACK_CACHE="${PACK_CACHE:-on}" | |
| Merge branch 'worktree-agent-af58ac8933b0dd125' | 40 | # off: skip publishing and installing an npm package (which needs npm). |
| 41 | PACKAGES="${PACKAGES:-on}" | |
| Mission control counts people's direct pushes to the default branch | 42 | RUN="$(date +%s)" |
| 43 | USER_NAME="smoke${RUN}" | |
| 44 | EMAIL="${USER_NAME}@example.com" | |
| 45 | PASSWORD="correct-horse-${RUN}" | |
| 46 | WORKSPACE="ws${RUN}" | |
| 47 | REPO="hello" | |
| 48 | WORK="$(mktemp -d)" | |
| 49 | JAR="$WORK/cookies" | |
| 50 | trap 'rm -rf "$WORK"' EXIT | |
| 51 | ||
| 52 | step() { printf '\n== %s\n' "$*"; } | |
| 53 | fail() { printf 'FAILED: %s\n' "$*" >&2; exit 1; } | |
| 54 | ||
| 55 | # A form POST as a browser sends it, with the Origin the site checks. | |
| 56 | post() { | |
| 57 | local path="$1"; shift | |
| 58 | curl -sS -o "$WORK/body" -w '%{http_code} %{redirect_url}' -b "$JAR" -c "$JAR" \ | |
| 59 | -H "Origin: $G1T_URL" "$@" "$G1T_URL$path" | |
| 60 | } | |
| 61 | get() { | |
| 62 | curl -sS -o "$WORK/body" -w '%{http_code}' -b "$JAR" -c "$JAR" "$G1T_URL$1" | |
| 63 | } | |
| Merge branch 'worktree-agent-aaf03bdceac799c89' | 64 | # An API call with the access token: method, path, optional JSON body. The |
| 65 | # answer is in $WORK/api; the status is printed. | |
| 66 | api() { | |
| 67 | local method="$1" path="$2" body="${3:-}" | |
| 68 | local args=(-sS -o "$WORK/api" -w '%{http_code}' -X "$method" -H "Authorization: Bearer $TOKEN") | |
| 69 | [ -n "$body" ] && args+=(-H "content-type: application/json" --data "$body") | |
| 70 | curl "${args[@]}" "$API_URL$path" | |
| 71 | } | |
| 72 | # A field of the last API answer (or of FILE), by a JavaScript path: `json pull.number`. | |
| 73 | json() { | |
| 74 | node -e 'const v = process.argv[2].split(".").reduce((o, k) => o?.[k], JSON.parse(require("fs").readFileSync(process.argv[1], "utf8"))); console.log(typeof v === "object" ? JSON.stringify(v) : v ?? "")' "${2:-$WORK/api}" "$1" | |
| 75 | } | |
| 76 | # Waits for pull request $1 to have status $2. | |
| 77 | until_status() { | |
| 78 | local status="" | |
| 79 | for _ in $(seq 1 30); do | |
| 80 | [ "$(api GET "/repos/$WORKSPACE/$REPO/pulls/$1")" = 200 ] && status="$(json pull.status)" | |
| 81 | [ "$status" = "$2" ] && return 0 | |
| 82 | sleep 1 | |
| 83 | done | |
| 84 | fail "pull request #$1 is $status, not $2: $(head -c 400 "$WORK/api")" | |
| 85 | } | |
| 86 | # Whether main, cloned fresh, has a file. | |
| 87 | main_has() { | |
| 88 | rm -rf "$WORK/main" | |
| 89 | git -c credential.helper= clone -q "$G1T_URL/$WORKSPACE/$REPO.git" "$WORK/main" | |
| 90 | [ -f "$WORK/main/$1" ] | |
| 91 | } | |
| 92 | # A commit on a new branch of $1 (a clone), pushed to $2. | |
| 93 | commit_file() { | |
| 94 | local dir="$1" remote="$2" branch="$3" file="$4" | |
| 95 | ( | |
| 96 | cd "$dir" | |
| 97 | git config user.name "Smoke Test" | |
| 98 | git config user.email "$EMAIL" | |
| 99 | git config commit.gpgsign false | |
| 100 | git switch -q -c "$branch" 2>/dev/null || git switch -q "$branch" | |
| 101 | mkdir -p "$(dirname "$file")" | |
| 102 | printf 'Changed by smoke.sh on %s.\n' "$branch" > "$file" | |
| 103 | git add . && git commit -qm "Add $file" | |
| 104 | git -c credential.helper= push -q "$remote" "HEAD:$branch" | |
| 105 | ) | |
| 106 | } | |
| Mission control counts people's direct pushes to the default branch | 107 | |
| 108 | step "site answers at $G1T_URL" | |
| 109 | [ "$(get /)" = 200 ] || fail "GET / did not answer 200" | |
| 110 | ||
| 111 | step "sign up as $USER_NAME" | |
| 112 | out="$(post /register --data-urlencode "username=$USER_NAME" --data-urlencode "email=$EMAIL" --data-urlencode "password=$PASSWORD")" | |
| 113 | echo "$out" | |
| 114 | case "$out" in 30[23]*) ;; *) fail "register: $out $(head -c 300 "$WORK/body")" ;; esac | |
| 115 | # curl keeps Secure cookies only for https or localhost; carry it by hand. | |
| 116 | grep -q g1t_session "$JAR" || fail "no session cookie" | |
| 117 | ||
| 118 | step "confirm the email" | |
| 119 | link="" | |
| 120 | for _ in $(seq 1 20); do | |
| 121 | if [ -n "$MAIL_LOG" ]; then | |
| 122 | link="$(grep -ao "[a-z]*://[^ \"<]*/verify?token=[0-9a-zA-Z_-]*" "$MAIL_LOG" | tail -1 || true)" | |
| 123 | else | |
| 124 | id="$(curl -sS "$MAILPIT_URL/api/v1/search?query=to:$EMAIL" | sed -n 's/.*"ID":"\([^"]*\)".*/\1/p' | head -1)" | |
| 125 | [ -n "$id" ] && link="$(curl -sS "$MAILPIT_URL/api/v1/message/$id" | grep -ao '[a-z]*://[^ "<\\]*/verify?token=[0-9a-zA-Z_-]*' | head -1 || true)" | |
| 126 | fi | |
| 127 | [ -n "$link" ] && break | |
| 128 | sleep 1 | |
| 129 | done | |
| 130 | [ -n "$link" ] || fail "no confirmation email arrived" | |
| 131 | echo "$link" | |
| 132 | [ "$(get "/verify?${link#*\?}")" = 200 ] || fail "verify" | |
| 133 | grep -q "$USER_NAME" "$WORK/body" || fail "verify page does not name the account" | |
| 134 | ||
| 135 | step "create workspace $WORKSPACE" | |
| 136 | out="$(post /workspaces/new --data-urlencode "slug=$WORKSPACE" --data-urlencode "displayName=Smoke $RUN")" | |
| 137 | echo "$out" | |
| 138 | case "$out" in 30[23]*) ;; *) fail "workspace: $out $(head -c 300 "$WORK/body")" ;; esac | |
| 139 | ||
| 140 | step "create repository $WORKSPACE/$REPO" | |
| 141 | out="$(post /new --data-urlencode "workspace=$WORKSPACE" --data-urlencode "name=$REPO" --data-urlencode "description=Self-host smoke test" --data-urlencode "visibility=public" --data-urlencode "source=empty")" | |
| 142 | echo "$out" | |
| 143 | case "$out" in 30[23]*) ;; *) fail "repo: $out $(head -c 300 "$WORK/body")" ;; esac | |
| 144 | ||
| 145 | step "push over HTTP" | |
| 146 | remote="${G1T_URL/:\/\//://$USER_NAME:$PASSWORD@}/$WORKSPACE/$REPO.git" | |
| 147 | git init -q -b main "$WORK/src" | |
| 148 | ( | |
| 149 | cd "$WORK/src" | |
| 150 | git config user.name "Smoke Test" | |
| 151 | git config user.email "$EMAIL" | |
| 152 | # A throwaway commit: never signed, whatever the global config says. | |
| 153 | git config commit.gpgsign false | |
| 154 | printf '# hello\n\nPushed to a self-hosted g1t.\n' > README.md | |
| 155 | mkdir -p src && printf 'fn main() {\n println!("hello from g1t");\n}\n' > src/main.rs | |
| 156 | git add . && git commit -qm "First commit" | |
| 157 | git -c credential.helper= push -q "$remote" main | |
| 158 | ) | |
| 159 | echo "pushed $(git -C "$WORK/src" rev-parse --short HEAD)" | |
| 160 | ||
| 161 | step "clone over HTTP" | |
| 162 | git -c credential.helper= clone -q "$G1T_URL/$WORKSPACE/$REPO.git" "$WORK/clone" | |
| 163 | diff -q "$WORK/src/README.md" "$WORK/clone/README.md" || fail "clone differs" | |
| 164 | echo "clone matches" | |
| 165 | ||
| Merge branch 'worktree-agent-aaf03bdceac799c89' | 166 | if [ "$PACK_CACHE" != off ]; then |
| 167 | step "clone again: the pack comes from the cache" | |
| 168 | # The repos service says in Server-Timing whether the pack was kept. | |
| 169 | GIT_TRACE_CURL=1 GIT_TRACE_CURL_NO_DATA=1 git -c credential.helper= clone -q "$G1T_URL/$WORKSPACE/$REPO.git" "$WORK/again" 2> "$WORK/trace" | |
| 170 | grep -qi 'server-timing:.*pack;desc=hit' "$WORK/trace" || fail "the second clone's pack was not kept: $(grep -io 'pack;desc=[a-z]*' "$WORK/trace" | tr '\n' ' ')" | |
| 171 | diff -qr --exclude=.git "$WORK/clone" "$WORK/again" >/dev/null || fail "the kept pack differs" | |
| 172 | echo "hit" | |
| 173 | fi | |
| 174 | ||
| Mission control counts people's direct pushes to the default branch | 175 | step "open an issue" |
| 176 | out="$(post "/$WORKSPACE/$REPO/issues/new" --data-urlencode "title=It works" --data-urlencode "body=Opened by smoke.sh")" | |
| 177 | echo "$out" | |
| 178 | case "$out" in 30[23]*/issues/1) ;; *) fail "issue: $out $(head -c 300 "$WORK/body")" ;; esac | |
| 179 | [ "$(get "/$WORKSPACE/$REPO/issues/1")" = 200 ] || fail "issue page" | |
| 180 | grep -q "It works" "$WORK/body" || fail "issue page does not show the title" | |
| 181 | ||
| 182 | step "browse code in the site" | |
| 183 | [ "$(get "/$WORKSPACE/$REPO/code")" = 200 ] || fail "code page" | |
| 184 | grep -q "README.md" "$WORK/body" || fail "code page does not list README.md" | |
| 185 | [ "$(get "/$WORKSPACE/$REPO/blob/main/src/main.rs")" = 200 ] || fail "blob page" | |
| 186 | grep -q "hello from g1t" "$WORK/body" || fail "blob page does not show the file" | |
| 187 | [ "$(get "/$WORKSPACE/$REPO/commits")" = 200 ] || fail "commits page" | |
| 188 | grep -q "First commit" "$WORK/body" || fail "commits page does not show the commit" | |
| 189 | ||
| Merge branch 'worktree-agent-aaf03bdceac799c89' | 190 | step "make an access token" |
| 191 | out="$(post /settings/tokens --data-urlencode "intent=add-token" --data-urlencode "label=smoke" --data-urlencode "preset=full" --data-urlencode "expires=7")" | |
| 192 | echo "$out" | |
| 193 | TOKEN="$(grep -ao 'g1t_[0-9A-Za-z_-]*' "$WORK/body" | head -1 || true)" | |
| 194 | [ -n "$TOKEN" ] || fail "no token in the tokens page: $out" | |
| 195 | echo "token ${TOKEN:0:8}…" | |
| 196 | ||
| 197 | step "the API answers at $API_URL" | |
| 198 | [ "$(api GET /user)" = 200 ] || fail "GET /user: $(head -c 300 "$WORK/api")" | |
| 199 | [ "$(json username)" = "$USER_NAME" ] || fail "GET /user names $(json username), not $USER_NAME" | |
| 200 | [ "$(api GET /)" = 200 ] || fail "GET /" | |
| 201 | [ "$(json mcp_url)" = "$MCP_URL" ] || fail "the API's index names $(json mcp_url) as MCP, not $MCP_URL" | |
| 202 | [ "$(json git_url)" = "$G1T_URL/{owner}/{name}.git" ] || fail "git_url is $(json git_url)" | |
| 203 | curl -sS -o "$WORK/api" "$API_URL/.well-known/oauth-authorization-server" | |
| 204 | [ "$(json issuer)" = "$API_URL" ] || fail "the OAuth issuer is $(json issuer), not $API_URL" | |
| 205 | [ "$(json authorization_endpoint)" = "$G1T_URL/oauth/authorize" ] || fail "people approve at $(json authorization_endpoint)" | |
| 206 | echo "issuer $(json issuer)" | |
| 207 | code="$(curl -sS -o "$WORK/api" -D "$WORK/headers" -w '%{http_code}' -X POST -H "content-type: application/json" \ | |
| 208 | --data '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' "$MCP_URL")" | |
| 209 | [ "$code" = 401 ] || fail "MCP without a token answered $code" | |
| 210 | grep -qi "resource_metadata=\"$API_URL/.well-known/oauth-protected-resource/mcp\"" "$WORK/headers" || fail "MCP's challenge: $(grep -i www-authenticate "$WORK/headers")" | |
| 211 | code="$(curl -sS -o "$WORK/api" -w '%{http_code}' -X POST -H "Authorization: Bearer $TOKEN" -H "content-type: application/json" \ | |
| 212 | -H "accept: application/json, text/event-stream" --data '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' "$MCP_URL")" | |
| 213 | [ "$code" = 200 ] && grep -q '"tools"' "$WORK/api" || fail "MCP tools/list: $code $(head -c 300 "$WORK/api")" | |
| 214 | echo "MCP lists its tools at $MCP_URL" | |
| 215 | ||
| Merge branch 'worktree-agent-af58ac8933b0dd125' | 216 | if [ "$PACKAGES" != off ]; then |
| 217 | step "publish an npm package and install it" | |
| 218 | # The tarball is kept in the packages store (S3), and read back from it. | |
| 219 | npmrc="@$WORKSPACE:registry=$G1T_URL/-/npm/ | |
| 220 | //${G1T_URL#*://}/-/npm/:_authToken=$TOKEN" | |
| 221 | mkdir -p "$WORK/pkg" "$WORK/app" | |
| 222 | printf '%s\n' "$npmrc" > "$WORK/pkg/.npmrc" | |
| 223 | printf '%s\n' "$npmrc" > "$WORK/app/.npmrc" | |
| 224 | printf '{"name":"@%s/%s","version":"1.0.0","repository":"%s/%s/%s","main":"index.js"}\n' \ | |
| 225 | "$WORKSPACE" "$REPO" "$G1T_URL" "$WORKSPACE" "$REPO" > "$WORK/pkg/package.json" | |
| 226 | printf 'module.exports = "published by smoke.sh %s";\n' "$RUN" > "$WORK/pkg/index.js" | |
| 227 | (cd "$WORK/pkg" && npm publish --silent) || fail "npm publish" | |
| 228 | (cd "$WORK/app" && npm init -y >/dev/null && npm install --silent --no-audit --no-fund "@$WORKSPACE/$REPO@1.0.0") || fail "npm install" | |
| 229 | got="$(cd "$WORK/app" && node -p "require('@$WORKSPACE/$REPO')")" | |
| 230 | [ "$got" = "published by smoke.sh $RUN" ] || fail "the installed package says: $got" | |
| 231 | echo "installed @$WORKSPACE/$REPO@1.0.0" | |
| 232 | fi | |
| 233 | ||
| Merge branch 'worktree-agent-aaf03bdceac799c89' | 234 | step "a pull request from a branch, merged" |
| 235 | git -C "$WORK/clone" config credential.helper "" | |
| 236 | commit_file "$WORK/clone" "$remote" from-branch docs/branch.md | |
| 237 | [ "$(api POST "/repos/$WORKSPACE/$REPO/pulls" '{"title":"From a branch","branch":"from-branch","body":"Opened by smoke.sh"}')" = 200 ] \ | |
| 238 | || fail "open from a branch: $(head -c 300 "$WORK/api")" | |
| 239 | BRANCH_PULL="$(json pull.number)" | |
| 240 | echo "pull request #$BRANCH_PULL ($(json pull.status))" | |
| 241 | [ "$(get "/$WORKSPACE/$REPO/pull/$BRANCH_PULL")" = 200 ] && grep -q "From a branch" "$WORK/body" || fail "pull request page" | |
| 242 | [ "$(api POST "/repos/$WORKSPACE/$REPO/pulls/$BRANCH_PULL/merge" '{}')" = 200 ] || fail "merge: $(head -c 300 "$WORK/api")" | |
| 243 | until_status "$BRANCH_PULL" merged | |
| 244 | main_has docs/branch.md || fail "main does not have the branch's change" | |
| 245 | echo "merged onto main" | |
| 246 | ||
| 247 | step "a pull request from a fork, merged" | |
| 248 | [ "$(api POST "/repos/$WORKSPACE/$REPO/pulls" '{"title":"From a fork","agent":"smoke"}')" = 200 ] \ | |
| 249 | || fail "open with a fork: $(head -c 300 "$WORK/api")" | |
| 250 | FORK_PULL="$(json pull.number)" | |
| 251 | fork_remote="$(json git.remote)" | |
| 252 | echo "pull request #$FORK_PULL ($(json pull.status)), fork $fork_remote" | |
| 253 | case "$fork_remote" in "$G1T_URL"/*) ;; *) fail "the fork's remote is not on $G1T_URL: $fork_remote" ;; esac | |
| 254 | [ "$fork_remote" != "$G1T_URL/$WORKSPACE/$REPO.git" ] || fail "no fork was made" | |
| 255 | authed_fork="${fork_remote/:\/\//://$USER_NAME:$TOKEN@}" | |
| 256 | git -c credential.helper= clone -q "$authed_fork" "$WORK/fork" | |
| 257 | commit_file "$WORK/fork" "$authed_fork" "$(git -C "$WORK/fork" branch --show-current)" docs/fork.md | |
| 258 | [ "$(api POST "/repos/$WORKSPACE/$REPO/pulls/$FORK_PULL/ready" '{"summary":"Adds docs/fork.md, from a fork."}')" = 200 ] \ | |
| 259 | || fail "ready: $(head -c 300 "$WORK/api")" | |
| 260 | [ "$(api POST "/repos/$WORKSPACE/$REPO/pulls/$FORK_PULL/merge" '{}')" = 200 ] || fail "merge: $(head -c 300 "$WORK/api")" | |
| 261 | until_status "$FORK_PULL" merged | |
| 262 | main_has docs/fork.md || fail "main does not have the fork's change" | |
| 263 | echo "merged onto main" | |
| 264 | ||
| 265 | step "the merge queue takes a pull request, and gives it back" | |
| 266 | [ "$(api PATCH "/repos/$WORKSPACE/$REPO/settings" '{"merge_queue":true}')" = 200 ] || fail "turn the queue on: $(head -c 300 "$WORK/api")" | |
| 267 | git -C "$WORK/clone" fetch -q "$G1T_URL/$WORKSPACE/$REPO.git" main | |
| 268 | git -C "$WORK/clone" switch -q -c queued FETCH_HEAD | |
| 269 | commit_file "$WORK/clone" "$remote" queued docs/queued.md | |
| 270 | [ "$(api POST "/repos/$WORKSPACE/$REPO/pulls" '{"title":"Through the queue","branch":"queued"}')" = 200 ] || fail "open: $(head -c 300 "$WORK/api")" | |
| 271 | QUEUE_PULL="$(json pull.number)" | |
| 272 | [ "$(api POST "/repos/$WORKSPACE/$REPO/pulls/$QUEUE_PULL/merge" '{}')" = 200 ] || fail "merge into the queue: $(head -c 300 "$WORK/api")" | |
| 273 | [ "$(api GET "/repos/$WORKSPACE/$REPO/queue")" = 200 ] || fail "queue: $(head -c 300 "$WORK/api")" | |
| 274 | [ "$(json enabled)" = true ] || fail "the queue is not on" | |
| 275 | node -e 'const q = JSON.parse(require("fs").readFileSync(process.argv[1], "utf8")); const e = q.active.find((e) => e.number === Number(process.argv[2])); if (!e) process.exit(1); console.log(`#${e.number} is ${e.state} in the queue`)' "$WORK/api" "$QUEUE_PULL" \ | |
| 276 | || fail "#$QUEUE_PULL is not in the queue: $(head -c 400 "$WORK/api")" | |
| 277 | [ "$(get "/$WORKSPACE/$REPO/queue")" = 200 ] && grep -q "Through the queue" "$WORK/body" || fail "queue page" | |
| The agents, models and context services are deleted. Nothing calls them any more: workspace agents, the hosted model proxy at models.g1t.sh with its AI Gateway, and the context hub with its search index are gone with the features they served. The deploy stack no longer builds or deploys them, so it no longer needs CONNECTORS_KEY, AI_GATEWAY_TOKEN, ANTHROPIC_API_KEY or WORKERS_AI_TOKEN, and a self-hosted install no longer generates CONNECTORS_KEY or stubs them out. Their databases, queues, index, gateway and domain stay in Cloudflare until they are deleted by hand after this is deployed. | 278 | # Testing a queued state needs a sandbox, and cloud runners are off: take it out. |
| Merge branch 'worktree-agent-aaf03bdceac799c89' | 279 | out="$(post "/$WORKSPACE/$REPO/pull/$QUEUE_PULL" --data-urlencode "action=unqueue")" |
| 280 | echo "unqueue: $out" | |
| 281 | [ "$(api GET "/repos/$WORKSPACE/$REPO/queue")" = 200 ] || fail "queue" | |
| 282 | node -e 'const q = JSON.parse(require("fs").readFileSync(process.argv[1], "utf8")); process.exit(q.active.some((e) => e.number === Number(process.argv[2])) ? 1 : 0)' "$WORK/api" "$QUEUE_PULL" \ | |
| 283 | || fail "#$QUEUE_PULL is still in the queue" | |
| 284 | [ "$(api PATCH "/repos/$WORKSPACE/$REPO/settings" '{"merge_queue":false}')" = 200 ] || fail "turn the queue off" | |
| 285 | [ "$(api POST "/repos/$WORKSPACE/$REPO/pulls/$QUEUE_PULL/merge" '{}')" = 200 ] || fail "merge: $(head -c 300 "$WORK/api")" | |
| 286 | until_status "$QUEUE_PULL" merged | |
| 287 | main_has docs/queued.md || fail "main does not have the change" | |
| 288 | echo "out of the queue, then merged onto main" | |
| 289 | ||
| 290 | if [ -n "$SCHEDULER_ONCE" ]; then | |
| 291 | step "every cron handler runs" | |
| 292 | $SCHEDULER_ONCE || fail "a cron handler failed" | |
| 293 | fi | |
| 294 | ||
| Mission control counts people's direct pushes to the default branch | 295 | printf '\nAll checks passed: %s/%s/%s\n' "$G1T_URL" "$WORKSPACE" "$REPO" |
This file's history is long; its oldest lines are credited to the oldest commit read.