GitHubアクションワークフローでのAPTパッケージのキャッシュ


9

Cプロジェクトでは、次のGithubアクションワークフローを使用します。ワークフローは約40秒で終了しますが、その時間の半分以上がvalgrindパッケージとその依存関係のインストールに費やされています。

キャッシングはワークフローをスピードアップするのに役立つと思います。もう数秒待ってもかまいませんが、これはGitHubのリソースの無駄な無駄のようです。

name: C Workflow

on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v1

    - name: make
      run: make

    - name: valgrind
      run: |
        sudo apt-get install -y valgrind
        valgrind -v --leak-check=full --show-leak-kinds=all ./bin

を実行sudo apt-get install -y valgrindすると、次のパッケージがインストールされます。

  • gdb
  • gdbserver
  • libbabeltrace1
  • libc6-dbg
  • libipt1
  • valgrind

アクションが特定のディレクトリのキャッシュをサポートしていることは知っています(そして、これについてすでにいくつかの回答済みのSOの質問と記事があります)が、aptによってインストールされたすべての異なるパッケージがどこに行き着くのかわかりません。パッケージをインストールすることによって影響を受けるディレクトリは、私だけ/bin//usr/bin/、それだけではありません。

将来のワークフロー実行のためにインストールされたシステムパッケージをキャッシュするエレガントな方法はありますか?

回答:


5

この回答の目的は、githubアクションでキャッシングを行う方法を示すことです。必ずしもキャッシュする方法を示す必要はありませんvalgrindが、すべてをキャッシュできる/すべきでないことを示し、キャッシュのキャッシュと復元と依存関係の再インストールのトレードオフを考慮する必要があります。


actions/cacheこれを行うには、アクションを使用します。

ステップとして追加します(valgrindを使用する必要がある前):

- name: Cache valgrind
  uses: actions/cache@v1.0.3
  id: cache-valgrind
  with:
      path: "~/valgrind"
      key: ${{secrets.VALGRIND_VERSION}}

次のステップでは、キャッシュされたバージョンをインストールするか、リポジトリからインストールする必要があります。

