☰
Decepticon 发布流程全解:从 SemVer 标签到多架构镜像签名与渠道发布的自动化管线
2026/10/12 3:20:58 网站建设 项目流程

【免费下载链接】Decepticon

Autonomous Hacking Agent for Red Team

项目地址:https://gitcode.com/gh_mirrors/de/Decepticon
点击查看免费下载

本篇技术指南以 Decepticon 仓库的 RELEASE.md 为核心,完整讲解该项目"版本如何确定、如何打标签、CI 如何构建发布"的端到端工程实践:包括0.0.0哨兵版本与构建期盖章机制、手动/自动两种切版路径、覆盖 PyPI 与 GHCR 多镜像的发布工作流、Cosign 签名与 SBOM、digest 固定与:latest/:stable双渠道策略,以及失败恢复和子模块处理。读完本文,你将掌握如何为 Decepticon 打一个规范的 release 标签,并理解标签触发后整条自动化流水线的每一步行为。

版本策略:SemVer 与0.0.0哨兵版本

Decepticon 遵循 Semantic Versioning 规范,版本号采用vMAJOR.MINOR.PATCH(如v1.1.1),预发布版本带后缀(如v1.2.0-rc.1)。

一个关键设计是:源码树中的版本字段是永久的0.0.0哨兵(sentinel),而不是真实版本号。涉及的位置包括:

  • packages/decepticon/pyproject.toml(第 7 行为version = "0.0.0")
  • clients/cli/package.json 与 clients/web/package.json("version": "0.0.0")

真实版本在构建期由 git 标签盖章写入,而不是靠一次"版本号提交":

  • PyPI 侧:release.yml中的publish-pypijob 先用sed把工作区所有pyproject.toml的version从哨兵改写为标签版本,再执行uv build --all-packages构建三个工作区包(decepticon-core、decepticon、decepticon-sdk)。
  • Docker 侧:--build-arg VERSION=<tag>传入镜像构建,containers/cli.Dockerfile、containers/langgraph.Dockerfile、containers/web.Dockerfile 内部再以sed将哨兵替换为真实版本(例如 cli 镜像改写clients/cli/package.json,web 镜像同时改写 web 与 cli 两份 package.json)。

因此打标签之前不需要任何 version-bump 提交,git log保持干净,版本信息全部收敛在 git tag 这一单一事实来源上。

手动切版:标准发布操作步骤

当需要手动发布一个版本时,按以下顺序执行(对应 RELEASE.md 的 "Cutting a release" 章节):

  1. 确认main分支为绿色、工作区干净。
  2. 运行本地质量门禁:
    make quality # Python + CLI + Web:lint、类型检查、测试 make smoke # Compose 构建 + 服务健康检查

    其中make quality对应 Makefile 中的quality: ci-lint ci-test quality-cli web-lint web-build,它镜像 CI 的 PR 车道(errors-only 类型检查 + 快速 pytest + CLI + Web);make smoke则执行 Compose-only 的发布形态检查(清理状态 → 本地代码构建镜像 →up -d --no-build --wait→ 健康检查),它刻意不使用 launcher,是最快的发布前置检查。

  3. 可选:运行make dogfood,它做一次完整的"launcher → onboard → 启动 → CLI"端到端冒烟测试。该目标会把docker-compose.yml、config/、containers/、.env.example符号链接到.dogfood/隔离的DECEPTICON_HOME,镜像统一打:dev标签并从本地代码构建,确保"测试的就是将要发布的东西"。
  4. 在 CHANGELOG.md 中,把[Unreleased]条目归入新的[X.Y.Z] — YYYY-MM-DD标题下,并在文件底部添加 compare 链接(当前 changelog 最新条目为[1.2.2] — 2026-10-03,格式遵循 Keep a Changelog)。
  5. 提交 changelog(提交信息docs: release vX.Y.Z)。
  6. 打标签并推送:
    git tag vX.Y.Z git push origin main --tags

推送v*标签即触发 .github/workflows/release.yml 的完整发布流水线。

自动切版:基于 Conventional Commits 的 auto-tag

多数情况下不需要手工打标签。每当有推送进入main,自动打标签流程会根据自上一个标签以来的 Conventional Commits判断是否值得发版,并调用 scripts/next_version.py 计算下一个版本号、自动推送vX.Y.Z标签:

自上个标签以来的提交类型版本号提升
feat:/feat(scope):minor(X.Y+1.0)
fix:/perf:/revert:patch(X.Y.Z+1)
type!:或含BREAKING CHANGE:footermajor(X+1.0.0)
仅有docs/chore/ci/test/refactor不发版

