oss-ci

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Continuous integration setup

持续集成设置

Decide what runs on push and on every change request, then write it in the syntax the project's forge understands. The decisions in this file are forge-independent: detect the ecosystem, decide what needs to run, choose a matrix, decide caching. The syntax that expresses those decisions is not, so it lives in references/github-actions.md for GitHub Actions and references/gitlab.md for GitLab CI/CD. Read the matching reference file before writing any configuration; do not write one forge's syntax by translating the other's keywords, because the two have different shapes for triggers, matrices, and caching. What differs by ecosystem rather than by forge, the setup action or image, the cache directory and its key, and the test command, lives in
references/ecosystems/
, one file per ecosystem, routed from Step 2.
先决定在 push 和每次变更请求(pull request 或 merge request)时运行哪些内容,然后用项目的 forge(代码托管平台)能够理解的语法写出来。本文件中的决策与 forge 无关:检测 ecosystem、决定需要运行的内容、选择 matrix、决定 caching。用于表达这些决策的语法则与 forge 相关,因此 GitHub Actions 的语法位于 references/github-actions.md,GitLab CI/CD 的语法位于 references/gitlab.md。在编写任何配置前,先阅读匹配的 reference 文件;不要通过逐一替换另一个 forge 的 keyword 来编写配置,因为二者在 trigger、matrix 和 caching 方面的结构不同。与 forge 无关而由 ecosystem 决定的内容——setup action 或 image、cache 目录及其 key、test 命令——位于
references/ecosystems/
,每个 ecosystem 一个文件,从步骤 2 路由到相应文件。

Scope

范围

The CI rules belong here: R-CI-01 triggers, R-CI-02 project commands, R-CI-03 version matrix, R-CI-04 cache keying, R-CI-05 timeouts and cancellation, and R-CI-06 test suite.
When
oss-audit-report.md
exists at the repository root, read the group addressed to this skill and work from that. Each failing rule there carries the audit's evidence and that rule's
Check:
text verbatim, so reading
STANDARD.md
as well adds nothing. Where the file is absent, work from the request as usual.
This skill owns what runs: which checks execute, on which triggers, across which versions, with what caching. It shares the workflow and pipeline files it writes with two other skills, and the boundary between them is the rule area, not a description of files.
The SEC rules, security posture of the same files such as pinned action SHAs, minimal permissions, dependency updaters, branch protection, and pinned images, belong to oss-harden. The REL rules, publishing a built artifact to a registry with trusted publishing, provenance, and an approval gate, belong to oss-publish. Do not add a
permissions:
block, pin a SHA, configure branch protection, or write a publish job while working from this skill; note that the project needs it and hand the work to the owning skill. A GitHub Pages deploy is the single exception, and it covers only the two blocks references/github-actions.md already emits: top-level
contents: read
, and
pages: write
plus
id-token: write
on the deploying job. Those grants are how the deployment authenticates, so a workflow written without them cannot run at all, and stripping them to honour the ban ships a green pipeline that deploys nothing. Every other permissions question still goes to
oss-harden
.
oss-writing
is not one of those hand-offs. It owns no rule area and takes no work over, so nothing here is handed to it. Read it before writing a branch name, a commit message, a change request title or description, or an issue, which is all of what this skill leaves behind on the forge.
Deploying a built static site to the forge's own Pages hosting is also something that runs on a push, so it stays here rather than with oss-publish, which owns registry releases. No rule requires it: a project publishes a site because it has one, so it is written only where the repository builds a site and the user asks for the deployment.
以下 CI 规则由本 skill 负责:R-CI-01 trigger、R-CI-02 项目命令、R-CI-03 版本 matrix、R-CI-04 cache key、R-CI-05 timeout 与取消、R-CI-06 test suite。
当仓库根目录存在
oss-audit-report.md
时,读取其中分配给本 skill 的规则组,并以该文件为准。该文件中的每条失败规则都附有 audit 的证据,并逐字包含该规则的
Check:
文本,因此再读取
STANDARD.md
不会增加任何信息。如果该文件不存在,则照常根据请求执行。
本 skill 负责运行哪些内容:执行哪些检查、由哪些 trigger 触发、覆盖哪些版本,以及如何使用 caching。它编写的 workflow 和 pipeline 文件还由另外两个 skill 共用;这些 skill 之间的边界按规则区域划分,而不是按文件描述划分。
SEC 规则、同一批文件的安全配置,例如固定 action SHA、最小权限、dependency updater、branch protection 和固定 image,属于 oss-harden。REL 规则,包括使用 trusted publishing 将构建产物发布到 registry、provenance 和 approval gate,属于 oss-publish。在本 skill 中工作时,不要添加
permissions:
块、固定 SHA、配置 branch protection 或编写 publish job;应指出项目需要这些配置,并将工作移交给对应的 skill。GitHub Pages 部署是唯一的例外,它仅涵盖 references/github-actions.md 已输出的两个块:顶层的
contents: read
,以及部署 job 上的
pages: write
和
id-token: write
。这些授权是部署进行身份验证的方式,因此没有它们,workflow 将完全无法运行;而为了遵守禁令而删除它们,只会产出一条显示成功却未部署任何内容的 pipeline。其他所有 permissions 问题仍应交给 oss-harden。
oss-writing
不属于上述移交范围。它不负责任何规则区域,也不接收任何工作,因此这里没有内容需要移交给它。在编写 branch name、commit message、change request 标题或描述或 issue 之前,应先读取该 skill;这些都是本 skill 在 forge 上留下的内容。
将构建后的静态站点部署到 forge 自带的 Pages 托管服务,也属于会在 push 时运行的内容,因此应保留在这里,而不是交给负责 registry release 的 oss-publish。没有规则强制要求这样做:项目可能因为拥有站点而发布它,所以只有当仓库会构建站点且用户要求部署时,才应编写相应配置。