- name: Install valgrind
  env:
    CACHE_HIT: ${{steps.cache-valgrind.outputs.cache-hit}}
    VALGRIND_VERSION: ${{secrets.VALGRIND_VERSION}}
  run: |
      if [[ "$CACHE_HIT" == 'true' ]]; then
        sudo cp --verbose --force --recursive ~/valgrind/* /
      else
        sudo apt-get install --yes valgrind="$VALGRIND_VERSION"
        mkdir -p ~/valgrind
        sudo dpkg -L valgrind | while IFS= read -r f; do if test -f $f; then echo $f; fi; done | xargs cp --parents --target-directory ~/valgrind/
      fi

説明

VALGRIND_VERSIONシークレットを次の出力に設定します。

apt-cache policy valgrind | grep -oP '(?<=Candidate:\s)(.+)'

これにより、シークレットの値を変更するだけで、新しいバージョンがリリースされたときにキャッシュを無効にすることができます。

dpkg -L valgrindを使用するときにインストールされるすべてのファイルをリストするために使用されますsudo apt-get install valgrind

このコマンドで実行できるのは、すべての依存関係をキャッシュフォルダーにコピーすることです。

dpkg -L valgrind | while IFS= read -r f; do if test -f $f; then echo $f; fi; done | xargs cp --parents --target-directory ~/valgrind/

さらに

のすべてのコンポーネントをコピーすることに加えてvalgrind、依存関係をコピーする必要がある場合もあります(libcこの場合など)が、依存関係チェーンはそこから拡大するだけなので、このパスに沿って続行することはお勧めしません。正確には、valgrindを実行するのに適した環境を最終的に作成するためにコピーする必要がある依存関係は次のとおりです。

  • libc6
  • libgcc1
  • gcc-8-base

これらすべての依存関係をコピーするには、上記と同じ構文を使用できます。

for dep in libc6 libgcc1 gcc-8-base; do
    dpkg -L $dep | while IFS= read -r f; do if test -f $f; then echo $f; fi; done | xargs cp --parents --target-directory ~/valgrind/
done

valgrind最初にインストールするために必要なのは単に実行することだけである場合、このすべての作業は本当に問題の価値がありますsudo apt-get install valgrindか?ビルドプロセスを高速化することが目的の場合は、キャッシュを復元(ダウンロードおよび抽出)するのにかかる時間と、コマンドを再度実行してインストールするのにかかる時間も考慮する必要がありますvalgrind


最後に、キャッシュがに保存されていると想定して、キャッシュを復元するには/tmp/valgrind、次のコマンドを使用できます。

cp --force --recursive /tmp/valgrind/* /

これは基本的にすべてのファイルをキャッシュからルートパーティションにコピーします。

上記のプロセスに加えて、ソースからインストールしてコンパイルすることにより、「valgrindをキャッシュする」もあります。キャッシュのサイズは約63MB(圧縮)になりましたlibcが、目的を達成するために、個別にインストールする必要があります。


参照:


ああ、なるほど、それは独創的です。インストールされているすべてのファイルを安全に取得して、何かを壊すことなくそれらを別のディレクトリに移動できるとは思いもしませんでした。それがうまくいくかどうかはわかりません。私はワークフローを3回実行し、常に行っていCache not found for input keys: ***.ます。VALGRIND_VERSION[設定]> [シークレット]でシークレットを追加しましたが、それでよろしいですか?
natiiix

私はキャッシュが今打撃を受けることができたが、私はvalgrindのから次のエラーを取得しています:--2906-- Reading syms from /lib/x86_64-linux-gnu/ld-2.27.so --2906-- Considering /lib/x86_64-linux-gnu/ld-2.27.so .. --2906-- .. CRC mismatch (computed 1b7c895e wanted 2943108a) --2906-- object doesn't have a symbol table
natiiix

@natiiix キャッシュが取得したときに依存関係がインストールされないvalgrindようにキャッシュが作成した可能性libcがあります。私は現在モニターの近くにいませんが、エラーを調べたところ、valgrindのバグのようです。libcバージョン6をインストールして、それが役立つかどうかを確認することもできます。私は答えを今日後で更新します
smac89

はい、そうです。を追加した場合sudo apt-get install -y libc6-dbg、問題なく機能しますが、そのパッケージのインストールにさらに30秒かかるため、私もここから始めました。
natiiix

@natiiix valgrindのキャッシングは予想よりも作業量が多いようですが、少なくともubuntuでキャッシングを行う方法を示しています。valgrindの依存関係を見ると、少なくとも6つの依存関係があり、これを機能させるには、おそらくすべてをキャッシュする必要があると思います。
smac89

4

あなたはドッカーイメージを作成することができます valgrindプリインストールされその上でワークフローを実行できます。

Dockerfile次のようなものを作成します。

FROM ubuntu

RUN apt-get install -y valgrind

ビルドしてdockerhubにプッシュします。

docker build -t natiiix/valgrind .
docker push natiiix/valgrind

次に、ワークフローとして次のようなものを使用します。

name: C Workflow

on: [push, pull_request]

jobs:
  build:
    container: natiiix/valgrind

    steps:
    - uses: actions/checkout@v1

    - name: make
      run: make

    - name: valgrind
      run: valgrind -v --leak-check=full --show-leak-kinds=all ./bin

完全にテストされていませんが、アイデアはわかります。


これは非常に興味深いアイデアですが、将来の実行のためにGitHubアクションに環境/アーティファクトをキャッシュさせるという全体的な原則を損なうものであり、代わりに私の側から追加の作業が必要になります。一方、一度実行すると、おそらく簡単に再利用できます。
natiiix

1
それは_(ツ)_ /¯あなたのための最高の作品、または何があなたの側から最もoffortを必要とするかを決定するのはあなた次第です
deivid
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.