Revert "merge: sync GitHub staging to Gitea"
Deploy staging to test server / deploy (push) Failing after 14m49s

This reverts commit a55c69115d, reversing
changes made to 02c9c9f3d6.
This commit is contained in:
linmeng
2026-07-30 14:38:17 +08:00
parent a55c69115d
commit f4e35974c6
106 changed files with 3228 additions and 1213 deletions
+26 -26
View File
@@ -6,6 +6,11 @@ required=(
INCOMING_PATH DEPLOY_PATH API_IMAGE WEB_IMAGE DEPLOY_SHA
EXPECTED_PREVIOUS_SHA ALLOW_ROLLBACK DOCKER_CONFIG STAGING_URL
)
case "${DOCKER_BIN:-docker}" in
docker) docker_command=(docker) ;;
"sudo -n docker") docker_command=(sudo -n docker --config "$DOCKER_CONFIG") ;;
*) echo "unsafe staging Docker command" >&2; exit 1 ;;
esac
for key in "${required[@]}"; do
if [ -z "${!key:-}" ]; then
echo "required staging deployment input is missing: $key" >&2
@@ -14,7 +19,7 @@ for key in "${required[@]}"; do
done
sha_pattern='^[0-9a-f]{40}$'
digest_pattern='^ghcr\.io/jesse-ux/jyotisha-(api|web)@sha256:[0-9a-f]{64}$'
digest_pattern='^[a-z0-9]([a-z0-9.-]*[a-z0-9])?(:[1-9][0-9]{0,4})?(/[a-z0-9]+([._-][a-z0-9]+)*)+@sha256:[0-9a-f]{64}$'
image_id_pattern='^sha256:[0-9a-f]{64}$'
if [[ ! "$DEPLOY_SHA" =~ $sha_pattern ]] ||
[[ ! "$API_IMAGE" =~ $digest_pattern ]] ||
@@ -22,12 +27,14 @@ if [[ ! "$DEPLOY_SHA" =~ $sha_pattern ]] ||
echo "unsafe staging image identity" >&2
exit 1
fi
api_repository="${API_IMAGE%@sha256:*}"
web_repository="${WEB_IMAGE%@sha256:*}"
if [ "$ALLOW_ROLLBACK" != "true" ] && [ "$ALLOW_ROLLBACK" != "false" ]; then
echo "invalid rollback authorization" >&2
exit 1
fi
case "$INCOMING_PATH" in
"$DEPLOY_PATH"/.incoming/*) ;;
/tmp/jyotisha-staging.*) ;;
*) echo "unsafe incoming staging path" >&2; exit 1 ;;
esac
@@ -43,11 +50,11 @@ current_sha="not-deployed"
if [ -f "$state_directory/deployed-revision" ]; then
current_sha="$(<"$state_directory/deployed-revision")"
else
existing_web="$(docker ps -aq \
existing_web="$("${docker_command[@]}" ps -aq \
--filter 'label=com.docker.compose.project=jyotisha-staging' \
--filter 'label=com.docker.compose.service=web' | head -n 1)"
if [ -n "$existing_web" ]; then
discovered_sha="$(docker inspect --format '{{range .Config.Env}}{{println .}}{{end}}' \
discovered_sha="$("${docker_command[@]}" inspect --format '{{range .Config.Env}}{{println .}}{{end}}' \
"$existing_web" | sed -n 's/^GITHUB_SHA=//p' | head -n 1)"
if [ -n "$discovered_sha" ]; then current_sha="$discovered_sha"; fi
fi
@@ -69,7 +76,7 @@ if [ "$ALLOW_ROLLBACK" = "false" ] &&
fi
container_id() {
docker ps -aq \
"${docker_command[@]}" ps -aq \
--filter 'label=com.docker.compose.project=jyotisha-staging' \
--filter "label=com.docker.compose.service=$1" | head -n 1
}
@@ -80,20 +87,20 @@ repo_digest_for_container() {
local id image_id
id="$(container_id "$service")"
[ -n "$id" ] || return 0
image_id="$(docker inspect --format '{{.Image}}' "$id")"
docker image inspect --format '{{range .RepoDigests}}{{println .}}{{end}}' "$image_id" |
image_id="$("${docker_command[@]}" inspect --format '{{.Image}}' "$id")"
"${docker_command[@]}" image inspect --format '{{range .RepoDigests}}{{println .}}{{end}}' "$image_id" |
awk -v prefix="$repository@sha256:" 'index($0, prefix) == 1 { print; exit }'
}
previous_api_image="$(repo_digest_for_container api ghcr.io/jesse-ux/jyotisha-api)"
previous_web_image="$(repo_digest_for_container web ghcr.io/jesse-ux/jyotisha-web)"
previous_api_image="$(repo_digest_for_container api "$api_repository")"
previous_web_image="$(repo_digest_for_container web "$web_repository")"
previous_api_id=""
previous_web_id=""
if [ -n "$(container_id api)" ]; then
previous_api_id="$(docker inspect --format '{{.Image}}' "$(container_id api)")"
previous_api_id="$("${docker_command[@]}" inspect --format '{{.Image}}' "$(container_id api)")"
fi
if [ -n "$(container_id web)" ]; then
previous_web_id="$(docker inspect --format '{{.Image}}' "$(container_id web)")"
previous_web_id="$("${docker_command[@]}" inspect --format '{{.Image}}' "$(container_id web)")"
fi
rollback_image() {
@@ -118,7 +125,7 @@ bash deploy/validate-staging-env.sh \
bash deploy/validate-staging-database-env.sh .env.staging.database
compose=(
docker compose -p jyotisha-staging --env-file .env.staging
"${docker_command[@]}" compose -p jyotisha-staging --env-file .env.staging
-f deploy/docker-compose.server.yml -f deploy/docker-compose.postgres.yml
-f deploy/docker-compose.staging.yml
)
@@ -126,7 +133,6 @@ export APP_ENV_FILE='../.env.staging'
export DATABASE_ENV_FILE='../.env.staging.database'
export CADDYFILE_PATH='./Caddyfile.staging'
export SITE_ADDRESS='https://staging.jyotisha.chat'
export ADMIN_SITE_ADDRESS='https://admin.staging.jyotisha.chat'
export GITHUB_SHA="$DEPLOY_SHA"
"${compose[@]}" config --quiet
@@ -172,10 +178,10 @@ verify_container_image() {
local id expected_id running_id repo_digests
id="$(container_id "$service")"
[ -n "$id" ]
expected_id="$(docker image inspect --format '{{.Id}}' "$expected_ref")"
running_id="$(docker inspect --format '{{.Image}}' "$id")"
expected_id="$("${docker_command[@]}" image inspect --format '{{.Id}}' "$expected_ref")"
running_id="$("${docker_command[@]}" inspect --format '{{.Image}}' "$id")"
[ "$running_id" = "$expected_id" ]
repo_digests="$(docker image inspect --format '{{range .RepoDigests}}{{println .}}{{end}}' "$expected_id")"
repo_digests="$("${docker_command[@]}" image inspect --format '{{range .RepoDigests}}{{println .}}{{end}}' "$expected_id")"
grep -Fqx "$expected_ref" <<<"$repo_digests"
}
verify_container_image api "$API_IMAGE"
@@ -184,7 +190,6 @@ verify_container_image rectification-v4-worker "$WEB_IMAGE"
"${compose[@]}" exec -T \
-e EXPECTED_SHA="$DEPLOY_SHA" -e STAGING_URL="$STAGING_URL" \
-e STAGING_ADMIN_URL="https://admin.staging.jyotisha.chat" \
web node --input-type=module <<'NODE'
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
let login;
@@ -196,15 +201,10 @@ for (let attempt = 0; attempt < 12; attempt += 1) {
await delay(5_000);
}
if (!login?.ok) process.exit(1);
const adminLogin = await fetch(`${process.env.STAGING_ADMIN_URL}/login`);
if (!adminLogin.ok) process.exit(1);
const adminRoot = await fetch(process.env.STAGING_ADMIN_URL, { redirect: "manual" });
if (
adminRoot.status !== 302 ||
adminRoot.headers.get("location") !== "/admin/codes"
) process.exit(1);
const adminSession = await fetch(`${process.env.STAGING_ADMIN_URL}/api/auth/get-session`);
if (!adminSession.ok) process.exit(1);
const adminPage = await fetch(`${process.env.STAGING_URL}/admin`, { redirect: "manual" });
if (adminPage.status !== 307 || adminPage.headers.get("location") !== "/login") process.exit(1);
const adminApi = await fetch(`${process.env.STAGING_URL}/api/admin/session`);
if (adminApi.status !== 401) process.exit(1);
const account = await fetch(`${process.env.STAGING_URL}/api/account`);
if (account.status !== 401) process.exit(1);
const publicHealth = await fetch(`${process.env.STAGING_URL}/api/health`);