When I run rspec/rubocop of Rails project on GitHub Acitons, I want to cache the gem with bundle install
, but I get aPermission denied
error and the cache cannot be created properly, and the cache key is polluted [ ^ 1] It was sometimes done.
error example
Post job cleanup.
/bin/tar --posix --use-compress-program zstd -T0 -cf cache.tzst -P -C /home/runner/work/project/project --files-from manifest.txt
/bin/tar: ../../../../../tmp/cache/bundle/gems/puma-5.1.1/ext/puma_http11/.gem.20201227-1-wtkvl5: Cannot open: Permission denied
/bin/tar: ../../../../../tmp/cache/bundle/gems/mini_racer-0.3.1/ext/mini_racer_extension/.gem.
[Omission]
/bin/tar: ../../../../../tmp/cache/bundle/gems/sassc-2.4.0/ext/.gem.20201227-1-1ompol5: Cannot open: Permission denied
/bin/tar: Exiting with failure status due to previous errors
Warning: Tar failed with error: The process '/bin/tar' failed with exit code 2
The above error is that the local / var/cache/bundle
directory is mounted on the container's/bundle
and BUNDLE_PATH =/bundle bundle install
is executed, and/var/cache/bundle
is . Occurs when caching with Actions/Cache
docker-compose and workflow yaml looks like this
docker-compose.yaml
version: '3.7'
services:
app:
...
volumes:
- ./:/app:cached
- /var/cache/bundle:/bundle
yaml:.github/workflows/ci.yml
jobs:
...
rspec:
...
env:
GEMS_CACHE_DIR: /tmp/cache/bundle
steps:
...
- name: Cache bundle gems
id: cache-bundle-gems
uses: actions/cache@v2
with:
path: ${{env.GEMS_CACHE_DIR}}
key: ${{ runner.os }}-${{ matrix.ruby }}-${{ env.GEM_CACHE_TAG }}-${{ hashFiles('Gemfile.lock') }}
restore-keys: |
${{ runner.os }}-${{ matrix.ruby }}-${{ env.GEM_CACHE_TAG }}-
Since it is a problem of access authority, how to rewrite the access authority roughly.
It would be nice if sudo could be added with the tar command when creating the cache, but since there is no such option, insert it at the end of the action steps
as shown below.
yaml:.github/workflows/ci.yml
- name: Fix permissions of bundle
id: fix-permissions-of-bundle
run: sudo chmod -R a+rwx ${{env.GEMS_CACHE_DIR}}
Maybe this way is okay.
However, since the access authority will be rewritten, I can not confirm the operation around that (I think that there is almost no problem ...
The permissions issue occurs because you're doing bundler install
on the container but you're creating the tar locally.
There is no problem if you create a tar of / bundle
on the container and cache the tar with Actions/Cache
.
With the settings below, we are creating a tar by launching only the minimum required lightweight container (this time we are using a container named standalone
).
yaml:.github/workflows/ci.yml
env:
GEMS_ARCHIVE_DIR: /tmp/cache/bundle-gem-archive
...
# $GEMS_ARCHIVE_Cache DIR directory
- name: Cache bundle gems
id: cache-bundle-gems
uses: actions/cache@v2
with:
path: ${{ env.GEMS_ARCHIVE_DIR }}
key: ${{ runner.os }}-${{ matrix.ruby }}-${{ env.GEM_CACHE_TAG }}-${{ hashFiles('Gemfile.lock') }}
restore-keys: |
${{ runner.os }}-${{ matrix.ruby }}-${{ env.GEM_CACHE_TAG }}-
# $GEMS_ARCHIVE_On a lightweight container with DIR mounted/archive/bundle.Extract files from tar
- name: Unarchive bundle gems cache
id: unarchive-bundle-gems-cache
run: test -f ${{env.GEMS_ARCHIVE_DIR}}/bundle.tar
&& docker-compose run --rm -v ${{ env.GEMS_ARCHIVE_DIR }}:/archive:cached standalone
tar -xf /archive/bundle.tar -C /
|| echo "bundle gem cache does not exist."
...
#On a lightweight container$GEM_Harden the contents of HOME with tar,/archive/bundle.Save as tar
- name: Create bundle gems archive
id: create-bundle-gems-archive
if: steps.cache-bundle-gems.outputs.cache-hit != 'true'
run: docker-compose run --rm -v ${{ env.GEMS_ARCHIVE_DIR }}:/archive:cached
standalone tar -cf /archive/bundle.tar -C / bundle
In the case of this method, tar is executed on the container, so it seems to be a little slow, but in my environment, the error (a few seconds) changed (I think it depends on the amount of gem etc.).
Recommended Posts