Restore routine dev preview sync after workspace rollout
Remote development preview source sync / sync-source (push) Successful in 10s

This commit is contained in:
2026-11-04 17:37:58 +08:00
parent cf0bc49732
commit 195e8d6deb
-65
View File
@@ -21,34 +21,6 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Apply additive Workspace migration to dev preview
if: gitea.ref == 'refs/heads/dev'
run: |
set -Eeuo pipefail
root=/opt/prompt-preview
test -f "$root/ready"
exec 8>/var/lock/prompt-preview-sync.lock
flock -w 30 8
id=$(docker ps -q --filter label=com.docker.compose.project=prompt-preview --filter label=com.docker.compose.service=postgres)
[[ "$id" =~ ^[a-f0-9]{12}$ ]]
sql=apps/waterfall-wiki/db/018_workspaces.sql
previous=$(cat "$root/fingerprint")
scratch=$(mktemp -d)
trap 'rm -rf "$scratch"' EXIT
mkdir -p "$scratch/apps/waterfall-wiki/db" "$scratch/packages/brand"
cp pnpm-workspace.yaml "$scratch/"
cp apps/waterfall-wiki/{pnpm-lock.yaml,next.config.ts,tsconfig.json,postcss.config.mjs,package.json} "$scratch/apps/waterfall-wiki/"
cp packages/brand/package.json "$scratch/packages/brand/"
cp apps/waterfall-wiki/db/*.sql "$scratch/apps/waterfall-wiki/db/"
rm "$scratch/$sql"
candidate=$(node scripts/preview/fingerprint.mjs "$PWD")
if [[ "$candidate" == "$previous" ]]; then exit 0; fi
test "$(node scripts/preview/fingerprint.mjs "$scratch")" = "$previous"
applied=$(docker exec "$id" psql -XAt -v ON_ERROR_STOP=1 -U prompt -d prompt -c "SELECT 1 FROM schema_migrations WHERE version='018_workspaces'")
if [[ "$applied" != 1 ]]; then
docker exec -i "$id" psql -X -v ON_ERROR_STOP=1 -U prompt -d prompt < "$sql"
fi
printf '%s\n' "$candidate" > "$root/fingerprint"
- name: Initialize once, otherwise synchronize files only
env:
SOURCE_SHA: ${{ gitea.sha }}
@@ -58,40 +30,3 @@ jobs:
bash scripts/preview/init.sh "$PWD" waterfall-wiki-tests:6654a1456bdcef77d83ca84373dc36188e15bd12
fi
bash scripts/preview/sync.sh "$PWD" "$SOURCE_SHA" "$SOURCE_BRANCH"
- name: Verify Workspace with two temporary dev accounts
if: gitea.ref == 'refs/heads/dev'
run: |
python3 - <<'PY'
import hashlib,json,secrets,subprocess,urllib.request,urllib.error,uuid
container=subprocess.check_output(['docker','ps','-q','--filter','label=com.docker.compose.project=prompt-preview','--filter','label=com.docker.compose.service=postgres'],text=True).strip()
assert len(container)==12
ids=[str(uuid.uuid4()),str(uuid.uuid4())]
tokens=[secrets.token_hex(32),secrets.token_hex(32)]
def sql(command):
subprocess.run(['docker','exec','-i',container,'psql','-Xq','-v','ON_ERROR_STOP=1','-U','prompt','-d','prompt'],input=command,text=True,check=True)
origin='http://8.211.154.134:18136'
def api(index,payload=None,expected=200):
req=urllib.request.Request('http://127.0.0.1:18136/api/account/workspaces',data=None if payload is None else json.dumps(payload).encode(),headers={'Origin':origin,'Content-Type':'application/json','Cookie':'preview_wiki_account='+tokens[index]})
try:
response=urllib.request.build_opener(urllib.request.ProxyHandler({})).open(req,timeout=30)
except urllib.error.HTTPError as error:
response=error
with response:
assert response.code==expected, (payload and payload['action'],response.code,expected)
return json.load(response)
try:
for uid,token in zip(ids,tokens):
digest=hashlib.sha256(token.encode()).hexdigest()
sql(f"INSERT INTO account_users(id,email,password_hash,verified_at) VALUES('{uid}','{uid}@example.test','invalid',now()); INSERT INTO account_tokens(digest,user_id,kind,expires_at) VALUES('{digest}','{uid}','session',now()+interval '5 minutes');")
space=api(0,{'action':'create','name':'Workspace smoke check','purpose':'个人创作'},201)['space']
assert space['owner'] and not api(1)['spaces']
api(1,{'action':'invite','workspaceId':space['id']},404)
invite=api(0,{'action':'invite','workspaceId':space['id']})['code']
assert api(1,{'action':'join','code':invite})['space']['id']==space['id']
api(1,{'action':'join','code':invite})
assert api(1)['spaces']==[{**space,'owner':False}]
print('PASS create, owner-only invite, join, repeat join, and membership isolation')
finally:
a,b=ids
sql(f"DELETE FROM workspaces WHERE owner_id IN ('{a}','{b}'); DELETE FROM account_users WHERE id IN ('{a}','{b}');")
PY