非自明なVoris CIパイプラインのGithubアクションへの移行


Image source: https://unsplash.com/photos/Grg6bwZuBMs


私のブログの熱心な読者は、私が本当に適当なCI/CDセットアップを評価しているということを知っています.数週間前まで、このようなセットアップの解決への私の試みはTravis CI . 残念ながら、トラリスはわずかにオープンソースプロジェクトのためにその使用を徹底的に制限するビジネスモデルを変えました.私にとって、これは大きな挫折だった.なぜなら、私はTravisnut.js . そして、私はこのプロジェクトからお金を稼いでいないので、CIのために少なくとも69ドルを支払う理由は難しいです.
既に使用していたのでGitHub Actions 他のreposでは、私は移動することを決めたnut.js Githubアクションにも.

既存のパイプライン
それでは、何を移行する必要がありますか?
エーnut.js build 2つから3つの段階から成ります.
  • sonar
  • test
  • deploy (タグにのみトリガされ、develop 枝)
  • The sonar ステージはLinuxで固定ノードバージョンで動作し、すべてのテストを実行します.
    つまり、
  • プラットフォーム独立テスト
  • プラットフォーム依存テスト
  • GUIを必要とするすべてのテスト
  • Dockerコンテナで実行中のすべてのテスト
  • 生成カバレッジレポートがマージされ、報告されてsonarcloud .
    下記test ステージはビルド・マトリックスで、MacOSとLinuxの両方でノードのバージョンを変えてテストを実行します.
    Linuxではtest ステージは、テストの正確な同じセットを実行しますsonar ステージは、MacOSテストでは、dockerコンテナで実行中です.
    オプションdeploy ステージは新しい@next snapshot release のためにdevelop 枝、または新しい@latest release タグ用.
    要約すると、GitHubアクションへの移行が成功するための要件は次のとおりです.
  • ビルドステージ
  • ビルド行列
  • Dockerサポート
  • GUIテストの実行
  • ソナーレポート

  • 移住しましょう!
    最終的なセットアップは3つの別個のファイル、一般的なブランチとプルのリクエストビルド、スナップショットのリリースのための1つと安定したリリースのための1つに分割されます.
    まずはブランチビルドを見てみましょう.

    ソナーステージ
    または、ワークフローはすべての枝にプッシュするdevelop 下のリリースブランチrelease/** だけでなく、プルのリクエスト.
    name: Run CI
    on:
      push:
        branches-ignore:
          - develop
          - release/**
      pull_request:
    
    トラヴィスステージは似ているjobs Githubアクションについて
    jobs:
      sonar:
        runs-on: ubuntu-latest
        steps:
          - name: Set up Git repository
            uses: actions/checkout@v2
          - name: Set up node
            uses: actions/setup-node@v2
            with:
              node-version: 14
    
    我々の仕事はLinuxで動くubuntu-latest デフォルトUbuntu 18.04、Ubuntu 20.04にアップグレードします.X . X .
    Linuxでは、dockerは右側にあるので、デーモン化されたコンテナを起動できます.
    - name: Setup Docker
      run: |
        docker pull s1hofmann/nut-ci:latest
        docker run -it -d --name nut-ci --shm-size 4gb --user $(id -u):$(id -g) -v ${PWD}:${PWD}:rw s1hofmann/nut-ci:latest bash
    
    プロジェクトを初期化する手順は次のとおりです.
    - name: Install
      run: npm ci
    - name: Compile
      run: npm run compile
    - name: Init e2e test subpackage
      run: npm --prefix e2e/tests ci
    - name: Clean coverage report
      run: npm run coverage:clean
    
    一度設定すると、GUIを必要とするテストを実行します.
    LinuxでヘッドレスGUIテストを実行する一般的な方法はvirtual framebuffer .
    トラビスは、使いやすい提供していますservice ビルド中の仮想フレームバッファを有効にするには、Githubアクションの適切な置換を見つけましょう.
    GabrielBB/xvfb-action 可能な場合は、仮想フレームバッファを開始する素敵なラッパーを提供します.
    Linux上で動作するときは、他のプラットフォームで実行される前に仮想フレームバッファを設定します.
    追加の設定は、クロスプラットフォームの設定で実行するときに必要な(我々は、マトリックスビルドで行うように)!
    GUIと単体テストのあと、Dockerコンテナで実行しているE 2 Eテストを実行し、すべてのカバレッジレポートをマージしましょう.
    - name: Run Docker E2E tests
      run: docker exec nut-ci bash -c "bash $PWD/.build/build.sh ${PWD} 14"
    - name: Merge coverage reports
      run: |
        npm run coverage:merge
        npm run coverage:merge-report
    
    Travisはアドオンを提供するsonarcloud 簡単にsonarcloud解析を実行します.
    幸運にも、当局者がいるSonarCloud アクションは、githubアクションでスキャンを実行します.
    走るsonar-scanner 既存でsonar-project.properties 設定は簡単になります
    - name: Send results to SonarCloud
      uses: SonarSource/[email protected]
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} 
    
    Travisのような我々のワークフローファイルで暗号化されたソナートークンを保存する代わりに、我々はrepo secret そして、我々は行くのが良いです!

    試験段階
    フォローsonar ステージは、複数のプラットフォームとノードのバージョンを持つビルド行列を実行します.
    デフォルトでは、ジョブは並列に動作しますが、test ジョブの場合sonar ステージは成功しました、前の仕事に要件を設定しています:
    test:
      needs:
        - sonar
    
    では、ビルド行列を設定しましょう.
    strategy:
      matrix:
        os: [ ubuntu-latest, windows-latest, macos-latest ]
        node: [ 10, 12, 14 ]
        exclude:
          - os: ubuntu-latest
            node: 14
        runs-on: ${{matrix.os}}
        steps:
          - name: Set up Git repository
            uses: actions/checkout@v2
          - name: Set up node
            uses: actions/setup-node@v2
            with:
              node-version: ${{matrix.node}}
    
    私たちは、ノードバージョン10、12、14を使用して、Linux、Windows、MacOSのテストを実行したい.
    でも我々からsonar ステージはすでにLinux上でノード14を使用して実行され、我々は時間を節約し、計算するために私たちのビルド行列からそれを除外している.
    合計では、ビルドの行列は8つの別々のビルドに展開されます.
    また、私たちのDockerテストをLinuxに制限したいので、ubuntu-latest :
    - name: Setup Docker
      if: ${{matrix.os == 'ubuntu-latest'}}
      run: |
        docker pull s1hofmann/nut-ci:latest
        docker run -it -d --name nut-ci --shm-size 4gb --user $(id -u):$(id -g) -v ${PWD}:${PWD}:rw s1hofmann/nut-ci:latest bash
    
        ...
    
    - name: Run Docker E2E tests
      if: ${{matrix.os == 'ubuntu-latest'}}
      run: docker exec nut-ci bash -c "bash $PWD/.build/build.sh ${PWD} ${{matrix.node}}"
    

    展開段階
    スナップショットのリリースはCOMMITdevelop :
    name: Create snapshot release
    on:
      push:
        branches:
          - develop
    
    最新のリリースはsemverタグに限られます.
    name: Create tagged release
    on:
      push:
        tags:
          - v*.*.*
    
    新しいパッケージをリリースするとき、我々はソナースキャンを必要としないので、我々はちょうどこのステージを完全にスキップして、我々のtest ステージ.
    この段階の結果により、パッケージのリリースが開始されます.
    deploy:
      needs:
        - test
      runs-on: ubuntu-latest
      steps:
        - name: Set up Git repository
          uses: actions/checkout@v2
        - name: Set up node
          uses: actions/setup-node@v2
          with:
            node-version: 14
        - name: Publish tagged release
          uses: JS-DevTools/npm-publish@v1
          with:
            token: ${{ secrets.NPM_TOKEN }}
    

    解決すべきか
    我々の中にはたくさんの重複があるworkflows これを減らしたいのですが.似たところGitLab CI ハンドルは良いでしょうが、それはまだサポートされていないように見えるGitHub Actions .
    もう一つのことは、コミットメッセージを通してビルドをスキップするサポートが不足していることです.
    コミットメッセージを介してCIビルドをスキップするのは一般的なパターンです.[skip_travis] or [skip_ci] .
    残念ながら、Githubアクションはまだこの種のショートカットをサポートしておらず、まだワークフローを実行します.

    結論
    Githubアクションへの既存のTravis CIパイプラインの移行は、当初予想されたより簡単になりました.
    コミュニティのアクションの広い範囲のためにそれはかなりすべての必要なボックスをティックに簡単だった.
    その結果、我々は現在、一つのCIシステムですべてのビルドを走らせることができましたAppVeyor 以来Windows build are in an early stage on Travis 全体のビルドランタイムが減少しました!