Principles

原则

Verify everything before adding a step, a secret, or a config value: read the actual repository rather than guessing at its shape. Ask when something is uncertain instead of inventing a plausible answer.
Call the project's own automation instead of writing shell logic inside the pipeline. A step that runs
npm test
instead of
jest --coverage --ci
keeps the pipeline and a contributor's laptop running the same command, which is what R-CI-02 checks for. When no such automation exists, ask whether to add it to the project or fall back to inline commands.
Present policy choices instead of guessing at them, even when the repository already contains tests, a Dockerfile, or a pipeline. What runs on a change request, what triggers a release build, and how deployment happens are decisions the user makes; code only tells you what is possible, not what is wanted.
在添加 step、secret 或 config value 之前,验证所有相关情况:读取实际仓库,而不是猜测其结构。如果存在不确定之处,应主动询问,不要臆造看似合理的答案。
调用项目自身的 automation,而不是在 pipeline 中编写 shell 逻辑。运行
npm test
而不是
jest --coverage --ci
,可以确保 pipeline 和贡献者的本地环境执行相同命令,这正是 R-CI-02 检查的内容。如果不存在此类 automation,应询问是将其添加到项目中,还是退回到使用内联命令。
应提供策略选项供用户决定,而不是自行猜测,即使仓库已经包含 tests、Dockerfile 或 pipeline 也应如此。变更请求上运行哪些内容、什么触发 release build,以及如何进行 deployment,都是由用户决定的;代码只能说明有哪些可能性,而不能说明用户想要什么。

Two ways in

两种进入方式

The request decides which one runs. Read it before starting the process below.
To set up CI, or to extend what a project already has, run Steps 1 to 8 in order.
To review CI without changing it, run Steps 1 and 2, then stop and report. Read the existing workflow or pipeline against each R-CI rule's
Check:
line and against the reference file for its forge. Report every check that fails, anchored at the file and line it fails at, and name what would fix it. Change no file unless the user asks for the fix after reading the report.
根据请求选择其中一种。开始下面的流程前先阅读相应说明。
如果要设置 CI 或扩展项目已有内容,请按顺序执行步骤 1 到步骤 8。
如果要审查 CI 但不进行修改,请执行步骤 1 和步骤 2,然后停止并报告。根据每条 R-CI 规则的
Check:
行以及对应 forge 的 reference 文件,检查现有 workflow 或 pipeline。报告每一项未通过的检查,指出失败所在的文件和行,并说明应如何修复。除非用户在阅读报告后要求修复,否则不要修改任何文件。

Process

流程

Step 1: Detect the forge

步骤 1:检测 forge

Look for an existing
.github/workflows/
directory or
.gitlab-ci.yml
file, check the git remote for a github.com or gitlab host, or ask directly if neither signal is present. This decides which reference file governs Steps 6 and 7. If the user states the forge explicitly, trust that over any signal found in the repository.
查找现有的
.github/workflows/
目录或
.gitlab-ci.yml
文件,检查 git remote 是否指向 github.com 或 gitlab 主机;如果两者都没有信号,则直接询问用户。这将决定步骤 6 和步骤 7 应使用哪个 reference 文件。如果用户明确说明了 forge,应优先采信用户陈述,而不是仓库中发现的任何信号。

