GitHub Actions 缓存 Rust 构件

14

使用GitHub Actions时,当使用Rust的cargo构建时,我无法从使用先前构建生成的缓存艺件中看到明显的改进。

我怀疑在以下代码中有些遗漏,可能是什么问题呢?

编辑:这里是日志,如果您想查看它们!

name: Rust

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

env:
  CARGO_TERM_COLOR: always

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - name: Cargo Cache
      uses: actions/cache@v1
      with:
        path: ~/.cargo
        key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml') }}-${{ hashFiles('**/Cargo.lock') }}
        restore-keys: |
          ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml') }}
          ${{ runner.os }}-cargo

    - name: Cargo Target Cache
      uses: actions/cache@v1
      with:
        path: target
        key: ${{ runner.os }}-cargo-target-${{ hashFiles('**/Cargo.toml') }}-${{ hashFiles('**/Cargo.lock') }}
        restore-keys: |
          ${{ runner.os }}-cargo-target-${{ hashFiles('**/Cargo.toml') }}
          ${{ runner.os }}-cargo-target

    - uses: actions/checkout@v2
    - name: Build
      run: cargo build --verbose --all --features "strict"
    - name: Run tests
      run: cargo test --verbose --all --features "strict"
4个回答

17

你可以一步缓存目标和 .cargo 文件夹。下面是我用于构建和测试后端 Web API 的设置示例。

name: Continuous Integration

on: [push, pull_request]

jobs:
  build_and_test:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:10.12-alpine
        env:
          POSTGRES_USER: test
          POSTGRES_PASSWORD: test
          POSTGRES_DB: pongstars
        ports:
          - 5432:5432
        # needed because the postgres container does not provide a healthcheck
        options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5

    steps:
      - uses: actions/checkout@v2
      - name:  Cache
        uses: actions/cache@v2
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}

      - uses: actions-rs/toolchain@v1
        with:
          toolchain: stable

      - name:  Build
        uses: actions-rs/cargo@v1
        with:
          command: build

      - name: Create env file
        run: mv .env.example .env

      - name:  Test
        uses: actions-rs/cargo@v1
        with:
          command: test

      - name:  Integration test
        uses: actions-rs/cargo@v1
        with:
          command: test
          args: --features "integration_tests"

1
因为巧妙运用表情符号,你赢得了我的点赞⚡ - chantey

5
我想我现在已经解决了问题:构建时间从4分钟缩短到1分15秒。
我所做的修复如下:
  • 首先需要检出代码库,以便在哈希函数中使用Cargo.toml文件进行缓存。
  • **/Cargo.toml被重构为Cargo.toml,以便找到该文件进行哈希。
这是最终的rust.yaml
name: Rust

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

env:
  CARGO_TERM_COLOR: always

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
    - name: Cargo Cache
      uses: actions/cache@v1
      with:
        path: ~/.cargo
        key: ${{ runner.os }}-cargo-${{ hashFiles('Cargo.toml') }}
        restore-keys: |
          ${{ runner.os }}-cargo-${{ hashFiles('Cargo.toml') }}
          ${{ runner.os }}-cargo

    - name: Cargo Target Cache
      uses: actions/cache@v1
      with:
        path: target
        key: ${{ runner.os }}-cargo-target-${{ hashFiles('Cargo.toml') }}
        restore-keys: |
          ${{ runner.os }}-cargo-target-${{ hashFiles('Cargo.toml') }}
          ${{ runner.os }}-cargo-target

    - name: Build
      run: cargo build --verbose --all --features "strict"
    - name: Run tests
      run: cargo test --verbose --all --features "strict"


"build --all"现在已被弃用。"build --all-targets"可能是更好的选择。 - poolie
1
~/.cargo/的所有缓存似乎会导致在macOS上Cargo失败。只缓存gitregistry子目录,正如其他答案中建议的那样,效果更好。 - poolie
这是正确的答案。在原始问题中,在缓存后进行了结算,因此没有 Cargo.toml / Cargo.lock 文件可以创建缓存键。根据我的经验,对于 Cargo.lock 进行缓存比 Cargo.toml 更好,因为不是所有对 toml 的更改都应该触发缓存失效(例如添加注释)。只有在依赖树发生变化时,Cargo.lock 才会发生变化,但并不总是能够使用它,例如构建库时。 - SirDorius
GitHub的示例模板对我起了作用,但只有在指向顶层项目目录中的Cargo.lock而不是**/Cargo.lock之后才有效。 - undefined

4

https://github.com/actions/cache/blob/main/examples.md#rust---cargo为例,我认为你可以使用以下代码:

name: Rust

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

env:
  CARGO_TERM_COLOR: always

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2

    - uses: actions/cache@v2
      with:
        path: |
          ~/.cargo/registry
          ~/.cargo/git
          target
        key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}

    - name: Build
      run: cargo build --verbose --all --features "strict"
    - name: Run tests
      run: cargo test --verbose --all --features "strict"

因为遇到问题,我在自己的项目中尝试了一下,但是Mihai建议先添加结账步骤,这确实产生了很大的影响。


1
这是由actions/cache的作者提供的示例
- uses: actions/cache@v3
  with:
    path: |
      ~/.cargo/bin/
      ~/.cargo/registry/index/
      ~/.cargo/registry/cache/
      ~/.cargo/git/db/
      target/
    key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接