Rust 및 github actions를 통한 CI 환경 구축

모티프


Rust의 privete 프로젝트에서 CI를 활용한 토대 위에서는 지금까지 모두 CircleaCI를 사용했지만, github actions에 집결하면 많은 진전이 있을 것이기 때문에 옮기고 싶다.
나는 이 기사에서 당시 토론한 일과 참고한 것을 공유하고 싶다.

추정 독자

  • Rust에서 CI를 활용하고 싶은 사람
  • github actions로 CI를 활용하려는 사람
  • 주의 사항


    이번에 CI를 구축하는 프로젝트에서 서버는 Rust이고 안내데스크는 Next이다.js로 구축하고 같은 창고로 둘을 관리하고 있습니다.
    git 창고의 루트 디렉터리가 아니라 서버라는 디렉터리 내부가 Rust의 프로젝트 루트이기 때문에 이번workflow 파일도 그 영향을 받았다.
    구체적으로 말하면working-directory: 서버나cache 디렉터리의 경로는 서버/target/이기 때문에 카고는 루트에 있습니다.toml를 설정하는 경우working-directory를 지정하지 않아도 되고 캐시 target/를 설정하면 됩니다.
    다음은 이번 프로젝트의 디렉터리 구성도입니다.
    . # ← gitリポジトリのルートはここ
    ├── .git
    ├── .github
    │   ├── actions
    │   │   └── cache_cargo
    │   │       └── action.yml
    │   └── workflows
    │       └── rust_ci.yml
    ├── ...
    └── server # ← Rustプロジェクトのルートはここ
        ├── ...
        └── Cargo.toml 
    

    작업 작성


    action은 일반적인 처리를 추출하는 데 사용되는 기능으로 이른바 함수 정의와 같다.
    CircleaCI에서 Job이라고 불리는 기능은 기본적으로 같지만 CircleaCI의 Job과 달리 워크플로우의yaml에 직접 액션을 기술할 수 없고 동작 하나하나에 파일을 만들어야 한다.
    다음 파일은 이번에 제작된yaml 파일입니다.cache가build에 유용한 데이터를 만드는 액션입니다.
    .github/actions/cache_cargo/action.yml
    name: cache_cargo
    description: caching .cargo directory
    runs:
      using: composite
    
      steps:
        - name: Cache cargo registry
          uses: actions/cache@v2
          with:
            path: |
              ~/.cargo/bin/
              ~/.cargo/registry/index/
              ~/.cargo/registry/cache/
              ~/.cargo/git/db/
              server/target/
            key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
            restore-keys: ${{ runner.os }}-cargo-
    
    이yaml 파일은workflow에서 다음 문법으로 호출할 수 있습니다.
    - uses: ./.github/actions/cache_cargo
    

    워크플로우의 제작


    github actions를 사용하여 CI를 실제로 실행하려면 workflow를 만들어야 합니다.
    다음 파일은 이번에 제작한yaml 파일입니다.
    이번 작업 절차는요.
  • 캐시를 만들기 위해 카고build를 미리 실행
  • 캐시 기반 데이터
    2-a.rustfmt를 사용하여 코드 스타일 검사
    2-b.clippy가 이용한 정적 분석
    2-c. 자동 테스트의 실행(postgres로 데이터 베이스 테스트도 가능)
  • 이런 구성은 최소한의 구성이다.
    tarpaulin으로 coverage를 얻으려고 했는데 캐치가 효과가 없어서 잠시 꺼졌어요.
    (RUSTC FORCE INCREMENTAL:1은 의미가 없을 수도 있지만 문헌을 먼저 참고하여 넣겠습니다.)
    .github/workflows/rust_ci.yml
    on: push
    
    jobs:
      build_cache:
        runs-on: ubuntu-latest
    
        env:
          RUSTC_FORCE_INCREMENTAL: 1
    
        steps:
          - uses: actions/checkout@v2
    
          - uses: ./.github/actions/cache_cargo
    
          - name: build
            run: cargo build
            working-directory: server
    
      fmt:
        runs-on: ubuntu-latest
    
        needs: build_cache
    
        steps:
          - uses: actions/checkout@v2
    
          - run: rustup component add rustfmt
    
          - uses: ./.github/actions/cache_cargo
    
          - name: fmt
            run: cargo fmt --all -- --check
            working-directory: server
    
      clippy:
        runs-on: ubuntu-latest
    
        env:
          RUSTC_FORCE_INCREMENTAL: 1
    
        needs: build_cache
    
        steps:
          - uses: actions/checkout@v2
    
          - run: rustup component add clippy
    
          - uses: ./.github/actions/cache_cargo
    
          - name: clippy
            run: cargo clippy --all-targets --all-features -- -D warnings
            working-directory: server
    
      test:
        runs-on: ubuntu-latest
    
        services:
          postgres:
            image: postgres:12
            ports:
              - 5432:5432
            env:
              POSTGRES_USER: postgres
              POSTGRES_PASSWORD: postgres
            options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
    
        env:
          RUSTC_FORCE_INCREMENTAL: 1
    
        needs: build_cache
    
        steps:
          - name: create database for test
            run: PGPASSWORD=postgres psql -h localhost -U postgres -c "CREATE DATABASE test"
    
          - uses: actions/checkout@v2
    
          - uses: ./.github/actions/cache_cargo
    
          - name: test
            run: cargo test --all -- --nocapture
            working-directory: server
    
    

    참고 문헌


    workflow 샘플


    이것들은 매우 참고 가치가 있다.
    워크플로우
    actix-web의workflow
    actions/cache@v2의 Rust 샘플

    sccache 연구


    sccache라는 프로그램의 이용으로 고속화 건설이 가능하다면 도입해 보았지만 실제 효과를 느낄 수 있는 프로젝트 사이즈가 아니어서 보류했습니다.
    sccache로 GiitHub Action에 있는 Rust 빌딩을 고속화해 보세요.
    GitHub Actions best practices for Rust projects

    incremental build 연구


    mtime 복원을 통해 increamental build을 실현할 수 있다고 하는데 checkkout은 무거워질 것 같고 프로젝트 사이즈가 크지 않기 때문에 외부 크레인의 캐시가 완성되면 우선 충분합니다.
    Rust 프로젝트의 GiitHub Actions에서 increamental build 기술 수행

    좋은 웹페이지 즐겨찾기