Compare commits

...

4 Commits

Author SHA1 Message Date
codex-bot cc8ddba7aa Accept formatted Foundry project configuration from Actions
Foundry Go checks / check (pull_request) Successful in 1m21s
Foundry Go checks / check (push) Successful in 1m22s
2026-11-05 01:44:44 +08:00
Zayden-Jung c7ec5f7eb2 Merge pull request '部署检查只验证 Foundry 后端就绪' (#2) from codex/foundry-backend-smoke into main
Foundry Go checks / check (push) Successful in 1m23s
Deploy Foundry Core / deploy (push) Failing after 1m24s
Reviewed-on: #2
2026-11-04 17:03:24 +00:00
codex-bot 33719a549b Keep deployment smoke checks backend-only
Foundry Go checks / check (pull_request) Successful in 1m22s
Foundry Go checks / check (push) Successful in 1m21s
2026-11-05 00:57:53 +08:00
Zayden-Jung 17cec9ff06 Merge pull request '从 main 部署 Foundry Core 并注入 OAuth 配置' (#1) from codex/foundry-actions-deploy into main
Foundry Go checks / check (push) Successful in 1m23s
Deploy Foundry Core / deploy (push) Failing after 1m47s
Reviewed-on: #1
2026-11-04 16:48:52 +00:00
3 changed files with 28 additions and 12 deletions
+1 -1
View File
@@ -31,7 +31,7 @@ jobs:
test -z "$(gofmt -l cmd internal)"
go test -mod=readonly ./...
CGO_ENABLED=0 go build -mod=readonly -o bin/foundry ./cmd/foundry
- name: Deploy and verify OAuth entry
- name: Deploy and verify backend readiness
env:
GOOGLE_CLIENT_ID: ${{ secrets.GOOGLE_CLIENT_ID }}
GOOGLE_CLIENT_SECRET: ${{ secrets.GOOGLE_CLIENT_SECRET }}
+1 -1
View File
@@ -14,7 +14,7 @@
在仓库的 Actions Secrets 配置 `GOOGLE_CLIENT_ID` 和 `GOOGLE_CLIENT_SECRET`,在 Actions Variables 配置 `FOUNDRY_PROJECTS`。变量值为 JSON 对象,例如 `{"prompt":"http://localhost:17321/auth/callback"}`。部署读取服务器上预先配置的 `/opt/endoleap-infra/foundry/database.env`,OAuth 值由 Actions 在启动容器时注入。
Google OAuth 的授权回调地址为 `https://api.foundry.entroia.com/auth/google/callback`。工作流会验证数据库就绪、匿名请求返回 401、Google 授权跳转参数和 HTTPS 就绪。完整登录还需在浏览器用 Google 测试账号走完回调、兑换和会话验证。
Google OAuth 的授权回调地址为 `https://api.foundry.entroia.com/auth/google/callback`。工作流会验证数据库就绪、匿名请求返回 401 和 HTTPS 就绪。前端接入后,可在浏览器用 Google 测试账号验证完整登录、回调、兑换和会话。
## 前端接入
+26 -10
View File
@@ -8,13 +8,36 @@ origin=https://api.foundry.entroia.com
candidate=foundry-core-candidate
network=endoleap-dev_default
for name in GOOGLE_CLIENT_ID GOOGLE_CLIENT_SECRET FOUNDRY_PROJECTS; do
for name in GOOGLE_CLIENT_ID GOOGLE_CLIENT_SECRET; do
value=${!name-}
if [[ -z "$value" || "$value" == *$'\n'* || "$value" == *$'\r'* ]]; then
printf 'Missing or invalid %s\n' "$name" >&2
exit 1
fi
done
# Accept formatted JSON from Actions Variables and never print its contents.
FOUNDRY_PROJECTS=$(python3 - <<'PYCONFIG'
import json
import os
import sys
raw = os.environ.get("FOUNDRY_PROJECTS", "")
if not raw.strip():
sys.exit("FOUNDRY_PROJECTS was not injected from Actions Variables")
try:
projects = json.loads(raw)
except ValueError:
sys.exit("FOUNDRY_PROJECTS must be valid JSON")
if not isinstance(projects, dict) or not projects or any(
not isinstance(callback, str) or not callback.strip()
for callback in projects.values()
):
sys.exit("FOUNDRY_PROJECTS must map project names to callback URLs")
print(json.dumps(projects, separators=(",", ":")))
PYCONFIG
)
export FOUNDRY_PROJECTS
test -s "$foundry/database.env"
docker network inspect "$network" >/dev/null
@@ -51,15 +74,8 @@ docker exec "$candidate" node -e '
const project = Object.keys(JSON.parse(process.env.FOUNDRY_PROJECTS))[0];
const route = base + "/projects/" + encodeURIComponent(project) + "/auth";
assert.equal((await fetch(route + "/me")).status, 401);
const challenge = require("node:crypto").randomBytes(32).toString("base64url");
const start = await fetch(route + "/google?challenge=" + challenge, {redirect: "manual"});
assert.ok([302, 303].includes(start.status));
const location = new URL(start.headers.get("location"));
assert.equal(location.hostname, "accounts.google.com");
assert.equal(location.searchParams.get("client_id"), process.env.GOOGLE_CLIENT_ID);
assert.equal(location.searchParams.get("redirect_uri"), process.env.PUBLIC_ORIGIN + "/auth/google/callback");
}
verify().catch(() => { console.error("Foundry readiness or OAuth entry check failed"); process.exit(1); });
verify().catch(() => { console.error("Foundry readiness or anonymous access check failed"); process.exit(1); });
'
# Keep the previous running container until the new candidate has passed checks.
@@ -70,4 +86,4 @@ docker rename "$candidate" "$live"
docker update --restart unless-stopped "$live" >/dev/null
bash "$(dirname "$0")/route.sh" "$live"
trap - EXIT
printf 'Foundry readiness, unauthenticated rejection and Google redirect verified.\n'
printf 'Foundry readiness and unauthenticated rejection verified.\n'