从 scripts/next_version.py 的源码可以确认这套分类逻辑的实现细节:脚本读取 stdin 中的提交信息,_BREAKING_TYPE正则匹配type!:或type(scope)!:的破坏性标记,BREAKING CHANGE出现即直接判定 major;否则按feat→ minor、fix/perf/revert→ patch 的优先级累加(_RANK序:none < patch < minor < major,混用时取最强级别)。bump()对MAJOR.MINOR.PATCH三段逐一加一并清零低位;脚本以退出码为信号:0且 stdout 输出新版本号 → 打标签;1无输出 → 跳过发版。

auto-tag 只负责推送标签,从不构建或发布——标签随后驱动与手动流程相同的release.yml管线,因此发布原子性(全部镜像就绪后才推进:latest)不受影响。

全自动发布的一次性配置:RELEASE_PLEASE_TOKEN

GitHub 会抑制用默认GITHUB_TOKEN推送的标签触发工作流。要实现"合入 main 自动发版"的全自动闭环,需要添加仓库级 secretRELEASE_PLEASE_TOKEN(一个具有contents: write权限的 fine-grained PAT),使 auto-tag 推送的标签能够触发release.yml。

关键约束:未配置该 PAT 时,标签仍会被正确创建,但release.yml不会自行构建该标签——用GITHUB_TOKEN推送的标签不触发工作流。此时可让维护者手动重新推送一次:

git push origin :refs/tags/vX.Y.Z # 删除远端标签 git push origin vX.Y.Z # 重新推送 → 触发 release.yml

注意 .github/workflows/release-recover.yml 在这里起不到作用:它只校验已构建好的镜像并收尾发布,从不负责构建。配置好 PAT 之后,未来的每个 auto-tag 都会自动触发构建;手动git tag流程仍可用于计划外的(out-of-band)发布。

release.yml:标签触发的完整发布管线

推送v*标签后,release.yml 并行执行多个 job,各 job 的职责与产物如下:

Job输出
publish-pypi构建 wheel + sdist,通过Trusted Publishing(OIDC,无需 API token)将decepticon包发布到 PyPI。
launcher用 GoReleaser 构建 Go launcher 二进制(并起草 GitHub release),上传config-checksums.txt——针对docker-compose.yml、config/litellm.yaml、.env.example的 SHA-256 完整性清单。
docker构建并推送多架构的litellm、langgraph、cli、skillogy镜像。
docker-heavy/docker-heavy-merge在原生 amd64/arm64 runner 上构建sandbox与c2-sliver(Kali 基镜像在 QEMU 下太慢),再按平台 digest 合并为 manifest。
docker-web/docker-web-merge以同样方式构建并合并web镜像。
publish-release校验全部 7 个:<version>镜像已存在于 GHCR,提升为:latest,并把 GitHub release 从草稿翻转为已发布。

几个值得展开的工程细节:

  • 原子发布门禁:publish-releasejob 依赖launcher、docker、docker-heavy-merge、docker-web-merge全部成功后执行;它用docker buildx imagetools inspect逐个校验 7 个:<version>镜像(litellm、langgraph、sandbox、cli、skillogy、c2-sliver、web)存在,然后才把:<version>提升为:latest并解除 release 草稿。因此在全部镜像验证通过之前,releases/latest接口与:latest标签都不会指向半成品。
  • 重镜像拆分构建:web 镜像的 arm64 模拟构建曾占整个发布约 21 分钟,Kali 基 + 约 25 个 apt 包的 sandbox/c2-sliver 在 QEMU 下更糟,因此这三类镜像被拆到ubuntu-24.04-arm原生 runner 上按平台构建(push-by-digest=true),再由 merge job 用docker buildx imagetools create将各平台 digest 缝合为多架构 manifest。
  • 配置完整性清单:config-checksums.txt的引入源于供应链安全考量——OSS 安装器与 launcher 自更新会从 raw 地址下载 compose 文件并直接应用,缺少完整性校验会把 GitHub CDN 篡改放大为一次性 RCE 向量;因此发布流水线用sha256sum生成清单作为 release asset,clients/launcher/internal/updater/updater.go 中的ConfigManifestAsset = "config-checksums.txt"常量表明 launcher 下载每个配置文件前都会对照该清单校验。

签名与软件物料清单(SBOM)

流水线对每个镜像执行两层供应链保护:

  • Cosign keyless 签名(OIDC):基于 Sigstore 的无密钥签名,无需长期密钥。release.yml 的dockerjob 在推镜像后执行cosign sign,docker-heavy-merge/docker-web-merge则对合并后的 manifest 签名。
  • CycloneDX SBOM:每个镜像通过 anchore/sbom-action 生成 CycloneDX JSON SBOM,并作为 release 产物上传。

