Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .github/actions/cache-keys/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---

name: placeholder
description: placeholder

outputs:
cache-key-for-dep-files:
description: >-
A cache key string derived from the dependency declaration files.
value: ${{ steps.calc-cache-key-files.outputs.files-hash-key }}

runs:
using: composite
steps:
- name: >-
Calculate dependency files' combined hash value
for use in the cache key
id: calc-cache-key-files
run: |
from os import environ
from pathlib import Path

FILE_APPEND_MODE = 'a'

files_derived_hash = '${{
hashFiles(
'tox.ini',
'pyproject.toml',
'.pre-commit-config.yaml',
'pytest.ini',
'requirements/**'
)
}}'

print(f'Computed file-derived hash is {files_derived_hash}.')

with Path(environ['GITHUB_OUTPUT']).open(
mode=FILE_APPEND_MODE,
) as outputs_file:
print(
f'files-hash-key={files_derived_hash}',
file=outputs_file,
)
shell: python

...
114 changes: 114 additions & 0 deletions .github/actions/cache-pip-deps/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
---

name: placeholder
description: placeholder

inputs:
cache-key-for-dep-files:
description: >-
A cache key string derived from the dependency declaration files.
required: true

outputs:
cache-key-for-pip-deps:
description: >-
A cache key string derived from the current interpreter version
and the dependency file hashes.
value: >-
${{ steps.python-runtime.outputs.cache-entry-key }}
cache-key-for-python-interpreter:
description: >-
A cache key string derived from the current interpreter version.
value: >-
${{ steps.python-runtime.outputs.restore-key-prefix }}
cache-key-for-os:
description: >-
A cache key string derived from the current OS and interpreter stability.
value: >-
${{ steps.python-runtime.outputs.restore-key-fallback-prefix }}
is-stable-abi:
description: >-
Whether the currently used Python version has a reliable
Application Binary Interface. If it doesn't, it's best to avoid
caching any dependencies.
value: ${{ steps.python-runtime.outputs.is-stable-abi }}
pip-cache-dir:
description: >-
The discovered pip cache directory path.
value: ${{ steps.pip-cache-dir.outputs.dir }}

runs:
using: composite
steps:
- name: >-
Calculate Python interpreter properties
version hash value
for use in the cache key
id: python-runtime
run: |
from hashlib import sha512
from os import environ
from sys import version, version_info

FILE_APPEND_MODE = 'a'

is_stable_abi = version_info.releaselevel == 'final'
version_hash = sha512(version.encode()).hexdigest()

stable_or_unstable = f'{"" if is_stable_abi else "un"}stable'
restore_key_fallback_prefix = (
f'${{ runner.os }}-pip-{stable_or_unstable}'
)
restore_key_prefix = f'{restore_key_fallback_prefix}-{version_hash}'
cache_entry_key = (
f'{restore_key_prefix}-{version_hash}-'
'${{ inputs.cache-key-for-dep-files }}'
)

print(f'Python ABI is found to be {stable_or_unstable}.')
print(f'Python version-derived hash is {version_hash}.')
print(f'The computed cache entry key is {cache_entry_key}.')

with open(
environ['GITHUB_OUTPUT'], mode=FILE_APPEND_MODE,
) as outputs_file:
print(
'is-stable-abi={is_stable_abi}'.
format(is_stable_abi=str(is_stable_abi).lower()),
file=outputs_file,
)
print(
f'restore-key-fallback-prefix={restore_key_fallback_prefix}',
file=outputs_file,
)
print(
f'restore-key-prefix={restore_key_prefix}',
file=outputs_file,
)
print(f'cache-entry-key={cache_entry_key}', file=outputs_file)
shell: python
- name: Get pip cache dir
id: pip-cache-dir
run: >-
echo "dir=$(python -m pip cache dir)" >> "${GITHUB_OUTPUT}"
shell: bash
- name: Skip setting up pip cache
if: >-
!fromJSON(steps.python-runtime.outputs.is-stable-abi)
run: >-
>&2 echo Skipping cache configuration because the current
Python ABI is unstable...
shell: bash
- name: Set up pip cache
if: fromJSON(steps.python-runtime.outputs.is-stable-abi)
uses: actions/cache@v4
with:
path: ${{ steps.pip-cache-dir.outputs.dir }}
key: >-
${{ steps.python-runtime.outputs.cache-entry-key }}
restore-keys: |
${{ steps.python-runtime.outputs.cache-entry-key }}
${{ steps.python-runtime.outputs.restore-key-prefix }}
${{ steps.python-runtime.outputs.restore-key-fallback-prefix }}

...
25 changes: 20 additions & 5 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,16 @@ jobs:
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_LATEST }}
cache: pip
cache-dependency-path:
requirements/*.txt
- name: >-
Calculate dependency files' combined hash value
for use in the cache key
id: calc-cache-key-files
uses: ./.github/actions/cache-keys
- name: Set up pip cache
uses: ./.github/actions/cache-pip-deps
with:
cache-key-for-dep-files: >-
${{ steps.calc-cache-key-files.outputs.cache-key-for-dep-files }}
- name: Install core libraries for build
run: python -Im pip install build
- name: Build sdists and pure-python wheel
Expand Down Expand Up @@ -220,8 +227,16 @@ jobs:
with:
python-version: ${{ matrix.pyver }}
allow-prereleases: true
cache: pip
cache-dependency-path: requirements/*.txt
- name: >-
Calculate dependency files' combined hash value
for use in the cache key
id: calc-cache-key-files
uses: ./.github/actions/cache-keys
- name: Set up pip cache
uses: ./.github/actions/cache-pip-deps
with:
cache-key-for-dep-files: >-
${{ steps.calc-cache-key-files.outputs.cache-key-for-dep-files }}
- name: Install dependencies
uses: py-actions/py-dependency-install@v4
with:
Expand Down
12 changes: 10 additions & 2 deletions .github/workflows/reusable-linters.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,16 @@ jobs:
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_LATEST }}
cache: pip
cache-dependency-path: requirements/*.txt
- name: >-
Calculate dependency files' combined hash value
for use in the cache key
id: calc-cache-key-files
uses: ./.github/actions/cache-keys
- name: Set up pip cache
uses: ./.github/actions/cache-pip-deps
with:
cache-key-for-dep-files: >-
${{ steps.calc-cache-key-files.outputs.cache-key-for-dep-files }}
- name: Cache pre-commit.com virtualenvs
uses: actions/cache@v4
with:
Expand Down
2 changes: 2 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -233,5 +233,7 @@ repos:
- 'SC2086:'
- -ignore
- 'SC1004:'
exclude: >-
^[.]github/actions/.*$

...
2 changes: 2 additions & 0 deletions CHANGES/622.contrib.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
GitHub Actions CI/CD is now configured to manage caching pip-managed
dependencies using in-tree composite actions -- by :user:`webknjaz`.
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ include LICENSE
include CHANGES.rst
include README.rst
include CONTRIBUTORS.txt
graft .github/actions
graft frozenlist
graft packaging
graft docs
Expand Down
Loading