Step 2: Analyze the repository

步骤 2:分析仓库

Identify the language and runtime from source files and the package manifest, and note the version range the project claims to support; the matrix in Step 4 has to cover all of it, including the oldest and newest supported version, per R-CI-03.
Detect every ecosystem the repository has a signal for, not only the one it ships. A manifest that exists only for development still gets installed in CI, so a Go tool with a documentation
package.json
needs a Node toolchain, cache, and test command as much as it needs the Go ones. Read the file below for each ecosystem found, and read no others.
Signal in the repositoryRead
package.json
references/ecosystems/npm.md
pyproject.toml
,
setup.py
,
setup.cfg
references/ecosystems/pypi.md
a
.gemspec
,
Gemfile
references/ecosystems/rubygems.md
Cargo.toml
references/ecosystems/crates.md
go.mod
references/ecosystems/go-modules.md
composer.json
references/ecosystems/packagist.md
a
.csproj
,
.fsproj
, or
.vbproj
references/ecosystems/nuget.md
pom.xml
,
build.gradle
,
build.gradle.kts
references/ecosystems/maven-central.md
mix.exs
references/ecosystems/hex.md
pubspec.yaml
references/ecosystems/pubdev.md
a workflow or pipeline pushing an image to a registry, or an existing image on the forge's registryreferences/ecosystems/containers.md
A lockfile with no manifest beside it is the same signal, and the roster names those too.
skills/oss-audit/ecosystems.json
is the canonical list; where this table and that file disagree, the file wins.
Find every applicable lint, test, typecheck, and build command the project already defines, whether that is package manager scripts, a Makefile, a Rakefile, or a tool like tox or just, and read them closely enough to know their arguments and side effects. Do not invent a missing class of check: a documentation repository may have no build, and a small script may have no linter. Where the repository ships executable code and defines no test suite at all, that is an R-CI-06 gap rather than a class of check this project does without, so raise it and ask whether to add a suite instead of writing CI that runs nothing. If the repository has a CONTRIBUTING guide, its commands and the project automation must agree; resolve any conflict before copying either into CI.
Read any existing CI configuration before changing it, so you know whether to extend it or replace it.
Identify every lockfile the project commits. The roster records which lockfiles each ecosystem's tooling produces, and whether it produces one at all; the ecosystem file names the download directory an install command can safely reuse and the file that keys it. Do not assume an installed dependency directory is a cache.
Find
.env.example
and search the source for required environment variables, so a step needing a secret is identified before generation rather than after a failed run.
根据源文件和 package manifest 识别语言与 runtime,并记录项目声称支持的 version range;按照 R-CI-03,步骤 4 中的 matrix 必须覆盖整个范围,包括最旧和最新的受支持版本。
检测仓库中存在信号的每一种 ecosystem,而不只是项目实际发布的那一种。即使 manifest 仅用于开发,其依赖仍会在 CI 中安装,因此,带有文档用
package.json
的 Go 工具既需要 Go toolchain、cache 和 test 命令,也需要 Node toolchain、cache 和 test 命令。每发现一种 ecosystem,就读取下表对应的文件,不读取其他文件。
仓库中的信号读取
package.json
references/ecosystems/npm.md
pyproject.toml
、
setup.py
、
setup.cfg
references/ecosystems/pypi.md
.gemspec
、
Gemfile
references/ecosystems/rubygems.md
Cargo.toml
references/ecosystems/crates.md
go.mod
references/ecosystems/go-modules.md
composer.json
references/ecosystems/packagist.md
.csproj
、
.fsproj
或
.vbproj
references/ecosystems/nuget.md
pom.xml
、
build.gradle
、
build.gradle.kts
references/ecosystems/maven-central.md
mix.exs
references/ecosystems/hex.md
pubspec.yaml
references/ecosystems/pubdev.md
将 image 推送到 registry 的 workflow 或 pipeline,或 forge 的 registry 中已有 imagereferences/ecosystems/containers.md
如果存在 lockfile,但旁边没有 manifest,这也算作相同信号,清单中也列出了这些情况。
skills/oss-audit/ecosystems.json
是规范列表;如果此表与该文件不一致,以该文件为准。
找出项目已经定义的所有适用 lint、test、typecheck 和 build 命令,无论它们来自 package manager script、Makefile、Rakefile,还是 tox、just 等工具;应充分阅读这些命令,以了解其参数和副作用。不要臆造缺失的检查类别:documentation repository 可能没有 build,小型 script 可能没有 linter。如果仓库提供 executable code,却完全没有定义 test suite,这属于 R-CI-06 缺口,而不是项目本来就没有某类检查;应指出这一点,并询问是否添加 test suite,而不是编写一个什么都不运行的 CI。如果仓库包含 CONTRIBUTING guide,其中的命令必须与项目 automation 保持一致;在将任何一方复制到 CI 之前,先解决冲突。
修改现有 CI 配置前先读取它,以确定应当扩展还是替换。
找出项目提交的所有 lockfile。清单记录了每种 ecosystem 的 tooling 会生成哪些 lockfile,以及是否生成 lockfile;对应的 ecosystem 文件会指出 install command 可以安全复用的下载目录,以及用于设置 key 的文件。不要将已安装的依赖目录视为 cache。
查找
.env.example
,并在源代码中搜索必需的环境变量,以便在生成配置前就确定哪些 step 需要 secret,而不是在运行失败后才处理。

