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.
| Running g1t yourself: the design, a docker compose proof, and a guide to what works today | 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 | |
| 4 | # read the code back through the site. | |
| 5 | # | |
| 6 | # ./smoke.sh # against the compose stack's defaults | |
| 7 | # G1T_URL=http://localhost:8787 MAIL_LOG=wrangler.log ./smoke.sh | |
| 8 | # | |
| 9 | # The confirmation link is read from Mailpit (MAILPIT_URL, the default) or, | |
| 10 | # with MAIL_LOG set, from a log the mail Worker printed it to. | |
| 11 | set -euo pipefail | |
| 12 | ||
| 13 | G1T_URL="${G1T_URL:-http://localhost:8787}" | |
| 14 | MAILPIT_URL="${MAILPIT_URL:-http://localhost:8025}" | |
| 15 | MAIL_LOG="${MAIL_LOG:-}" | |
| 16 | RUN="$(date +%s)" | |
| 17 | USER_NAME="smoke${RUN}" | |
| 18 | EMAIL="${USER_NAME}@example.com" | |
| 19 | PASSWORD="correct-horse-${RUN}" | |
| 20 | WORKSPACE="ws${RUN}" | |
| 21 | REPO="hello" | |
| 22 | WORK="$(mktemp -d)" | |
| 23 | JAR="$WORK/cookies" | |
| 24 | trap 'rm -rf "$WORK"' EXIT | |
| 25 | ||
| 26 | step() { printf '\n== %s\n' "$*"; } | |
| 27 | fail() { printf 'FAILED: %s\n' "$*" >&2; exit 1; } | |
| 28 | ||
| 29 | # A form POST as a browser sends it, with the Origin the site checks. | |
| 30 | post() { | |
| 31 | local path="$1"; shift | |
| 32 | curl -sS -o "$WORK/body" -w '%{http_code} %{redirect_url}' -b "$JAR" -c "$JAR" \ | |
| 33 | -H "Origin: $G1T_URL" "$@" "$G1T_URL$path" | |
| 34 | } | |
| 35 | get() { | |
| 36 | curl -sS -o "$WORK/body" -w '%{http_code}' -b "$JAR" -c "$JAR" "$G1T_URL$1" | |
| 37 | } | |
| 38 | ||
| 39 | step "site answers at $G1T_URL" | |
| 40 | [ "$(get /)" = 200 ] || fail "GET / did not answer 200" | |
| 41 | ||
| 42 | step "sign up as $USER_NAME" | |
| 43 | out="$(post /register --data-urlencode "username=$USER_NAME" --data-urlencode "email=$EMAIL" --data-urlencode "password=$PASSWORD")" | |
| 44 | echo "$out" | |
| 45 | case "$out" in 30[23]*) ;; *) fail "register: $out $(head -c 300 "$WORK/body")" ;; esac | |
| 46 | # curl keeps Secure cookies only for https or localhost; carry it by hand. | |
| 47 | grep -q g1t_session "$JAR" || fail "no session cookie" | |
| 48 | ||
| 49 | step "confirm the email" | |
| 50 | link="" | |
| 51 | for _ in $(seq 1 20); do | |
| 52 | if [ -n "$MAIL_LOG" ]; then | |
| 53 | link="$(grep -ao "[a-z]*://[^ \"<]*/verify?token=[0-9a-zA-Z_-]*" "$MAIL_LOG" | tail -1 || true)" | |
| 54 | else | |
| 55 | id="$(curl -sS "$MAILPIT_URL/api/v1/search?query=to:$EMAIL" | sed -n 's/.*"ID":"\([^"]*\)".*/\1/p' | head -1)" | |
| 56 | [ -n "$id" ] && link="$(curl -sS "$MAILPIT_URL/api/v1/message/$id" | grep -ao '[a-z]*://[^ "<\\]*/verify?token=[0-9a-zA-Z_-]*' | head -1 || true)" | |
| 57 | fi | |
| 58 | [ -n "$link" ] && break | |
| 59 | sleep 1 | |
| 60 | done | |
| 61 | [ -n "$link" ] || fail "no confirmation email arrived" | |
| 62 | echo "$link" | |
| 63 | [ "$(get "/verify?${link#*\?}")" = 200 ] || fail "verify" | |
| 64 | grep -q "$USER_NAME" "$WORK/body" || fail "verify page does not name the account" | |
| 65 | ||
| 66 | step "create workspace $WORKSPACE" | |
| 67 | out="$(post /workspaces/new --data-urlencode "slug=$WORKSPACE" --data-urlencode "displayName=Smoke $RUN")" | |
| 68 | echo "$out" | |
| 69 | case "$out" in 30[23]*) ;; *) fail "workspace: $out $(head -c 300 "$WORK/body")" ;; esac | |
| 70 | ||
| 71 | step "create repository $WORKSPACE/$REPO" | |
| 72 | 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")" | |
| 73 | echo "$out" | |
| 74 | case "$out" in 30[23]*) ;; *) fail "repo: $out $(head -c 300 "$WORK/body")" ;; esac | |
| 75 | ||
| 76 | step "push over HTTP" | |
| 77 | remote="${G1T_URL/:\/\//://$USER_NAME:$PASSWORD@}/$WORKSPACE/$REPO.git" | |
| 78 | git init -q -b main "$WORK/src" | |
| 79 | ( | |
| 80 | cd "$WORK/src" | |
| 81 | git config user.name "Smoke Test" | |
| 82 | git config user.email "$EMAIL" | |
| 83 | # A throwaway commit: never signed, whatever the global config says. | |
| 84 | git config commit.gpgsign false | |
| 85 | printf '# hello\n\nPushed to a self-hosted g1t.\n' > README.md | |
| 86 | mkdir -p src && printf 'fn main() {\n println!("hello from g1t");\n}\n' > src/main.rs | |
| 87 | git add . && git commit -qm "First commit" | |
| 88 | git -c credential.helper= push -q "$remote" main | |
| 89 | ) | |
| 90 | echo "pushed $(git -C "$WORK/src" rev-parse --short HEAD)" | |
| 91 | ||
| 92 | step "clone over HTTP" | |
| 93 | git -c credential.helper= clone -q "$G1T_URL/$WORKSPACE/$REPO.git" "$WORK/clone" | |
| 94 | diff -q "$WORK/src/README.md" "$WORK/clone/README.md" || fail "clone differs" | |
| 95 | echo "clone matches" | |
| 96 | ||
| 97 | step "open an issue" | |
| 98 | out="$(post "/$WORKSPACE/$REPO/issues/new" --data-urlencode "title=It works" --data-urlencode "body=Opened by smoke.sh")" | |
| 99 | echo "$out" | |
| 100 | case "$out" in 30[23]*/issues/1) ;; *) fail "issue: $out $(head -c 300 "$WORK/body")" ;; esac | |
| 101 | [ "$(get "/$WORKSPACE/$REPO/issues/1")" = 200 ] || fail "issue page" | |
| 102 | grep -q "It works" "$WORK/body" || fail "issue page does not show the title" | |
| 103 | ||
| 104 | step "browse code in the site" | |
| 105 | [ "$(get "/$WORKSPACE/$REPO/code")" = 200 ] || fail "code page" | |
| 106 | grep -q "README.md" "$WORK/body" || fail "code page does not list README.md" | |
| 107 | [ "$(get "/$WORKSPACE/$REPO/blob/main/src/main.rs")" = 200 ] || fail "blob page" | |
| 108 | grep -q "hello from g1t" "$WORK/body" || fail "blob page does not show the file" | |
| 109 | [ "$(get "/$WORKSPACE/$REPO/commits")" = 200 ] || fail "commits page" | |
| 110 | grep -q "First commit" "$WORK/body" || fail "commits page does not show the commit" | |
| 111 | ||
| 112 | printf '\nAll checks passed: %s/%s/%s\n' "$G1T_URL" "$WORKSPACE" "$REPO" |