Skip to content

Commit 5be6645

Browse files
authored
feat: add isolated staging results environment / 添加隔离的结果预发布环境 (#565)
* feat: add isolated staging results environment Refresh the shared Neon staging branch from production before each staged ingest, synchronize the Vercel staging branch from master, and isolate server/CDN/blob caches by environment. 中文:添加隔离的结果预发布环境。每次预发布写入前从生产环境刷新共享 Neon staging 分支,将 Vercel staging 分支同步到 master,并按环境隔离服务端、CDN 和 Blob 缓存。 * fix: overwrite changelog metadata on reingest Update changelog rows on their workflow/ref natural key and document the destructive staging refresh that replaces the previous unofficial run before every ingest. 中文:重复写入时覆盖 changelog 元数据。按 workflow/ref 自然键更新 changelog 行,并明确预发布环境会在每次写入前执行破坏性刷新,从而替换上一次非官方运行。 * fix: skip source wait for staged ingests Keep the legacy delay only for direct ingest-agentic-results repository dispatches. Reusable /stage-results calls and manual workflow dispatches now start ingestion immediately. 中文:预发布写入时跳过源运行等待。仅直接 ingest-agentic-results repository dispatch 保留原有延迟;可复用的 /stage-results 调用和手动 workflow dispatch 会立即开始写入。 * fix: scope staging workflow secrets Document the staging-ref write permission and pass only the secrets required by the reusable staging ingest instead of inheriting the repository secret set. 中文:限制预发布工作流的密钥范围。说明 staging Git 引用写入权限的用途,并仅向可复用预发布写入工作流传递所需密钥,不再继承仓库的全部密钥。
1 parent 7780426 commit 5be6645

9 files changed

Lines changed: 460 additions & 31 deletions

File tree

.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
# DATABASE_READONLY_URL=
3131
# DATABASE_DRIVER=neon
3232
# DATABASE_SSL=true
33+
# CACHE_NAMESPACE=
3334
# BLOB_CACHE_PREFIX=
3435
# BLOB_READ_WRITE_TOKEN=
3536
# GITHUB_TOKEN=

.github/workflows/ingest-agentic-results.yml

Lines changed: 85 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,47 @@ name: Ingest Agentic Benchmark Results
2424
on:
2525
repository_dispatch:
2626
types: [ingest-agentic-results]
27+
workflow_call:
28+
inputs:
29+
run-id:
30+
description: InferenceX Actions run ID to ingest
31+
required: true
32+
type: string
33+
run-attempt:
34+
description: InferenceX Actions run attempt to ingest
35+
required: false
36+
default: '1'
37+
type: string
38+
database-target:
39+
description: Database/cache target for the ingest
40+
required: false
41+
default: production
42+
type: string
43+
secrets:
44+
DATABASE_WRITE_URL:
45+
description: Production database write connection for direct ingests
46+
required: false
47+
DATABASE_DEV_WRITE_URL:
48+
description: Development database write connection for direct ingests
49+
required: false
50+
DATABASE_STAGING_WRITE_URL:
51+
description: Neon staging branch write connection
52+
required: true
53+
VERCEL_INVALIDATE_SECRET:
54+
description: Production and development cache invalidation bearer token
55+
required: false
56+
VERCEL_STAGING_INVALIDATE_SECRET:
57+
description: Staging cache invalidation bearer token
58+
required: true
59+
VERCEL_STAGING_BYPASS_SECRET:
60+
description: Vercel protection automation bypass token
61+
required: true
62+
INFX_MAIN_PAT:
63+
description: Token used to download InferenceX artifacts
64+
required: true
65+
SLACK_WEBHOOK_URL:
66+
description: Optional failure and unmapped-entity notifications
67+
required: false
2768
workflow_dispatch:
2869
inputs:
2970
run-id:
@@ -43,6 +84,7 @@ on:
4384
options:
4485
- production
4586
- dev
87+
- staging
4688

4789
permissions: {}
4890

@@ -61,7 +103,9 @@ jobs:
61103
contents: read
62104
steps:
63105
- name: Wait for source run to finish
64-
if: github.event_name != 'workflow_dispatch'
106+
if: >-
107+
github.event_name == 'repository_dispatch' &&
108+
github.event.action == 'ingest-agentic-results'
65109
run: sleep 300
66110

67111
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
@@ -82,15 +126,28 @@ jobs:
82126
REQUESTED_DATABASE_TARGET: ${{ github.event.client_payload.database-target || inputs.database-target || 'production' }}
83127
DATABASE_WRITE_URL_PRODUCTION: ${{ secrets.DATABASE_WRITE_URL }}
84128
DATABASE_WRITE_URL_DEV: ${{ secrets.DATABASE_DEV_WRITE_URL }}
129+
DATABASE_WRITE_URL_STAGING: ${{ secrets.DATABASE_STAGING_WRITE_URL }}
130+
INVALIDATE_SECRET_DEFAULT: ${{ secrets.VERCEL_INVALIDATE_SECRET }}
131+
INVALIDATE_SECRET_STAGING: ${{ secrets.VERCEL_STAGING_INVALIDATE_SECRET }}
132+
PROTECTION_BYPASS_SECRET_STAGING: ${{ secrets.VERCEL_STAGING_BYPASS_SECRET }}
133+
STAGING_SITE_URL: ${{ vars.STAGING_SITE_URL || 'https://inferencemax-app-git-staging-semianalysisai.vercel.app' }}
85134
run: |
86135
case "$REQUESTED_DATABASE_TARGET" in
87136
production)
88137
database_write_url="$DATABASE_WRITE_URL_PRODUCTION"
89138
cache_invalidate_url="https://inferencex.semianalysis.com/api/v1/invalidate"
139+
cache_invalidate_secret="$INVALIDATE_SECRET_DEFAULT"
90140
;;
91141
dev)
92142
database_write_url="$DATABASE_WRITE_URL_DEV"
93143
cache_invalidate_url="https://inferencemax-app-git-feat-agentx-semianalysisai.vercel.app/api/v1/invalidate"
144+
cache_invalidate_secret="$INVALIDATE_SECRET_DEFAULT"
145+
;;
146+
staging)
147+
database_write_url="$DATABASE_WRITE_URL_STAGING"
148+
cache_invalidate_url="${STAGING_SITE_URL%/}/api/v1/invalidate"
149+
cache_invalidate_secret="$INVALIDATE_SECRET_STAGING"
150+
protection_bypass_secret="$PROTECTION_BYPASS_SECRET_STAGING"
94151
;;
95152
*)
96153
echo "::error::Unsupported database-target: $REQUESTED_DATABASE_TARGET"
@@ -102,11 +159,27 @@ jobs:
102159
echo "::error::Database secret is empty for target: $REQUESTED_DATABASE_TARGET"
103160
exit 1
104161
fi
162+
if [ -z "$cache_invalidate_secret" ]; then
163+
echo "::error::Cache invalidation secret is empty for target: $REQUESTED_DATABASE_TARGET"
164+
exit 1
165+
fi
166+
if [ "$REQUESTED_DATABASE_TARGET" = "staging" ] && [ -z "$protection_bypass_secret" ]; then
167+
echo "::error::Vercel protection bypass secret is empty for staging"
168+
exit 1
169+
fi
105170
106171
echo "::add-mask::$database_write_url"
107-
echo "DATABASE_WRITE_URL=$database_write_url" >> "$GITHUB_ENV"
108-
echo "INGEST_DATABASE_TARGET=$REQUESTED_DATABASE_TARGET" >> "$GITHUB_ENV"
109-
echo "CACHE_INVALIDATE_URL=$cache_invalidate_url" >> "$GITHUB_ENV"
172+
echo "::add-mask::$cache_invalidate_secret"
173+
if [ -n "$protection_bypass_secret" ]; then
174+
echo "::add-mask::$protection_bypass_secret"
175+
fi
176+
{
177+
echo "DATABASE_WRITE_URL=$database_write_url"
178+
echo "CACHE_INVALIDATE_SECRET=$cache_invalidate_secret"
179+
echo "INGEST_DATABASE_TARGET=$REQUESTED_DATABASE_TARGET"
180+
echo "CACHE_INVALIDATE_URL=$cache_invalidate_url"
181+
echo "CACHE_PROTECTION_BYPASS_SECRET=$protection_bypass_secret"
182+
} >> "$GITHUB_ENV"
110183
echo "Selected ingest target: $REQUESTED_DATABASE_TARGET"
111184
echo "Cache invalidate URL: $cache_invalidate_url"
112185
@@ -184,11 +257,15 @@ jobs:
184257
run: pnpm admin:db:verify
185258

186259
- name: Invalidate Vercel cache
187-
env:
188-
VERCEL_INVALIDATE_SECRET: ${{ secrets.VERCEL_INVALIDATE_SECRET }}
189260
run: |
190-
curl -sSf -X POST "$CACHE_INVALIDATE_URL" \
191-
-H "Authorization: Bearer $VERCEL_INVALIDATE_SECRET" || true
261+
if [ "$INGEST_DATABASE_TARGET" = "staging" ]; then
262+
curl --retry 12 --retry-delay 10 --retry-all-errors -sSf -X POST "$CACHE_INVALIDATE_URL" \
263+
-H "Authorization: Bearer $CACHE_INVALIDATE_SECRET" \
264+
-H "x-vercel-protection-bypass: $CACHE_PROTECTION_BYPASS_SECRET"
265+
else
266+
curl -sSf -X POST "$CACHE_INVALIDATE_URL" \
267+
-H "Authorization: Bearer $CACHE_INVALIDATE_SECRET" || true
268+
fi
192269
193270
- name: Check for unmapped entities
194271
if: always()

0 commit comments

Comments
 (0)