diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index b22bb5673b1..b7ecb922edd 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -9,9 +9,11 @@ on: types: [opened, reopened, synchronize] push: # PR events cover draft and fork PRs without also checking copy-pr-bot's - # pull-request/N mirrors. Only main needs a push check. + # pull-request/N mirrors. Only the default branch needs a push check, and + # it is the only ref that refreshes the saved cache (see the save step). branches: - "main" + - "ctk-next" workflow_dispatch: {} concurrency: @@ -42,6 +44,8 @@ jobs: # Link checks have their own Linux workflow. The installation reminder # is for developer machines; CI does not install a Git commit hook. SKIP: lychee,check-precommit-installed + # Minor version used by setup-python and as the cache restore-key prefix. + PYTHON_VERSION: "3.14" steps: - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -53,19 +57,40 @@ jobs: id: python uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: - python-version: '3.14' + python-version: ${{ env.PYTHON_VERSION }} - name: Set pre-commit cache location run: echo "PRE_COMMIT_HOME=${RUNNER_TEMP}/pre-commit" >> "${GITHUB_ENV}" - - name: Cache pre-commit environments - uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + - name: Restore pre-commit cache + id: precommit-cache + uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: path: ${{ env.PRE_COMMIT_HOME }} - key: pre-commit-${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{ hashFiles('.pre-commit-config.yaml') }} + # The full patch version keeps the key exact, so a patch bump misses + # and re-saves. The minor-version restore-key still partially hits on + # that bump, so hooks rebuild from a warm cache instead of cold. The + # prefix stops at the minor with no trailing separator, so it is a + # prefix of "py3.14.-..." regardless of the separator that + # follows the resolved version. + key: pre-commit-${{ runner.os }}-py${{ steps.python.outputs.python-version }}-${{ hashFiles('.pre-commit-config.yaml') }} + restore-keys: | + pre-commit-${{ runner.os }}-py${{ env.PYTHON_VERSION }} - name: Install pre-commit run: python -m pip install --upgrade pip pre-commit - name: Run pre-commit run: pre-commit run --all-files --show-diff-on-failure + + - name: Save pre-commit cache + # Only the default branch saves, so per-PR merge refs don't store their + # own duplicate copies. !cancelled() keeps a push that fails lint from + # discarding the valid hook environments. Skipping on an exact key hit + # avoids re-saving identical content; a patch-bump partial hit still + # saves because cache-hit is only 'true' on an exact match. + if: ${{ !cancelled() && github.ref_name == github.event.repository.default_branch && steps.precommit-cache.outputs.cache-hit != 'true' }} + uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: ${{ env.PRE_COMMIT_HOME }} + key: pre-commit-${{ runner.os }}-py${{ steps.python.outputs.python-version }}-${{ hashFiles('.pre-commit-config.yaml') }}