diff --git a/.github/actions/setup-tools/action.yml b/.github/actions/setup-tools/action.yml index 703dac29..79868a89 100644 --- a/.github/actions/setup-tools/action.yml +++ b/.github/actions/setup-tools/action.yml @@ -1,11 +1,10 @@ -name: Setup tools (sccache / mold / nextest) +name: Setup tools (sccache / nextest) -# 工具缓存:sccache、mold、nextest 缓存到用户可写的 ~/oxide-tools-cache,恢复后 -# sudo cp 到 /usr/bin(sccache、mold)与 ~/.cargo/bin(nextest)。mold 必须落 -# /usr/bin(默认 PATH)——落 ~/.cargo/bin 时 sccache 包装 rustc 的链接子进程不 -# 继承 GITHUB_PATH 加的 PATH,链接器找不到 mold 报 cannot find ld。nextest 走 -# 官方预编译二进制直下,不依赖 main 分支安装脚本(脚本会被移动而 404)。 -description: 恢复工具缓存;缺失时安装 sccache、mold、nextest 并落系统目录 +# 工具缓存:nextest 缓存到用户可写的 ~/oxide-tools-cache,恢复后 cp 到 ~/.cargo/bin。 +# sccache 改用官方 sccache-action 安装,它带 GitHub Actions 缓存后端;apt 版 sccache +# 无该后端,本地磁盘缓存每个 job 用完即弃、跨 run 零命中,等于只付包装开销。 +# mold 目前在 CI 统一禁用(见下方配置步骤),故不安装。 +description: 恢复 nextest 工具缓存;安装 nextest 与 sccache(GHA 缓存后端) runs: using: composite @@ -15,42 +14,39 @@ runs: uses: actions/cache/restore@v6 with: path: ~/oxide-tools-cache - key: oxide-tools-ubuntu-v1 + key: oxide-tools-ubuntu-v2 - - name: Install tools (cache miss) + - name: Install nextest (cache miss) if: steps.tool-cache.outputs.cache-hit != 'true' shell: bash run: | - sudo apt-get update -y - sudo apt-get install -y sccache mold mkdir -p "$HOME/oxide-tools-cache" - cp /usr/bin/sccache /usr/bin/mold "$HOME/oxide-tools-cache/" curl -LsSf https://get.nexte.st/latest/linux | tar zxf - -C "$HOME/oxide-tools-cache" - - name: Install tools to system dirs + - name: Install nextest to cargo bin shell: bash - run: | - sudo cp "$HOME/oxide-tools-cache/sccache" "$HOME/oxide-tools-cache/mold" /usr/bin/ - cp "$HOME/oxide-tools-cache/cargo-nextest" "$HOME/.cargo/bin/" + run: cp "$HOME/oxide-tools-cache/cargo-nextest" "$HOME/.cargo/bin/" - - name: Disable mold in CI + - name: Setup sccache + uses: mozilla-actions/sccache-action@v0.0.11 + + - name: Configure build cache shell: bash run: | - # mold 在主 workflow 正常,但在可复用 workflow 里 sccache 包装 rustc 的 - # 链接子进程定位不到 mold、回退默认 ld 报 cannot find ld。CI 统一走默认 - # lld;只删工作副本的 mold 行,本地提交的 config 保留 mold 提速。 + # CI 链接器统一走默认 lld:sccache 包装 rustc 时,链接子进程定位不到 mold、 + # 回退默认 ld 报 cannot find ld。只删工作副本的 mold 行,本地提交的 config + # 保留 mold 提速。 sed -i '/link-arg=-fuse-ld=mold/d' .cargo/config.toml - name: Verify tools in PATH shell: bash run: | - which sccache mold cargo-nextest + which cargo-nextest sccache sccache --version - mold --version - name: Save tool cache if: steps.tool-cache.outputs.cache-hit != 'true' uses: actions/cache/save@v6 with: path: ~/oxide-tools-cache - key: oxide-tools-ubuntu-v1 + key: oxide-tools-ubuntu-v2 diff --git a/.github/workflows/ci-test.yml b/.github/workflows/ci-test.yml index 90ba35db..0b5f8d55 100644 --- a/.github/workflows/ci-test.yml +++ b/.github/workflows/ci-test.yml @@ -2,11 +2,16 @@ name: CI Test # 可复用工作流:主 ci.yml 的 test job 经 workflow_call 调用本文件。外观上主 CI # 只有一个 test job(全过才绿),点进去才看到内部 matrix(os × group)并行图。 -# 产物复用:rust-cache 按「OS + Cargo.lock」键在仓库级共享,本 workflow 的 test -# job 能 restore 主 ci.yml build job 存的 target/ 缓存(跨 workflow 边界有效)。 +# 产物复用:test 依赖主 workflow 的 build job 先把 workspace 编译一遍并写入 +# sccache(GitHub Actions 缓存后端),各分区随后经 sccache 命中已编产物,只补编 +# 自己的 test harness;rust-cache 负责依赖源码与 registry 的缓存。 on: workflow_call: +env: + # 与主 ci.yml 一致:sccache 走 GitHub Actions 缓存后端,编译产物跨 run 复用。 + SCCACHE_GHA_ENABLED: "true" + jobs: test: name: Test (${{ matrix.os }} / ${{ matrix.group.name }}) @@ -36,6 +41,7 @@ jobs: args: "-p oxide_kernel -p oxide_regalloc -p oxide_cfg -p oxide_bytecode -p oxide_engine -p oxide_compiler -p oxide_parser -p oxide_log -p oxide_ir -p oxide_code_cache" # === END AUTO-GENERATED === runs-on: ${{ matrix.os }} + timeout-minutes: 40 steps: - uses: actions/checkout@v7 with: @@ -43,9 +49,9 @@ jobs: - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 with: - # 与 ci.yml 的 build job 同键:复用 build 的 target/ 缓存,只补编 - # test harness。自定义键避免按 profile 自动分键(build/test 各一) - # 导致 test 恢复陈旧缓存、重链接时走默认 ld 报 cannot find ld。 + # 与 ci.yml build job 同名后缀的稳定键;rust-cache 自动键附 job 名, + # 故与 build 仍是两份独立缓存,跨 job 的 workspace 产物复用由 sccache + # 承担(见本文件头注释)。 key: oxide-target-ubuntu-v1 - uses: ./.github/actions/setup-tools - name: Test diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 25b5ada6..e4b67ede 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,22 +6,37 @@ on: pull_request: branches: [main] +# 同一 PR 的新推送取消上一轮未完成的 run:一轮 CI 数十分钟,过期 run 继续跑纯浪费 +# runner 分钟,且其状态已无意义。main 分支的推送不取消,保留每个提交的完整记录。 +concurrency: + group: ci-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +# 最小权限:CI 只读仓库内容,不需要写 token。 +permissions: + contents: read + env: CARGO_TERM_COLOR: always + # sccache 走 GitHub Actions 缓存后端:编译产物跨 run 复用。本地磁盘缓存无后端、 + # 每个 job 用完即弃,跨 run 零命中,等于白装。须在 sccache 服务启动前设置。 + SCCACHE_GHA_ENABLED: "true" -# job 拓扑:fmt / clippy / build 三者并行独立;test 依赖 build(needs),在 -# build 编译完成后启动,复用 build 的产物(经共享 rust-cache 传递 target/), -# 只补编 test harness、不重编整个 workspace。各 job 单独状态,一个挂了不阻塞 -# 无关者,GitHub 界面一眼看出哪个红。clippy 走 check 模式、产物与 build 不同, -# 无法复用 build 产物,故保持独立并行。 +# job 拓扑:fmt / clippy / build 三者并行独立;test 依赖 build(needs),在 build +# 编译完成后启动。build 先编译 workspace 依赖,并把每个编译单元写进 sccache +# (GitHub Actions 缓存后端);test 各分区随后经 sccache 命中这些已编产物,只需 +# 补编自己的 test harness,不重编整个 workspace。各 job 单独状态,一个挂了不阻塞 +# 无关者,GitHub 界面一眼看出哪个红。 # -# sccache 与 mold:.cargo/config.toml 全局引用(rustc-wrapper 与 -fuse-ld=mold), -# 凡跑 rustc 的 job(clippy/build/test)必须先装,否则构建直接失败。fmt 只跑 -# rustfmt、不跑 rustc,无需安装。 +# sccache 与 mold:.cargo/config.toml 全局引用 rustc-wrapper=sccache,凡跑 rustc +# 的 job(clippy/build/test)都要经 setup-tools 装好 sccache,否则构建直接失败; +# mold 由 setup-tools 从工作副本剥掉,CI 链接统一走默认 ld。fmt 只跑 rustfmt、 +# 不跑 rustc,无需 setup-tools。 jobs: fmt: name: Format runs-on: ubuntu-latest + timeout-minutes: 10 steps: - uses: actions/checkout@v7 - uses: dtolnay/rust-toolchain@stable @@ -33,6 +48,7 @@ jobs: clippy: name: Clippy runs-on: ubuntu-latest + timeout-minutes: 30 steps: - uses: actions/checkout@v7 with: @@ -48,6 +64,7 @@ jobs: build: name: Build runs-on: ubuntu-latest + timeout-minutes: 30 steps: - uses: actions/checkout@v7 with: @@ -55,16 +72,18 @@ jobs: - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 with: - # 与 ci-test.yml 的 test job 同键:test 复用 build 的 target/ 缓存, - # 只补编 test harness、不重编整个 workspace。自定义键避免按 profile - # 自动分键(build/test 各一)导致 test 恢复陈旧缓存。 + # 稳定键后缀:让 build 的依赖产物缓存跨 run 固定在同一命名空间。 + # rust-cache 的自动键会附 job 名,故 build 与 test 仍是两份独立缓存; + # 且它只缓存依赖、不缓存 workspace 自身,workspace 产物的跨 job 复用 + # 由 sccache 承担。 key: oxide-target-ubuntu-v1 - uses: ./.github/actions/setup-tools - name: Build run: cargo build --verbose # test 是单一 job:经 workflow_call 调用 ci-test.yml,外观上主 CI 只有一个 test - # (全过才绿),点进去才见内部 matrix(os × group)并行图。needs build 复用产物。 + # (全过才绿),点进去才见内部 matrix(os × group)并行图。build 先编 workspace + # 并填充 sccache,test 经 sccache 命中已编产物。 test: name: Test needs: [build]