Gleam 编译器版本发布全流程指南:从版本号更新到 CI 自动发布
【免费下载链接】gleam⭐️ A friendly language for building type-safe, scalable systems!项目地址: https://gitcode.com/GitHub_Trending/gl/gleam
本篇指南围绕 Gleam 编译器仓库根目录下的 RELEASE.md 发布清单展开,系统梳理该开源项目从"代码就绪"到"用户拿到安装包"的完整发布链路。你将掌握版本号如何同步、make test build本地验证、Git 标签触发机制、CI 自动构建与发布草稿的生成原理,以及发布后如何交付容器镜像与补充文档,可直接用于维护该仓库或借鉴到自己的 Rust 项目发布流程中。
发布清单概览:一条 8 步的发布流水线
RELEASE.md 全文只有一份简洁的清单,但它浓缩了整个 Gleam 项目对外发版的全部动作。从仓库源码与工作流配置可以还原出,这份清单背后是一条"文档先行 → 版本同步 → 本地验证 → Git 标签触发 → CI 构建 → 人工确认发布 → 对外分享"的完整流水线。其 8 个步骤为:
- 在官网上撰写发布公告(release post)。
- 更新官网上的文档(语言服务器、gleam.toml 等)。
- 更新每个
Cargo.toml中的版本号。 - 运行
make test build。 - Git 提交、打标签、推送、推送标签。
- 等待 CI 发布构建完成。
- 在 GitHub 上从 CI 生成的草稿发布正式 Release。
- 分享官网发布公告。
下面结合仓库中的 Makefile、Cargo.toml、.github/workflows/release.yaml 等真实实现,逐条展开讲解每一步该做什么、为什么做、底层发生了什么。
第 1~2 步:发布公告与官网文档先行
清单把"写发布公告"和"更新文档"放在最前面,而不是放到代码改动之后,这体现了 Gleam 团队"发布即对外承诺"的做法:先确定本次版本对外讲述的故事(新特性、破坏性变更),再让代码与之一致。
- 发布公告:说明本次版本面向用户的核心亮点。仓库的 CHANGELOG.md 维护着未发布变更(
Unreleased区块),而 changelog/ 目录按版本存放v1.1.md~v1.18.md的历史变更记录,可以作为公告素材的直接来源。 - 文档更新:清单特别点名了语言服务器与
gleam.toml等主题。例如语言服务器的新能力对应的实现位于 language-server/src,配置项解析在 compiler-core/src/config.rs。凡是本次版本改动到的行为、配置项或命令,都要同步到官网文档,避免发布后用户读到过时说明。
这两步与后续第 8 步(分享公告)首尾呼应:先写好内容,最后再发布传播。
第 3 步:同步更新每个 Cargo.toml 的版本号
Gleam 编译器是一个 Cargo workspace,根目录 Cargo.toml 声明了 16 个成员 crate:
[workspace] resolver = "2" members = [ "gleam-bin", "compiler-cli", "compiler-core", "compiler-wasm", "language-server", "test-helpers-rs", "test-commands", "test-output", "test-package-compiler", "test-project-compiler", "hexpm", "pretty-arena", "format", "erlang-term-format", "erlang-generation", "src-span", ]发布时需要把这些成员 crate 的[package] version统一升到新版本号。以当前仓库为例,gleam-bin/Cargo.toml 中version = "1.18.0",且 compiler-cli、compiler-core、language-server、hexpm、compiler-wasm、format 等成员的版本号也全部是1.18.0——版本号一旦不同步,发布构建时依赖解析就可能出现版本混乱。这一步骤是后续 CI 生成安装包文件名(gleam-<版本>-<目标平台>.tar.gz)的依据。
第 4 步:本地跑通 make test build
版本号统一后,发布者要在本地执行完整验证。仓库根目录 Makefile 定义了这些目标:
make build:执行cargo build --release,产出 release 版编译器。make test:执行完整的编译器单测与集成测试链,包括cargo test --quiet、cargo clippy,以及test/language、test/javascript_prelude、test/project_erlang、test/project_javascript、test/project_deno、test/hextarball、test/typescript_declarations、test/running_modules、test/subdir_ffi等端到端项目测试。test目标实际覆盖了从 Erlang/JavaScript/Deno 目标代码生成到 TS 声明、子目录 FFI、hex tarball 导出的方方面面。
清单中的make test build相当于把上面两步串起来:先保证全量测试通过(make test),再确认 release 构建成功(make build)。发布者还可以用make help查看所有目标及说明,或用make test-watch(基于watchexec的文件变更监听)在迭代阶段快速回归。
第 5 步:Git 提交、打标签并推送
本地验证通过后进入 Git 操作:
git add -A git commit -m "Release v1.18.0" git tag v1.18.0 git push git push --tags标签名必须以v开头(如v1.18.0),因为 .github/workflows/release.yaml 的触发条件正是:
on: push: tags: - "v*"也就是说,推送v*标签是启动整条 CI 发布流水线的唯一开关。从源码结构看,标签命名还约定了一种特殊情况:若标签包含-rc(如v1.18.0-rc1),CI 创建 Release 时会自动加上--prerelease标记,作为预发布版本处理。
第 6 步:等待 CI 发布构建
推送标签后,release.yaml 会在 GitHub Actions 上启动build-release作业,构建矩阵覆盖:
| 目标平台 | 运行环境 | 构建工具 |
|---|---|---|
x86_64-unknown-linux-musl | ubuntu-latest | cross |
aarch64-unknown-linux-musl | ubuntu-latest | cross |
x86_64-apple-darwin | macos-15-intel | cargo |
aarch64-apple-darwin | macos-latest | cargo |
x86_64-pc-windows-msvc | windows-2022 | cargo |
aarch64-pc-windows-msvc | windows-11-arm | cargo |
wasm32-unknown-unknown | ubuntu-latest | wasm-pack |
具体构建逻辑封装在 .github/actions/build-release/action.yml 这个复合 Action 中,发布者等待期间可以理解 CI 在做什么:
- 构建与打包:非 WASM 目标通过
cross或cargo执行cargo build --release --target <目标>,产物命名为gleam-<版本>-<目标>.tar.gz(Windows 为.zip);WASM 目标用wasm-pack build --release --target web compiler-wasm产出gleam-<版本>-browser.tar.gz。 - 产物校验:用
file命令核对二进制架构与期望一致,并实际解包运行./gleam --version确认能正常启动。 - Windows 代码签名:通过 Azure Trusted Signing 对
gleam.exe进行 SHA256 签名并打 RFC3161 时间戳。 - 安全与合规产物:每个归档附带
.sha256、.sha512校验和;用cargo-sbom生成 SPDX 与 CycloneDX 两种格式的 SBOM;通过actions/attest生成 SLSA 供应链证明(.sigstore文件)。 - 许可证清单:Linux musl 构建还会在
licence-bundler目录下运行gleam run,生成随 Release 附带的gleam-licences.html。
从 .github/workflows/release.yaml 的RUSTFLAGS: "-D warnings"环境变量可以看出,发布构建对代码质量要求严格——任何警告都会直接导致构建失败。
第 7 步:从 CI 草稿发布正式 Release
当build-release作业在所有平台上成功后,create-release作业(needs: ['build-release'])会汇总下载所有release-*构建产物,并执行:
gh release create \ --repo "$REPOSITORY" \ --title "$TITLE" \ --notes "$NOTES" \ --draft \ --verify-tag \ ${{ contains(github.ref_name, '-rc') && '--prerelease' || '' }} \ "$TAG_NAME" \ gleam-*关键点解读:
--draft:CI 只会创建一个草稿 Release,不会直接公开。这正是清单第 6、7 步之间"人工确认"的意义——发布者需要等所有平台的产物齐全、检查附件无误后,再手动点击发布。--verify-tag:确保待发布的标签真实存在。--notes:Release 说明直接链接到该版本标签下的 CHANGELOG.md,因此第 4 步之前务必确认 CHANGELOG 已更新到位。-rc标签自动带--prerelease标记,便于先发候选版本收集反馈。
发布者此时只做一件事:登录 GitHub,打开 CI 生成的草稿,核对版本号、CHANGELOG 链接与gleam-*附件(归档、校验和、sigstore、SBOM、licences HTML)后,点击正式发布。
第 8 步:分享发布公告
Release 正式发布后,回到第 1 步写好的官网公告,通过社区渠道对外分享,并引导用户下载新版本。至此,一个版本的生命周期闭环完成。
附加环节:容器镜像与每日夜间构建
正式 Release 发布(published事件)还会触发 .github/workflows/release-containers.yaml,基于 containers/ 目录中的 Dockerfile 矩阵构建并推送镜像,基础镜像覆盖scratch、erlang、erlang-slim、erlang-alpine、elixir、elixir-slim、elixir-alpine、node、node-slim、node-alpine十种组合。
此外,仓库还维护一条不依赖正式发版的夜间通道:.github/workflows/release-nightly.yaml 每天通过 cron(45 0 * * *)或手动触发,先用 bin/add-nightly-suffix-to-versions.sh 给版本号追加 nightly 后缀,再构建并更新名为Nightly的预发布版本——这条通道与正式发布相互独立,正式发布流程中无需干预。
发布清单速查表
| 步骤 | 关键操作 | 仓库依据 |
|---|---|---|
| 1 | 撰写官网发布公告 | CHANGELOG.md、changelog/ |
| 2 | 更新官网文档(language server、gleam.toml 等) | language-server/src、compiler-core/src/config.rs |
| 3 | 同步所有Cargo.toml版本号 | Cargo.toml(workspace 成员)、gleam-bin/Cargo.toml |
| 4 | make test build | Makefile |
| 5 | commit、tagv*、push、push tags | .github/workflows/release.yaml 触发条件 |
| 6 | 等待 CI 构建(多平台产物 + 签名 + SBOM) | .github/actions/build-release/action.yml |
| 7 | 从草稿发布 Release(gh release create --draft --verify-tag) | .github/workflows/release.yamlcreate-release作业 |
| 8 | 分享官网发布公告 | — |
小结
Gleam 的发布流程将文档先行、版本同步、本地全量验证、Git 标签触发、CI 自动构建、人工最终确认六个环节拆解得清晰可执行。对维护者而言,日常只需关注清单前 5 步的"人肉"操作,剩下的构建、签名、校验和、SBOM 与草稿生成全部由 .github/workflows/ 与 .github/actions/ 中的流水线自动完成;对想借鉴发布经验的开发者而言,这套"草稿制发布 + 供应链安全产物 + 容器镜像矩阵"的组合,也是一个可以直接参考的 Rust 项目发版范本。
【免费下载链接】gleam⭐️ A friendly language for building type-safe, scalable systems!项目地址: https://gitcode.com/GitHub_Trending/gl/gleam
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考