ci: serialize deployments and restore previous release on smoke failure
This commit is contained in:
1 parent
85a6df162b
commit
7c1f109a9d
7 files changed
+366
-231
No files matched your search
+9
-128
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -18,6 +18,10 @@ set -uo pipefail
|
||||
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
cd "$DIR" || exit 2
|
||||
|
||||
# Share the CI lock before pulling or touching the live application.
|
||||
exec 9>"$DIR/.deploy.lock"
|
||||
flock -w 1800 9 || exit 2
|
||||
|
||||
LOG_FILE="${LOG_FILE:-$DIR/logs/docker-update.log}"
|
||||
PM2_APP="${PM2_APP:-next}" # host-side CMS that must stay stopped (port 3002)
|
||||
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -58,10 +58,10 @@ describe("CI workflow", () => {
|
||||
expect(workflow).toContain('tags: ["v*"]');
|
||||
});
|
||||
|
||||
it("has e2e job that smoke-tests the deployed app", () => {
|
||||
expect(workflow).toContain("e2e:");
|
||||
expect(workflow).toContain("needs: deploy");
|
||||
expect(workflow).toContain("pnpm test:e2e");
|
||||
expect(workflow).toContain("PLAYWRIGHT_BASE_URL");
|
||||
it("smoke-tests the deployed app within the deployment transaction", () => {
|
||||
expect(workflow).toContain("bash scripts/ci-deploy.sh");
|
||||
const deploy = readFileSync("scripts/ci-deploy.sh", "utf8");
|
||||
expect(deploy).toContain("pnpm test:e2e");
|
||||
expect(deploy).toContain("PLAYWRIGHT_BASE_URL");
|
||||
});
|
||||
});
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,44 @@
|
||||
# Sourced only by the deployment simulation tests; no external services are used.
|
||||
git() {
|
||||
if [ "$1" = rev-parse ]; then printf '%s\n' "$TEST_SHA"; return; fi
|
||||
local n=0
|
||||
if [ -f "$TEST_DIR/remote-count" ]; then read -r n < "$TEST_DIR/remote-count"; fi
|
||||
n=$((n+1)); printf '%s\n' "$n" > "$TEST_DIR/remote-count"
|
||||
if [ "$SCENARIO" = remote-failure ]; then return 1; fi
|
||||
if [ "$SCENARIO" = stale ] || { [ "$SCENARIO" = superseded ] && [ "$n" -gt 1 ]; }; then
|
||||
printf '%s\trefs/heads/main\n' bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
else printf '%s\trefs/heads/main\n' "$TEST_SHA"; fi
|
||||
}
|
||||
flock() { echo "lock" >> "$TEST_DIR/calls"; [ "$SCENARIO" != lock-failure ]; }
|
||||
pnpm() {
|
||||
echo "pnpm $*" >> "$TEST_DIR/calls"
|
||||
if [ "$1" = db:migrate ] && [ "$SCENARIO" = migration-failure ]; then return 1; fi
|
||||
if [ "$1" = test:e2e ] && [ "$SCENARIO" = smoke-failure ]; then return 1; fi
|
||||
return 0
|
||||
}
|
||||
curl() {
|
||||
if [ "$SCENARIO" = health-failure ] && [ "$(cat "$TEST_DIR/epicnext-cms-app" 2>/dev/null)" = new ]; then return 1; fi
|
||||
echo '{"database":true}'
|
||||
}
|
||||
sleep() { :; }
|
||||
docker() {
|
||||
echo "docker $*" >> "$TEST_DIR/calls"
|
||||
local name="${@: -1}"
|
||||
case "$1" in
|
||||
inspect)
|
||||
[ -f "$TEST_DIR/$name" ] || return 1
|
||||
if [ "${3:-}" = '{{.State.Running}}' ]; then echo true
|
||||
elif [ "${3:-}" = '{{.Image}}' ]; then echo sha256:old
|
||||
fi ;;
|
||||
build) [ "$SCENARIO" != build-failure ] ;;
|
||||
stop) return 0 ;;
|
||||
rename) mv "$TEST_DIR/$2" "$TEST_DIR/$3" ;;
|
||||
run)
|
||||
echo new > "$TEST_DIR/epicnext-cms-app"
|
||||
[ "$SCENARIO" != run-failure ] ;;
|
||||
start) [ -f "$TEST_DIR/$2" ] ;;
|
||||
rm) rm -f "$TEST_DIR/$name" ;;
|
||||
*) return 0 ;;
|
||||
esac
|
||||
}
|
||||
export -f git flock pnpm curl sleep docker
|
||||
Reference in new issue
Block a user