actions / cache

Cache dependencies and build outputs in GitHub Actions
MIT License
4.59k stars 1.23k forks source link

cache restore on versions 3 and 4 not working #1361

Open mark-jordanovic-lewis opened 8 months ago

mark-jordanovic-lewis commented 8 months ago

The functionality of the cache action seems to be completely broken.

Configurations attempted:

Experimental Workflow and Results

The cache is being accessed on the same branch, in the same workflow (and later, if the first set of jobs pass).

Screenshot 2024-03-19 at 17 07 18 Screenshot 2024-03-19 at 17 17 01

Screenshot 2024-03-19 at 17 20 47

These screenshots pertain to the run of base cache action @v3, they are consistent across all configurations.

Cache version 2 works as expected.

Would definitely prefer to use the most recent versions.

mark-jordanovic-lewis commented 8 months ago

~Cause of the above issue is a difference in the actions/checkout version. There must be a difference in the way they reference the branch.~

matthiasPOE commented 8 months ago

Im currently getting:

Failed to save: Unable to reserve cache with key db09ccc890352b660ddd94bbcf7ce4b880b254099c5050c6059b00b0b4c5777e, another job may be creating this cache. More details: Cache already exists.

Not sure if its related but even deleting all caches it wont recreate them...

serpro69 commented 8 months ago

Same issue here. Have been wracking my brain why this doesn't work and then wanted to eventually open an issue and found out there's one already. Trying v2 now as recommended above.

upd: v2 works as expected

yrtimiD commented 8 months ago

@mark-jordanovic-lewis just to ensure, do you have exactly same value in the "path" parameter both in save and restore? I had different and restore failed too.

mark-jordanovic-lewis commented 8 months ago

Correct. Same parameters in each use of the action.

SimonSchick commented 7 months ago

We are seeing similar issues on v4 where the cache is not found despite clearly existing, only 1/5 runs are picked up correctly, is the cache action not reliable-ish?

njzjz commented 6 months ago

I encountered the same issue. Save v4 + restore v2 cannot work as well. Using save v2 + restore v2 can resolve the problem. However, it seems that Node.js 16 is going to be deprecated.

njzjz commented 6 months ago

I encountered the same issue. Save v4 + restore v2 cannot work as well. Using save v2 + restore v2 can resolve the problem. However, it seems that Node.js 16 is going to be deprecated.

I just found the reason: in v4, the path for restore and save must be the same. The error message doesn't give such information.

wmertens commented 6 months ago

@njzjz I'm encountering this problem too and the paths are the same for me

lsdm83114 commented 6 months ago

1

El dom, 26 de may. de 2024 19:55, Wout Mertens @.***> escribió:

@njzjz https://github.com/njzjz I'm encountering this problem too and the paths are the same for me

— Reply to this email directly, view it on GitHub https://github.com/actions/cache/issues/1361#issuecomment-2132119284, or unsubscribe https://github.com/notifications/unsubscribe-auth/BGG5ZMWZ5SQ7TVB3OGEP663ZEGINXAVCNFSM6AAAAABE574CB6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCMZSGEYTSMRYGQ . You are receiving this because you are subscribed to this thread.Message ID: @.***>

MostefaKamalLala commented 6 months ago

Facing the same issue, any fix anytime soon?

I encountered the same issue. Save v4 + restore v2 cannot work as well. Using save v2 + restore v2 can resolve the problem. However, it seems that Node.js 16 is going to be deprecated.

restore v2 does not exist. it's only cache v2

hammzj commented 6 months ago

I can also confirm that v2 works, but v4 is completely broken. I am running a job with a matrix and am consistently getting failures because it cannot save nor restore the cache correctly.

serpro69 commented 6 months ago

To be frank I'm surprised how a core action like "cache" is still broken and no (visible) steps are taken to fix it... At times github actions seem completely unreliable for anything beyond small open-source stuff that isn't mission-critical.

markfickett commented 5 months ago

I hit this too. I was using actions/cache@v4.0.2 to save a virtual env and some other things, specifying a literal path on that job, and then setting job outputs for the different things in the path (like outputs: venv-path: my-venv). Then in another job, I used actions/cache/restore@v4.0.2 and referenced the same list of paths but via output variables (like paths: ${{ needs.setup-env.outputs.venv-path }}). As others have described, I could see the cache being created (and the setup-env job could pick up its own cache), but the downstream jobs say they can't find the cache. Changing both lists to be literal instead fixed the issue.

Variations of this issue seem to be reported in a number of other issues:

wmertens commented 5 months ago

@markfickett my paths are static and I'm experiencing this issue.

The problem is that it's intermittent.

danielkorte commented 5 months ago

Also confirming v4 is broken. I’m using static paths as well. I downgraded to v2 and everything works now.

matthiasPOE commented 5 months ago

@bethanyj28 @robherley @kotewar sorry about the pings but I cant believe this has been sitting here broken for so long

mark-jordanovic-lewis commented 5 months ago

