actions / cache

Cache dependencies and build outputs in GitHub Actions
MIT License
4.47k stars 1.19k forks source link

Cache Save/Restore is not working between GitHub Runner and Container, even with the same absolute path. #1455

Open sabbott1877 opened 3 weeks ago

sabbott1877 commented 3 weeks ago

I'm trying to cache files in a standard runner and then access them in a container, but the files aren't being restored as expected.

I noticed the issue mentioned in #1444 (which would be great to have fixed) and read through the guidance in the cross-os-cache docs. From what I understand, the full absolute path for saving and restoring the cache must be identical across environments. In an attempt to address this, I tried placing the files in /tmp/, but even when the full absolute path matches and I've set enableCrossOsArchive: 'true', it still doesn't work. You can see the failure in this run: https://github.com/sabbott1877/cache-issues/actions/runs/10608423120/job/29402474270.

name: Cache Issue Testing
on:
  push:
    branches:
      - '**'

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

permissions:
  contents: read
jobs:
  create-cache:
    name: Setup Cache
    runs-on: ubuntu-latest
    steps:
      - run: | 
          echo ~
          echo $PWD
      # Trying to use /tmp to avoid issues with absolute paths, but still seems to be failing.
      - name: Create files
        run: |
          mkdir -p /tmp/cache-path/
          echo "test" > /tmp/cache-path/file.txt

      - name: Cache Files
        uses: actions/cache/save@v4
        with:
          path: /tmp/cache-path
          key: cache-path-${{ github.run_id }}
          enableCrossOsArchive: 'true'
  read-cache:
    name: Read Cache
    needs: create-cache
    runs-on: ubuntu-latest
    container:
      image: rockylinux:9
      options: -u root
    steps:
      - run: |
          echo ~
          echo $PWD
      - name: Get Cached Files
        uses: actions/cache/restore@v4
        with:
          path: /tmp/cache-path
          key: cache-path-${{ github.run_id }}
          enableCrossOsArchive: 'true'
          fail-on-cache-miss: 'true'
vkuptcov commented 3 weeks ago

Can confirm the issue: have a similar one in one of my projects

vkuptcov commented 2 weeks ago

@sabbott1877 I've found the reason of the issue. The problem is that despite the fact that the same keys are used, cache versions for the container and ubuntu-latest Github runners are different: https://github.com/actions/cache?tab=readme-ov-file#cache-version Cache version depends on used compression method https://github.com/actions/toolkit/blob/6c4e082c181a51609197e536ef5255a0c9baeef7/packages/cache/README.md?plain=1#L15 and default ubuntu-latest uses zstd to compress data. If a container doesn't have zstd installed, gzip will be used instead https://github.com/actions/toolkit/blob/6c4e082c181a51609197e536ef5255a0c9baeef7/packages/cache/src/internal/cacheUtils.ts#L100

The solution for me was to add zstd into the container, and after that I can use caches between my container and GitHub runner.

A better solution might be to allow to explicitly set a compression method via the action parameters.

sb185296 commented 2 weeks ago

@vkuptcov can you sahre what its mean to install zstd what is missing in the pod

can you sahre the steps?

sudo apt-get -y install zstd

thanks

sb185296 commented 2 weeks ago

ya its working !!!

thanks for the help !

sabbott1877 commented 2 weeks ago

Thank you for digging in further and finding a solution! I haven't been able to test it yet, but it seems plausible. I would have thought enableCrossOsArchive: 'true' would have handled this, but maybe that's just focused on windows/linux cross platform.

vkuptcov commented 2 weeks ago

It looks like enableCrossOsArchive: 'true' just tries to solve cross platform issue. And it doesn't solve even the issue when an absolute path not in a workdir is used. If workdirs in a container and in a native runner have different nesting level, the archive is restored not in an absolute path, but in a relative. In general it looks like the interoperability part for this GitHub action is not well designed/implemented yet, there are too many unspecified edge cases.

laverdet commented 2 weeks ago

Yeah it's really bad. I'm having issues with it too. I read in another issue that making sure your relative path starts with ./ fixes some issues but I haven't had a chance to directly investigate that.