flagon-io/g1t

public

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

g1t/deploy/self-host/smoke.sh

112 lines4,844 bytesCodeBlame
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.
11set -euo pipefail
12
13G1T_URL="${G1T_URL:-http://localhost:8787}"
14MAILPIT_URL="${MAILPIT_URL:-http://localhost:8025}"
15MAIL_LOG="${MAIL_LOG:-}"
16RUN="$(date +%s)"
17USER_NAME="smoke${RUN}"
18EMAIL="${USER_NAME}@example.com"
19PASSWORD="correct-horse-${RUN}"
20WORKSPACE="ws${RUN}"
21REPO="hello"
22WORK="$(mktemp -d)"
23JAR="$WORK/cookies"
24trap 'rm -rf "$WORK"' EXIT
25
26step() { printf '\n== %s\n' "$*"; }
27fail() { printf 'FAILED: %s\n' "$*" >&2; exit 1; }
28
29# A form POST as a browser sends it, with the Origin the site checks.
30post() {
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}
35get() {
36 curl -sS -o "$WORK/body" -w '%{http_code}' -b "$JAR" -c "$JAR" "$G1T_URL$1"
37}
38
39step "site answers at $G1T_URL"
40[ "$(get /)" = 200 ] || fail "GET / did not answer 200"
41
42step "sign up as $USER_NAME"
43out="$(post /register --data-urlencode "username=$USER_NAME" --data-urlencode "email=$EMAIL" --data-urlencode "password=$PASSWORD")"
44echo "$out"
45case "$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.
47grep -q g1t_session "$JAR" || fail "no session cookie"
48
49step "confirm the email"
50link=""
51for _ 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
60done
61[ -n "$link" ] || fail "no confirmation email arrived"
62echo "$link"
63[ "$(get "/verify?${link#*\?}")" = 200 ] || fail "verify"
64grep -q "$USER_NAME" "$WORK/body" || fail "verify page does not name the account"
65
66step "create workspace $WORKSPACE"
67out="$(post /workspaces/new --data-urlencode "slug=$WORKSPACE" --data-urlencode "displayName=Smoke $RUN")"
68echo "$out"
69case "$out" in 30[23]*) ;; *) fail "workspace: $out $(head -c 300 "$WORK/body")" ;; esac
70
71step "create repository $WORKSPACE/$REPO"
72out="$(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")"
73echo "$out"
74case "$out" in 30[23]*) ;; *) fail "repo: $out $(head -c 300 "$WORK/body")" ;; esac
75
76step "push over HTTP"
77remote="${G1T_URL/:\/\//://$USER_NAME:$PASSWORD@}/$WORKSPACE/$REPO.git"
78git 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)
90echo "pushed $(git -C "$WORK/src" rev-parse --short HEAD)"
91
92step "clone over HTTP"
93git -c credential.helper= clone -q "$G1T_URL/$WORKSPACE/$REPO.git" "$WORK/clone"
94diff -q "$WORK/src/README.md" "$WORK/clone/README.md" || fail "clone differs"
95echo "clone matches"
96
97step "open an issue"
98out="$(post "/$WORKSPACE/$REPO/issues/new" --data-urlencode "title=It works" --data-urlencode "body=Opened by smoke.sh")"
99echo "$out"
100case "$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"
102grep -q "It works" "$WORK/body" || fail "issue page does not show the title"
103
104step "browse code in the site"
105[ "$(get "/$WORKSPACE/$REPO/code")" = 200 ] || fail "code page"
106grep -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"
108grep -q "hello from g1t" "$WORK/body" || fail "blob page does not show the file"
109[ "$(get "/$WORKSPACE/$REPO/commits")" = 200 ] || fail "commits page"
110grep -q "First commit" "$WORK/body" || fail "commits page does not show the commit"
111
112printf '\nAll checks passed: %s/%s/%s\n' "$G1T_URL" "$WORKSPACE" "$REPO"