Step 3: Present findings and ask

步骤 3:汇报发现并询问

Summarize what Step 2 found, then ask about the choices code alone cannot answer: what should run on a pull or merge request, what should trigger a release build, and whether existing CI should be extended or replaced. Ask only what applies to this project; a project with no Dockerfile gets no question about a registry.
Where Step 2 found a build that produces a static site, ask whether it should also deploy, and to where. A site can be built as a check and never published, so treat a static build as a question rather than as consent to deploy one.
总结步骤 2 的发现,然后询问代码本身无法回答的选项:pull request 或 merge request 上应运行什么,什么应触发 release build,以及现有 CI 应扩展还是替换。只询问与该项目相关的问题;没有 Dockerfile 的项目不需要询问 registry 相关事项。
如果步骤 2 发现某个 build 会生成静态站点,应询问是否也要部署,以及部署到哪里。站点可以作为检查项进行构建,但不一定发布,因此应将静态构建视为一个需要确认的问题,而不能将其视为部署许可。

Step 4: Choose the matrix

步骤 4:选择 matrix

Build the version matrix from the supported release lines identified in Step 2, not from a single pinned version. The ecosystem file read there says where the support claim lives in that ecosystem's manifest and which setup action or image installs the version. Include every maintained major or minor release line the project claims to support. A project with no stated support range gets a single-version pipeline instead of an invented matrix; do not manufacture support claims the manifest does not make. If a range is continuous and includes release lines the project does not intend to support, fix the declared range rather than silently testing a subset.
根据步骤 2 中识别出的受支持 release line 构建 version matrix,而不是只使用一个固定版本。对应的 ecosystem 文件会说明支持范围声明位于 manifest 的哪个位置,以及应使用哪个 setup action 或 image 安装版本。应包含项目声称支持的每个仍在维护的 major 或 minor release line。如果项目没有声明支持范围,则使用单版本 pipeline,不要创建臆造的 matrix;不要生成 manifest 中不存在的支持声明。如果某个范围是连续的,却包含项目不打算支持的 release line,应修正声明的范围,而不是在测试中静默地只覆盖一个子集。

Step 5: Decide caching

步骤 5:决定 caching

Cache only package-manager download data or another directory the tool's official documentation says is safe to reuse. Where the forge ships a first-party mechanism that caches the detected package manager's data and keys on the lockfile, prefer it; the ecosystem file names it, what it actually caches, and what it keys on by default, which is not always the lockfile. Otherwise key an explicit cache on the lockfile plus every compatibility boundary that changes its contents, such as the operating system, architecture, runtime, and package manager. A fallback key is optional and must not cross one of those boundaries. A project with no lockfile or no reusable download cache gets no cache step.
只缓存 package manager 的下载数据,或工具官方文档明确说明可以安全复用的其他目录。如果 forge 提供第一方机制来缓存检测到的 package manager 数据并根据 lockfile 设置 key,应优先使用该机制;对应的 ecosystem 文件会指明具体机制、实际缓存内容以及默认 key,而默认 key 不一定是 lockfile。否则,应根据 lockfile 以及所有会改变缓存内容的兼容性边界来设置显式 cache 的 key,例如操作系统、架构、runtime 和 package manager。fallback key 是可选的,并且不能跨越上述任何边界。如果项目没有 lockfile,也没有可复用的下载缓存,则不应添加 cache step。

