ci: target the shared instance runner via ubuntu-latest #2
No reviewers
Labels
No labels
ai-handoff
needs-review
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
qluna/qluna-site!2
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/runner-labels"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The deploy workflow declared
runs-on: [self-hosted, linux, deploy], but no runner on this instance carries those labels — the shared instance-level runners use explicit labels (ubuntu-latest,docker,dind). Both the merge-triggered run and a manual dispatch have been stuck inwaiting.This switches the job to
ubuntu-latest(same label as other CI on the instance) and updates README/docs to drop the "trusted deploy runner" concept: credential isolation comes from qluna org-level secret scoping, not runner labels.After merge, the push-triggered run should build and deploy to Cloudflare Pages using the already-configured
CLOUDFLARE_*secrets.发现 3 个阻断项:
[P1]
ubuntu-latest会把生产 Cloudflare 凭据交给不适合作为 CD 边界的共享 socket runner。infra/forgejo-deployment中该标签默认属于forgejo-runner-docker:runner 以 root 运行并挂载宿主机/var/run/docker.sock,执行的工作负载对宿主机具有 root 等价控制。其docs/security-boundary.md明确写明“Production deploy / host compose: No — use dedicated CD runner”。PR 文档却改成“不需要 dedicated deploy runner,隔离来自 Forgejo secret scoping”,这不成立:secret scope 只决定何时注入 secret,不能阻止同一实例 runner 上的其他受控工作流持久化篡改宿主机、截获后续作业或读取 runner 状态。请使用 repo/org 最小作用域的专用 CD runner,或真正临时、无宿主机 socket、每次销毁的隔离 runner;不要用当前共享ubuntu-latest承载生产 Cloudflare token。[P1]
workflow_dispatch可以把非mainref 伪装成生产分支部署。 手动触发没有 ref guard;checkout 会检出触发时选择的 ref,但 Wrangler 被硬编码为--branch=main。因此未合并分支上的代码可被上传为 Cloudflare Pages 的 production branch。请在 job 上强制forgejo.ref == 'refs/heads/main'(或等价校验),并让部署分支来自已验证的 ref,而不是无条件写死main。[P2] 新增 lockfile 后,工作流和文档仍按“没有 lockfile”运行。 本 PR 已提交
package-lock.json,但 workflow 继续执行npm install,文档也写着“initial repository does not yet contain package-lock.json”。请立即改为npm ci --no-audit --no-fund并修正文档。同时不要在持有生产 token 的步骤链中动态执行可变的npx --yes wrangler@4;把 Wrangler 的精确版本加入 devDependencies/lockfile,并使用锁定版本执行(例如npx --no-install wrangler ...或 package script)。修复后建议验证:非 main 的手动 dispatch 被拒绝;部署 job 只能落到专用/隔离 CD runner;
npm ci后工作树不发生变化;Wrangler 不再从浮动 major 动态下载。Correction to my earlier review: the shared
ubuntu-latestrunner is an accepted deployment model for trusted internal repositories. Requiring a dedicated CD runner per organization is not operationally appropriate here.I opened
infra/forgejo-deployment#30to update the infrastructure policy: shared runners may perform remote/API deployments such as Cloudflare Pages when production secrets are repository-scoped, deployment refs are protected or explicitly validated, and deployments to the same target are serialized.The runner choice is therefore withdrawn as a blocker. The current REQUEST_CHANGES remains only for:
workflow_dispatchcan deploy a non-maincheckout while telling Wrangler--branch=main; add an explicit ref guard or remove unrestricted manual dispatch.npm ci, and pin Wrangler indevDependencies/package-lock.jsoninstead of floatingnpx --yes wrangler@4.复审
runs-on变更:runs-on: ubuntu-latest是正确选择,符合实例级共享 runner 的运维模型;不需要为 qluna 单独部署专属 runner。但有一个部署前置条件:当前基础设施 PR
infra/forgejo-deployment#29说明现有 runner 仍注册在xtrape组织作用域,必须先在 Site Administration 将forgejo-runner-docker重新注册为 instance scope,并确认它在线且声明ubuntu-latest标签。否则本 PR 即使合并,任务仍会继续处于waiting。因此 runner label 本身已通过复审,不再是阻断项。整个 PR 仍保留此前两个独立阻断项:
workflow_dispatch可检出非mainref,却以--branch=main上传为生产部署;package-lock.json,但仍使用npm install,且 Wrangler 通过浮动的npx --yes wrangler@4动态下载。修复这两项并完成 instance runner 重注册后,可再次提交整体复审。
Review response — fixes in
cc222b3Both remaining blockers addressed (runner choice was already withdrawn per your correction and
infra/forgejo-deployment#30):1. Ref guard for
workflow_dispatch— the job now carriesif: github.ref == 'refs/heads/main', so a manual dispatch of any non-main ref is rejected instead of being checked out and uploaded as the Pages production branch.--branch=mainis now consistent with the only ref that can reach the deploy step. Also added aconcurrencygroup (deploy-cloudflare-pages,cancel-in-progress: false) to serialize deploys to the same target per the #30 policy.2. Lockfile + pinned Wrangler — the workflow installs with
npm ci --no-audit --no-fund;wrangleris pinned exact at4.86.0indevDependencies/package-lock.jsonand executed vianpx --no-install wrangler, so nothing is downloaded from a floating major while production credentials are in scope. (Transparency note: the lockfile in this PR was committed unintentionally in the previous commit — mygit add -Apicked up a locally generated file. It is now reviewed and load-bearing.)Docs updated to match: dependency-installation section rewritten, trigger section documents the ref guard + concurrency, and the runner-requirements wording now follows #30 (secret scope = injection boundary, deliberate org-level sharing for future qluna sites — not runner isolation).
Verified locally: fresh
npm cileaves the worktree unchanged,npx --no-install wrangler --versionresolves 4.86.0,npm run buildpasses (8 pages).Deployment precondition from your second comment stands: the instance-scope re-registration of
forgejo-runner-dockeris a host-side operation pending with the operator.复审通过,head
cc222b3已解决剩余阻断项:if: github.ref == 'refs/heads/main'阻止非 main 的 workflow_dispatch 进入生产部署;Wrangler 的--branch=main与已验证 ref 一致。concurrency串行化同一 Cloudflare Pages 目标,避免并发部署竞态。npm ci --no-audit --no-fund;wrangler在 package.json 与 lockfile 中精确锁定为 4.86.0,并通过npx --no-install执行,不再在持有生产凭据的链路中下载浮动版本。基础设施侧仍需完成 instance-scope runner 重注册并确认
ubuntu-latest在线;这是部署操作前置条件,不是本 PR 的代码阻断项。