I have some workflows in which v3 and v4 work consistently and some that fail consistently. I'm not seeing the intermittant success/fail but I do see inconsistenty across workflows.

mark-jordanovic-lewis commented 5 months ago

Cache Experiment Workflow

Amendmenent

Path in cache-container-file has a leading ./. Removal of this results in a cache hit in container-read-container-cache.

on:
  push:

jobs:
  # Cache files `cache-file-runner` and `cache-file-container`
  cache-file-runner:
    runs-on: ubuntu-22.04
    steps:
      - name: Create cache-file
        run: |
          touch cache-file-runner
          echo "I am in ubuntu-latest-runner cache" > cache-file-runner
      - uses: actions/cache/save@v4
        with:
          path: cache-file-runner
          key: ${{ github.sha }}-cache-file-runner
          enableCrossOsArchive: true

  cache-file-container:
    runs-on: ubuntu-22.04
    container:
      image: ubuntu:22.04
    steps:
      - name: Create cache-file
        run: |
          touch cache-file-container
          echo "I am in ubuntu-latest-container cache" > cache-file-container
      - uses: actions/cache/save@v4
        with:
          path: ./cache-file-container
          key: ${{ github.sha }}-cache-file-container
          enableCrossOsArchive: true

  # Read each of the cache files from the runner
  runner-read-runner-cache:
    runs-on: ubuntu-22.04
    needs: ["cache-file-runner", "cache-file-container"]
    steps:
      - uses: actions/cache/restore@v4
        with:
          path: cache-file-runner
          key: ${{ github.sha }}-cache-file-runner
      - name: Check cache-file
        run: |
          if [ -f "cache-file-runner" ]
          then
            echo "Found cached file"
          else
            echo "Cache not restored"
          fi

  runner-read-container-cache:
    runs-on: ubuntu-22.04
    needs: ["cache-file-runner", "cache-file-container"]
    steps:
      - uses: actions/cache/restore@v4
        with:
          path: cache-file-container
          key: ${{ github.sha }}-cache-file-container
      - name: Check cache-file
        run: |
          if [ -f "cache-file-container" ]
          then
            echo "Found cached file"
          else
            echo "Cache not restored"
          fi

  # Read each of the cache files from the container
  container-read-runner-cache:
    runs-on: ubuntu-22.04
    needs: ["cache-file-runner", "cache-file-container"]
    container:
      image: ubuntu:22.04
    steps:
      - uses: actions/cache/restore@v4
        with:
          path: cache-file-runner
          key: ${{ github.sha }}-cache-file-runner
      - name: Check cache-file
        run: |
          if [ -f "cache-file-runner" ]
          then
            echo "Found cached file"
          else
            echo "Cache not restored"
          fi

  container-read-container-cache:
    runs-on: ubuntu-22.04
    needs: ["cache-file-runner", "cache-file-container"]
    container:
      image: ubuntu:22.04
    steps:
      - uses: actions/cache/restore@v4
        with:
          path: cache-file-container
          key: ${{ github.sha }}-cache-file-container
      - name: Check cache-file
        run: |
          if [ -f "cache-file-container" ]
          then
            echo "Found cached file"
          else
            echo "Cache not restored"
          fi

  # CrossOs access
  runner-crossOS-read-container-cache:
    runs-on: ubuntu-22.04
    needs: ["cache-file-runner", "cache-file-container"]
    steps:
      - uses: actions/cache/restore@v4
        with:
          path: cache-file-container
          key: ${{ github.sha }}-cache-file-container
          enableCrossOsArchive: true
      - name: Check cache-file
        run: |
          if [ -f "cache-file-container" ]
          then
            echo "Found cached file"
          else
            echo "Cache not restored"
          fi

  container-crossOS-read-runner-cache:
    runs-on: ubuntu-22.04
    needs: ["cache-file-runner", "cache-file-container"]
    container:
      image: ubuntu:22.04
    steps:
      - uses: actions/cache/restore@v4
        with:
          path: cache-file-runner
          key: ${{ github.sha }}-cache-file-runner
          enableCrossOsArchive: true
      - name: Check cache-file
        run: |
          if [ -f "cache-file-runner" ]
          then
            echo "Found cached file"
          else
            echo "Cache not restored"
         fi

Results

Screenshot 2024-07-05 at 09 02 39 Screenshot 2024-07-05 at 09 03 03 Screenshot 2024-07-05 at 09 03 33 Screenshot 2024-07-05 at 09 03 55 Screenshot 2024-07-05 at 09 04 12 Screenshot 2024-07-05 at 09 04 29

Cache code

I don't really see much in the cache restore code that would lead to this behavior other than how the cache path in Azure is calculated. I think this uses the below function to create a path on the fly? Couldn't see the encodeURI function in the code so can't comment on that.