一个值得注意的边界情况:decepticon-sandbox的 SBOM 约 7 MB(Kali rolling 基 + 完整渗透工具链 → 数千 dpkg 组件),超出 Sigstore Rekor 透明日志单条约 5 MiB 的上限,会被确定性拒绝,因此该镜像使用--tlog-upload=false仅将 SBOM attestation 附加到 OCI artifact(验证者仍可对 registry 执行cosign verify-attestation)。其余镜像保留 Rekor 上传,并包裹 5 次线性退避重试以吸收瞬时 Rekor 5xx;最终失败仅产生 workflow 警告而不阻断发布——镜像已签名且 SBOM 文件已作为产物上传。

Digest 固定:不可变、防篡改的部署方式

发布完成后,.github/workflows/pin-digests.yml 在release: published事件上运行,解析每个镜像对应版本的manifest-list digest,并将image-digests.txt(每行一个镜像,形如ghcr.io/bittersecurity/<image>:<version>@sha256:<digest>)作为 release asset 上传。

需要不可变、防篡改部署的运维人员,可以把 compose 栈固定到 digest 形式,而不是随动的:stable/:latest渠道标签:

image: ghcr.io/bittersecurity/decepticon-litellm@sha256:<digest>

该 digest 是 manifest-list digest,因此覆盖所有已发布的平台架构。作为对照,docker-compose.yml 中默认使用:stable渠道标签(如ghcr.io/bittersecurity/decepticon-litellm:${DECEPTICON_VERSION:-stable})。

预发布版本的处理

包含连字符的标签(如v1.2.0-rc.1)被视为预发布:

  • GitHub release 被标记为 pre-release;
  • :latestDocker 标签不会被提升——现有:latest用户完全不受影响。

这与 docs/update-channels.md 描述的渠道模型一致:Decepticon 的:stable与:latest两个渠道都只交付正式版(从不自动选择预发布/测试版),区别仅在于烘焙(soak)延迟。:latest在每次正式发布时立即推进;:stable则由每日定时运行的 .github/workflows/promote-stable.yml 推进到"已在:latest上烘焙至少 7 天(可配置,且有 7 天下限)的最新的正式版"——对自主攻防工具而言,保守的stable默认渠道是更安全的选择。launcher 侧的渠道解析逻辑(ChannelStable/ChannelLatest、stableSoak注入式时间源)位于 clients/launcher/internal/updater/updater.go。

失败恢复:release-recover.yml

.github/workflows/release-recover.yml 是一个手动(workflow_dispatch)兜底工作流,用于当瞬时故障(registry 5xx、Sigstore Rekor 中断)导致发布进行到一半时,对已存在的标签重新执行发布收尾步骤:

  • 输入参数:version(不含前导v,如1.0.20)与promote_latest(预发布请设为false);
  • 行为:重新校验 7 个:<version>镜像是否存在 → 按需提升:latest→ 解除 GitHub release 草稿并正确设置 pre-release 标记。

它只做"校验 + 收尾",不会重新构建任何镜像;与pin-digests.yml一样遵循最小权限原则,工作流顶层仅声明contents: read,写入权限收敛在需要它的 job 上。

子模块:克隆后的必做步骤

仓库包含 git 子模块,clone 之后必须初始化:

git submodule update --init --recursive
  • benchmark/xbow-validation-benchmarks(由 .gitmodules 固定到上游 commit)是必选项,基准测试运行依赖它固定的上游版本;
  • benchmark/MHBench是可选项,仅在用到对应 benchmark provider 时才需要。

小结

Decepticon 的发布体系是一套"标签即事实来源、构建期盖章、CI 全自动、原子化收尾"的工程闭环:源码树常驻0.0.0哨兵版本,真实版本由 git tag 在 PyPI 构建与 Docker 构建时分别写入;常规合入 main 即可能由 auto-tag 自动打出下一个版本标签;标签触发release.yml并行完成 PyPI 三包发布、Go launcher 二进制、7 个多架构容器镜像的构建,并以 Cosign keyless 签名 + CycloneDX SBOM 提供供应链保障;所有:<version>镜像经publish-release校验后才整体提升:latest,再经pin-digests.yml提供 digest 级不可变引用,由每日promote-stable.yml按烘焙期推进:stable渠道;任何瞬时故障都可通过release-recover.yml手动收尾。这套设计对自托管发布流水线的读者具有直接的参考价值。

【免费下载链接】Decepticon

Autonomous Hacking Agent for Red Team

项目地址:https://gitcode.com/gh_mirrors/de/Decepticon
点击查看免费下载

相关推荐

上一篇:C++ WebServer内存管理最佳实践:Buffer类设计与资源释放
下一篇:AdGuard ContentBlocker社区贡献指南:如何提交过滤器规则与bug报告

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询