在开发名为 Textpod(用 Rust 编写的笔记应用)时,我需要自动化地在 GitHub 上完成构建和发布。 以下内容(以及相应的 YAML 配置文件)演示了整套自动化流程的配置步骤,包括:
- 为 Windows、Linux、macOS (Intel + ARM) 构建二进制
- 将这些构建产物及校验文件上传到最新的 GitHub Release
- 发布到 crates.io
- 构建面向 amd64 和 arm64 的精简 Docker 镜像,并推送到 Docker Hub
一、触发条件:GitHub Release
首先,我们以 release 事件作为执行触发器。YAML 配置大致如下:
on:
release:
types:
- created
当我们在 GitHub 中创建一个新的 Release 时,这些后续的构建及发布任务就会自动执行。
二、在 Linux 环境中构建 Linux 与 Windows 二进制
可以在同一个 Linux 环境中通过 rustup
对不同的目标进行交叉编译(例如 Windows 和 Linux)。
jobs:
linux_windows:
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@v2
- name: Install Linux and Windows Cross Compilers
run: sudo apt-get install --yes --no-install-recommends musl-tools gcc-mingw-w64-x86-64-win32
- name: Install rustup targets
run: rustup target add x86_64-unknown-linux-musl x86_64-pc-windows-gnu
- name: Build the executable
run: cargo build --release --target x86_64-unknown-linux-musl --target x86_64-pc-windows-gnu
- name: Tar x86_64 binary
run: tar -czvf textpod-gnu-linux-x86_64.tar.gz -C target/x86_64-unknown-linux-musl/release textpod
- name: Zip windows binary
run: zip -j textpod-windows.zip target/x86_64-pc-windows-gnu/release/textpod.exe
- name: Generate SHA256 checksums
run: |
shasum -a 256 textpod-gnu-linux-x86_64.tar.gz > textpod-gnu-linux-x86_64.tar.gz.sha256
shasum -a 256 textpod-windows.zip > textpod-windows.zip.sha256
- name: Upload release binaries
uses: alexellis/upload-assets@0.4.0
env:
GITHUB_TOKEN: ${{ github.token }}
with:
asset_paths: '["textpod-gnu-linux-x86_64.tar.gz", "textpod-windows.zip", "textpod-gnu-linux-x86_64.tar.gz.sha256", "textpod-windows.zip.sha256"]'
构建说明
- Step 4 (
cargo build
) 一次性构建两个目标:x86_64-unknown-linux-musl
x86_64-pc-windows-gnu
- 后续分别将 Linux 产物打包为
tar.gz
文件、Windows 产物打包为zip
文件。 - 生成各自的 SHA256 校验文件:
textpod-gnu-linux-x86_64.tar.gz.sha256
与textpod-windows.zip.sha256
。 - 使用
alexellis/upload-assets@0.4.0
Action 将这四个文件一并上传到 GitHub Release。
注意:
${{ github.token }}
是 GitHub 自动提供的内置 Token,不需要你额外创建或配置。
三、在 macOS 环境中构建 x86 和 ARM 二进制
对 macOS 的构建与上述类似,但需要指定在 macOS 平台下(runs-on: macos-latest
)进行,并添加两个目标:Intel 和 ARM。
rustup target add x86_64-apple-darwin aarch64-apple-darwin
cargo build --release --target=x86_64-apple-darwin --target=aarch64-apple-darwin
同理,你可以将打包、校验、上传至 Release 等步骤与 Linux/Windows 的做法相结合,为 macOS 平台生成并上传相应产物。
四、发布到 crates.io
在完成了所有平台的构建(Linux、Windows、macOS)后,可以通过以下方式将包发布到 crates.io:
crates:
runs-on: ubuntu-latest
needs: [linux_windows, macos]
steps:
- uses: actions/checkout@v3
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true
- uses: katyo/publish-crates@v2
with:
registry-token: ${{ secrets.CARGO_REGISTRY_TOKEN }}
needs: [linux_windows, macos]
表示这个 job 必须等前面的两个构建都成功后才会执行。- 你需要在 crates.io 创建一个 API Token,并将其作为机密变量(
CARGO_REGISTRY_TOKEN
)添加到 GitHub 的 secrets 中。
五、构建并推送 Docker 镜像至 Docker Hub
最后,可以构建面向 amd64 和 arm64 平台的 Docker 镜像,然后推送到 Docker Hub:
docker:
runs-on: ubuntu-latest
needs: crates
steps:
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v6
with:
platforms: linux/amd64,linux/arm64
push: true
tags: freetonik/textpod:latest
说明
docker/build-push-action@v6
可以自动构建多架构镜像。- 在构建之前,先使用
setup-qemu-action
和setup-buildx-action
来启用对多平台(amd64、arm64)的支持。 - 将 Docker Hub 的认证信息 (
DOCKERHUB_USERNAME
,DOCKERHUB_TOKEN
) 配置为 GitHub secrets。 - 构建完成后,镜像会被推送到
freetonik/textpod:latest
,你可以换成自己的 Docker Hub 命名空间和仓库名称。
需要注意,多平台构建常常比较耗时,可能需要 20-40 分钟左右。
六、最终效果
- GitHub Release:创建新的 Release 后,一开始只会显示源代码链接;几分钟后,构建完成并将二进制文件(以及校验文件)上传到 Release 页。
- Docker 镜像:我们使用了
rust:alpine
作为基础镜像(参见项目中的 Dockerfile),通常可获得体积只有约 10 MB 的容器镜像,已发布在 Docker Hub。
以下是项目目录示例,可在对应仓库的 .github/workflows/
中查看 YAML 文件的历史版本。
整个流程可以保证在一次 Release 后,自动完成所有平台的编译、打包、上传与发布。
小结:这样就轻松搞定了多平台二进制 + Docker 镜像 + crates.io 同步发布的完整 CI/CD。