function createTempDirectory() {
    return __awaiter(this, void 0, void 0, function* () {
        const IS_WINDOWS = process.platform === 'win32';
        let tempDirectory = process.env['RUNNER_TEMP'] || '';
        if (!tempDirectory) {
            let baseLocation;
            if (IS_WINDOWS) {
                // On Windows use the USERPROFILE env variable
                baseLocation = process.env['USERPROFILE'] || 'C:\\';
            }
            else {
                if (process.platform === 'darwin') {
                    baseLocation = '/Users';
                }
                else {
                    baseLocation = '/home';
                }
            }
            tempDirectory = path.join(baseLocation, 'actions', 'temp');
        }
        const dest = path.join(tempDirectory, (0, uuid_1.v4)()); <<< uuid_1.v4 call???
        yield io.mkdirP(dest);
        return dest;
    });
}
exp

but my JS is not good enough to really debug this.

njzjz commented 4 months ago

@mark-jordanovic-lewis I am not sure about other jobs, but for container-read-container-cache, you just need to change path: cache-file-container to path: ./cache-file-container to match the path in cache-file-container.

mark-jordanovic-lewis commented 4 months ago

@mark-jordanovic-lewis I am not sure about other jobs, but for container-read-container-cache, you just need to change path: cache-file-container to path: ./cache-file-container to match the path in cache-file-container.

Correct. Thanks @njzjz.

wmertens commented 4 months ago

I just realized I had a trailing slash in one of the places and not the others. Now I made sure all the path strings are exactly the same and it seems to work without issues.

mdeweerd commented 3 months ago

I confirm that caching works after:

coreymcmahon commented 2 weeks ago

Just want to highlight that we're also having problems with v3 and v4.

Our build (at a high level) does this:

(1) Download dependencies (using Composer as it's a PHP app, but I don't think that detail is important) and cache them using actions/cache/save@v4 (2a) Build frontend assets (after restoring Composer dependencies with actions/cache/restore@v4) (2b) Run static analysis (after restoring Composer dependencies with actions/cache/restore@v4) (3) Run tests

Steps (2a) and (2b) need step (1) and run concurrently after step (1) is finished. The call to actions/cache/restore@v4 works in step 2b and fails in step 2a.

After reverting to v2 this works as expected.

Our workflow file looks something like the following:

name: Tests

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches:
      - '**'

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

jobs:

  composer_install:
    name: Install composer dependencies
    runs-on: ubuntu-latest
    container:
      image: jakzal/phpqa:php8.3-alpine
    steps:
      - uses: actions/checkout@v4
      - name: Cache composer dependencies
        uses: actions/cache/save@v4
        id: cache-composer
        with:
          path: vendor
          key: composer-${{ hashFiles('composer.lock') }}
      - name: Install composer dependencies
        run: composer install --prefer-dist --no-ansi --no-interaction --no-progress

  build_frontend:
    name: Build frontend
    runs-on: ubuntu-latest
    needs: [composer_install]
    container:
      image: node:20.11.0
    steps:
      - uses: actions/checkout@v4
      - name: Cache frontend build
        uses: actions/cache/save@v4
        id: cache-frontend
        with:
          path: public/build
          key: npm-${{ hashFiles('package-lock.json') }}
      - name: Restore composer cache
        uses: actions/cache/restore@v4
        id: restore-composer-cache
        with:
          path: vendor
          key: composer-${{ hashFiles('composer.lock') }}
          fail-on-cache-miss: true
      - name: Install dependencies
        run: npm ci
      - name: Build
        run: npm run build

  static_analysis_check:
    name: Check static analysis
    runs-on: ubuntu-latest
    container:
      image: jakzal/phpqa:php8.3-alpine
    needs: [composer_install]
    steps:
      - uses: actions/checkout@v4
      - name: Restore composer cache
        uses: actions/cache/restore@v4
        id: restore-composer-cache
        with:
          path: vendor
          key: composer-${{ hashFiles('composer.lock') }}
          fail-on-cache-miss: true
      - name: Run PHPStan analysis
        run: php -d memory_limit=-1 vendor/bin/phpstan analyze --error-format=github

  tests:
    name: Run tests
    runs-on: ubuntu-latest
    container:
      image: jakzal/phpqa:php8.3-alpine
    needs: [composer_install, build_frontend]
    steps:
      - uses: actions/checkout@v4
      - name: Restore composer cache
        uses: actions/cache/restore@v4
        id: restore-composer-cache
        with:
          path: vendor
          key: composer-${{ hashFiles('composer.lock') }}
          fail-on-cache-miss: true
      - name: Restore frontend cache
        uses: actions/cache/restore@v4
        id: restore-frontend-cache
        with:
          path: public/build
          key: npm-${{ hashFiles('package-lock.json') }}
          fail-on-cache-miss: true
      # snip... not relevant after this line
JJ-Kamminga commented 1 day ago

Had a similar issue as many in this thread.

Can confirm that it works with an absolute path, inputted identically as path in the restore and save actions (v4).

Would not be an issue IMO if the documentation was clearer on this.