Step 6: Write the configuration

步骤 6:编写配置

Open the reference file for the forge chosen in Step 1 and follow its syntax exactly. Open only that one. The other forge's file has no syntax this run can use, and reading it costs the run its context for nothing.
Each reference file covers triggering on push to the default branch and on every change request (R-CI-01), a timeout on every job with cancellation of superseded runs on the same branch (R-CI-05), and the cache decisions from Step 5 (R-CI-04). Each also carries a Pages deployment section, used only when Step 3 established that the project wants one. Neither file covers permissions, SHA pinning, or publishing; those stay out of the file you write here.
Order jobs and steps so a fast check fails before a slow one starts: lint before test, test before build. This holds on either forge.
打开步骤 1 所选 forge 的 reference 文件,并严格遵循其中的语法。只打开这一个文件。另一个 forge 的文件不包含本次运行可用的语法,读取它只会无意义地消耗运行上下文。
每个 reference 文件都涵盖推送到默认分支以及每次 change request 时的 trigger(R-CI-01)、每个 job 的 timeout,以及取消同一分支上被取代的运行(R-CI-05),并包含步骤 5 的 cache 决策。每个文件还包含 Pages 部署部分,仅在步骤 3 确认项目需要部署时才使用。两个文件都不涵盖 permissions、SHA 固定或发布;这些内容不应写入此处生成的文件。
安排 job 和 step 的顺序,让快速检查在慢速检查启动之前失败:先 lint,再 test,最后 build。这一点适用于两种 forge。

Step 7: Validate before presenting

步骤 7:展示前进行验证

Confirm the configuration is syntactically valid with the forge's own validator where one is available, and confirm that every command it calls exists and succeeds locally in the same order. For GitLab, use CI Lint with included configuration expanded. For GitHub, inspect the workflow in the Actions editor or push it on a branch when the user has authorized that external change; a generic YAML parser cannot validate GitHub expressions or workflow semantics. List any secrets the pipeline needs, with the command to add each one, without running that command. The forge's CLI need not be installed here, because the command is printed for the repository owner to run on their own machine. Confirm the matrix matches every supported release line and that every job carries a timeout and participates in cancellation of superseded runs when safe.
如果 forge 提供自己的 validator,应使用它确认配置在语法上有效;同时确认它调用的每个命令都存在,并按相同顺序在本地成功执行。对于 GitLab,使用展开 include 配置后的内容运行 CI Lint。对于 GitHub,在 Actions editor 中检查 workflow,或者在用户授权这项外部变更后将其推送到分支;通用 YAML parser 无法验证 GitHub expressions 或 workflow 语义。列出 pipeline 所需的全部 secret,以及添加每个 secret 对应的命令,但不要运行这些命令。此处不必安装 forge 的 CLI,因为这些命令会输出给仓库所有者在其自己的机器上执行。确认 matrix 覆盖每个受支持的 release line,并确认每个 job 都设置了 timeout,且在安全的情况下支持取消同一分支上被取代的运行。

Step 8: Present the result

步骤 8:展示结果

Before presenting, read each R-CI rule's
Check:
line in
skills/oss-audit/STANDARD.md
(from the plugin root, like the roster in Step 2) against the configuration as it now stands, and fix what fails. The file is long: read only its R-CI section. Start the list again after each fix, and do not report done while any cited rule still fails. On GitHub there is no local validator, so this reference-plus-checklist pass is the validator, and the loop terminates when every cited rule passes rather than when the file looks finished.
Then show the generated file, a short summary of what was detected and decided, the list of secrets to configure, and anything left for the user to set at the repository or project level, such as branch protection or environment approvers, naming the skill that owns it rather than attempting it here.
展示结果前,从 plugin root 读取
skills/oss-audit/STANDARD.md
中每条 R-CI 规则的
Check:
行,位置与步骤 2 中的清单相同,并根据当前配置逐项检查,修复未通过的内容。该文件很长:只读取其中的 R-CI 部分。每次修复后从头重新检查;在任何已引用规则仍未通过时,不要报告任务已完成。GitHub 没有本地 validator,因此这个“reference 加 checklist”的检查过程就是 validator;循环应在每条已引用规则都通过后结束,而不是在文件看起来已经完成时结束。
然后展示生成的文件、检测结果与所做决策的简要说明、需要配置的 secret 列表,以及仍需用户在仓库或项目级别设置的内容,例如 branch protection 或 environment approver;同时指出负责这些事项的 skill,而不要在此处尝试处理。