Skip to content

Add save-pants-cache companion action for cancellation-safe cache saves#48

Open
Affanmir wants to merge 1 commit intopantsbuild:mainfrom
Affanmir:fix/cancellation-safe-cache-save
Open

Add save-pants-cache companion action for cancellation-safe cache saves#48
Affanmir wants to merge 1 commit intopantsbuild:mainfrom
Affanmir:fix/cancellation-safe-cache-save

Conversation

@Affanmir
Copy link
Copy Markdown

@Affanmir Affanmir commented Apr 14, 2026

Summary

BREAKING: init-pants now restores caches only (via actions/cache/restore@v5). A new save-pants-cache companion action must be added at the end of the job to persist caches.

Why: actions/cache@v5 saves via a post-step hook that does not run on workflow cancellation. Workflows using cancel-in-progress: true enter a cold-cache cycle — every cancelled run loses its cache save, so the next run starts cold.

Fix: Split restore and save into separate actions. The save step uses if: always() which fires even on cancellation, breaking the cycle.

Changes

  • init-pants/action.yaml — Switch actions/cache@v5actions/cache/restore@v5, add outputs for cache keys/paths
  • save-pants-cache/action.yamlNew companion action using actions/cache/save@v5
  • READMEs updated with migration guide

Usage

      - uses: pantsbuild/actions/init-pants@main
        id: pants-init
        with:
          named-caches-hash: ${{ hashFiles('lockfiles/*.json') }}

      # ... build/test steps ...

      - uses: pantsbuild/actions/save-pants-cache@main
        if: always()
        with:
          setup-cache-path: ${{ steps.pants-init.outputs.setup-cache-path }}
          setup-cache-key: ${{ steps.pants-init.outputs.setup-cache-key }}
          named-caches-path: ${{ steps.pants-init.outputs.named-caches-path }}
          named-caches-key: ${{ steps.pants-init.outputs.named-caches-key }}
          named-caches-hash: ${{ steps.pants-init.outputs.named-caches-hash }}
          lmdb-store-path: ${{ steps.pants-init.outputs.lmdb-store-path }}
          lmdb-store-key: ${{ steps.pants-init.outputs.lmdb-store-key }}
          cache-lmdb-store: ${{ steps.pants-init.outputs.cache-lmdb-store }}

Context

Discovered in CI where persistent cold caches occurred despite no code changes between runs. GHA cache keys are immutable, so actions/cache/save is a safe no-op when the key already exists.

Test plan

  • init-pants restores caches correctly (setup, named, LMDB)
  • save-pants-cache with if: always() saves caches on normal completion
  • Cache saves survive cancel-in-progress cancellation
  • Cache keys match between init-pants outputs and save-pants-cache inputs

BREAKING: init-pants now restores caches only (actions/cache/restore).
Add pantsbuild/actions/save-pants-cache with if: always() at the end of
your job to persist caches. This ensures saves survive workflow
cancellation (cancel-in-progress: true), which post-step hooks do not.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Affanmir Affanmir force-pushed the fix/cancellation-safe-cache-save branch from 0cdbb04 to 89a00ce Compare April 14, 2026 06:36
@Affanmir Affanmir changed the title Add cancellation-safe cache save mode for init-pants Add save-pants-cache companion action for cancellation-safe cache saves Apr 14, 2026
@benjyw
Copy link
Copy Markdown
Contributor

benjyw commented Apr 15, 2026

It's probably a bad idea to break all the existing users by making the existing action not save the cache. Plus that usage snippet is very verbose, since we have to set up all those paths.

Is it possible to have an optional save action, and it only runs if the earlier job was cancelled?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants