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
66 changes: 54 additions & 12 deletions .github/actions/cache-test-data/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,18 @@ inputs:
description: "Cache number. Use != 1 to reset data cache"
required: false
default: "1"
mode:
description: "One of restore, save, or restore-save"
required: false
default: "restore"

outputs:
cache-hit:
description: "True if an exact cache key was restored"
value: ${{ steps.restore-test-data.outputs.cache-hit }}
cache-key:
description: "The cache key derived from the registry hash"
value: ${{ env.DATA_CACHE_KEY }}

runs:
using: "composite"
Expand All @@ -17,29 +29,59 @@ runs:
echo "This action requires Python to be installed first."
exit 1
fi
if ! python -c "import pooch" 2>/dev/null; then
echo "❌ Error: Pooch is not installed"
echo "This action requires Pooch to be installed (pip install pooch or include in dependencies)."
exit 1
fi
echo "✅ Prerequisites verified: Python and Pooch are available"
echo "✅ Prerequisites verified: Python is available"

- name: get data registry hash
shell: bash -el {0}
run: |
echo "DATA_REGISTRY_HASH=$(python -c "import pooch; print(pooch.file_hash('dascore/data_registry.txt'))")" >> $GITHUB_ENV
python - <<'PY' >> "$GITHUB_ENV"
from hashlib import sha256
from pathlib import Path

registry_path = Path("dascore/data_registry.txt")
print(f"DATA_REGISTRY_HASH={sha256(registry_path.read_bytes()).hexdigest()}")
PY

- name: get data cache path
shell: bash -el {0}
run: |
echo "DATA_CACHE_PATH=$(python -c "import pooch; print(pooch.os_cache('dascore'))")" >> $GITHUB_ENV
python - <<'PY' >> "$GITHUB_ENV"
import os
import sys
from pathlib import Path

- name: cache test data
uses: actions/cache@v4
id: cache-test-data
home = Path.home()
if sys.platform == "win32":
cache_root = Path(os.environ.get("LOCALAPPDATA", home / "AppData" / "Local"))
elif sys.platform == "darwin":
cache_root = home / "Library" / "Caches"
else:
cache_root = Path(os.environ.get("XDG_CACHE_HOME", home / ".cache"))

print(f"DATA_CACHE_PATH={cache_root / 'dascore'}")
PY

- name: get data cache key
shell: bash -el {0}
run: |
echo "DATA_CACHE_KEY=data-${{ env.DATA_REGISTRY_HASH }}-${{ inputs.cache-number }}" >> $GITHUB_ENV

- name: restore test data cache
if: ${{ inputs.mode == 'restore' || inputs.mode == 'restore-save' }}
uses: actions/cache/restore@v4
id: restore-test-data
with:
enableCrossOsArchive: true
path: ${{ env.DATA_CACHE_PATH }}
key: data-${{ env.DATA_REGISTRY_HASH }}-${{ inputs.cache-number }}
key: ${{ env.DATA_CACHE_KEY }}
restore-keys: |
data-${{ env.DATA_REGISTRY_HASH }}-

- name: save test data cache
if: ${{ inputs.mode == 'save' || inputs.mode == 'restore-save' }}
uses: actions/cache/save@v4
id: cache-test-data
with:
enableCrossOsArchive: true
path: ${{ env.DATA_CACHE_PATH }}
key: ${{ env.DATA_CACHE_KEY }}
5 changes: 2 additions & 3 deletions .github/actions/mamba-install-dascore/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,13 @@ inputs:

install-package:
description: "If true, install dascore"
default: true
default: "true"
required: false
type: boolean

cache-number:
description: "Cache number. Use != 1 to reset data cache"
required: false
default: 1
default: "1"

runs:
using: "composite"
Expand Down
22 changes: 22 additions & 0 deletions .github/scripts/cache_test_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
"""Populate the pooch cache with every file in dascore's data registry."""

from __future__ import annotations

from pathlib import Path

from dascore.utils.downloader import fetch, get_registry_df


def main() -> None:
"""Fetch every registered test-data file into the local pooch cache."""
registry = get_registry_df()
total = len(registry)
print(f"Priming DASCore test-data cache with {total} files") # noqa
for index, name in enumerate(registry["name"], start=1):
path = Path(fetch(name))
print(f"[{index}/{total}] {name} -> {path}") # noqa
print("Finished priming DASCore test-data cache") # noqa


if __name__ == "__main__":
main()
37 changes: 37 additions & 0 deletions .github/workflows/get_coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,44 @@ on:
- master

jobs:
prime_test_data_cache:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- uses: ./.github/actions/load-shared-vars

- uses: actions/setup-python@v6
with:
python-version: ${{ env.PYTHON_DEFAULT }}

- name: Install dascore for cache priming
shell: bash
run: |
python -m pip install --upgrade pip
pip install -e .

- uses: ./.github/actions/cache-test-data
id: cache-test-data
with:
mode: restore
cache-number: 1

- name: Download all registered test data
if: steps.cache-test-data.outputs.cache-hit != 'true'
shell: bash
run: python .github/scripts/cache_test_data.py

- name: Save primed test data cache
if: steps.cache-test-data.outputs.cache-hit != 'true'
uses: ./.github/actions/cache-test-data
with:
mode: save
cache-number: 1

calc_coverage:
needs: prime_test_data_cache
runs-on: ubuntu-latest

steps:
Expand Down
60 changes: 60 additions & 0 deletions .github/workflows/prime_test_data_cache.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: PrimeTestDataCache

on:
workflow_dispatch:
schedule:
- cron: "0 4 * * 1"
push:
branches:
- master
paths:
- "dascore/data_registry.txt"
- ".github/actions/cache-test-data/action.yml"
- ".github/scripts/cache_test_data.py"
- ".github/workflows/prime_test_data_cache.yml"
pull_request:
branches:
- master
paths:
- "dascore/data_registry.txt"
- ".github/actions/cache-test-data/action.yml"
- ".github/scripts/cache_test_data.py"
- ".github/workflows/prime_test_data_cache.yml"

jobs:
prime_test_data_cache:
name: Prime shared test data cache
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- uses: ./.github/actions/load-shared-vars

- uses: actions/setup-python@v6
with:
python-version: ${{ env.PYTHON_DEFAULT }}

- name: Install dascore
shell: bash
run: |
python -m pip install --upgrade pip
pip install -e .

# The cache key is shared across OSes. Each consuming job restores this
# archive into the platform-specific cache path that pooch uses locally.
- uses: ./.github/actions/cache-test-data
id: cache-test-data
with:
mode: restore

- name: Download all registered test data
if: steps.cache-test-data.outputs.cache-hit != 'true'
shell: bash
run: python .github/scripts/cache_test_data.py

- name: Save primed test data cache
if: steps.cache-test-data.outputs.cache-hit != 'true'
uses: ./.github/actions/cache-test-data
with:
mode: save
62 changes: 55 additions & 7 deletions .github/workflows/profile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,24 @@ on:
branches:
- master
pull_request:
types:
- opened
- synchronize
- reopened
- labeled
- unlabeled
workflow_dispatch:

permissions:
contents: read # required for actions/checkout
id-token: write # required for OIDC authentication with CodSpeed

jobs:
benchmarks:
name: Run benchmarks
prime_test_data_cache:
name: Prime test data cache
if: >
github.event_name != 'pull_request' ||
contains(github.event.pull_request.labels.*.name, 'benchmark')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -26,18 +35,57 @@ jobs:

- uses: actions/setup-python@v6
with:
# Defined in .github/actions/load-shared-vars/action.yml
python-version: ${{ env.PYTHON_DEFAULT }}

- name: Install dependencies
run: pip install ".[profile]"
- name: Install dascore for cache priming
run: |
python -m pip install --upgrade pip
pip install -e .

- uses: ./.github/actions/cache-test-data
id: cache-test-data
with:
mode: restore
cache-number: 1

- name: Download all registered test data
if: steps.cache-test-data.outputs.cache-hit != 'true'
run: python .github/scripts/cache_test_data.py

- name: Save primed test data cache
if: steps.cache-test-data.outputs.cache-hit != 'true'
uses: ./.github/actions/cache-test-data
with:
mode: save
cache-number: 1

benchmarks:
name: Run benchmarks
if: >
github.event_name != 'pull_request' ||
contains(github.event.pull_request.labels.*.name, 'benchmark')
needs: prime_test_data_cache
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-tags: "true"
fetch-depth: '0'

- uses: ./.github/actions/load-shared-vars

- uses: ./.github/actions/mamba-install-dascore
with:
# Defined in .github/actions/load-shared-vars/action.yml
python-version: ${{ env.PYTHON_DEFAULT }}
install-group-str: "[profile]"
cache-number: 1
Comment thread
coderabbitai[bot] marked this conversation as resolved.

Comment on lines +62 to 83

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Missing test data cache restore in benchmarks job.

The benchmarks job depends on prime_test_data_cache but doesn't actually restore the cached test data. GitHub Actions caches must be explicitly restored in each job that needs them—the needs directive only ensures job ordering, not cache sharing.

Add a step to restore the test data cache before running benchmarks:

🔧 Proposed fix to add cache restore
       - uses: ./.github/actions/load-shared-vars
 
+      - uses: ./.github/actions/cache-test-data
+        with:
+          mode: restore
+          cache-number: 1
+
       - uses: ./.github/actions/mamba-install-dascore
         with:
🧰 Tools
🪛 actionlint (1.7.11)

[error] 65-65: could not parse action metadata in "/home/jailuser/git/.github/actions/mamba-install-dascore": line 4: unexpected key "type" for definition of input "install-package"

(action)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/profile.yml around lines 53 - 71, The benchmarks job
depends on prime_test_data_cache but never restores the cached test data; add a
step named like "Restore test data cache" at the start of the benchmarks job
(before running setup/install steps such as
./.github/actions/mamba-install-dascore) that uses actions/cache@v3 to restore
the same cache key and paths used by the prime_test_data_cache job (match the
key/paths/restore-keys used there so the cache is actually restored into the
test data directory or env var like TEST_DATA_CACHE_PATH).

- name: Run benchmarks
uses: CodSpeedHQ/action@v4
with:
mode: instrumentation
run: ./.github/test_code.sh profile
mode: simulation
# CodSpeed does not inherit the shell activation done by the
# micromamba setup step, so run benchmarks explicitly inside the
# dascore environment to ensure pytest and pytest-codspeed resolve.
run: micromamba run -n dascore ./.github/test_code.sh profile
42 changes: 41 additions & 1 deletion .github/workflows/run_min_dep_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ on:
- 'pyproject.toml'
- '**.py'
- '.github/workflows/run_min_dep_tests.yml'
- '.github/actions/**/*.yml'

env:
# Ensure matplotlib doesn't try to show figures in CI
Expand All @@ -35,8 +36,47 @@ jobs:
id: load-vars

# Runs the tests on combinations of the supported python/os matrix.
test_code_min_deps:
prime_test_data_cache:
needs: setup
Comment on lines +39 to 40

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Apply no_ci guard to min-deps cache priming

Like the main test workflow, the added prime_test_data_cache job here is unconditional while test_code_min_deps is still skipped for no_ci PRs. That means PRs marked no_ci still execute the expensive cache-priming matrix (and can fail in it), which defeats the intended skip mechanism and introduces avoidable CI failures/cost.

Useful? React with 👍 / 👎.

timeout-minutes: 20
if: github.event_name == 'push' || !contains(github.event.pull_request.labels.*.name, 'no_ci')
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- uses: ./.github/actions/load-shared-vars

- uses: actions/setup-python@v6
with:
python-version: ${{ env.PYTHON_DEFAULT }}

- name: Install dascore for cache priming
shell: bash
run: |
python -m pip install --upgrade pip
pip install -e .

- uses: ./.github/actions/cache-test-data
id: cache-test-data
with:
mode: restore
cache-number: 1

- name: Download all registered test data
if: steps.cache-test-data.outputs.cache-hit != 'true'
shell: bash
run: python .github/scripts/cache_test_data.py

- name: Save primed test data cache
if: steps.cache-test-data.outputs.cache-hit != 'true'
uses: ./.github/actions/cache-test-data
with:
mode: save
cache-number: 1

test_code_min_deps:
needs: [setup, prime_test_data_cache]
timeout-minutes: 25
runs-on: ${{ matrix.os }}
strategy:
Expand Down
Loading
Loading