Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CI: Run tests on GHA, using Anaconda #138

Closed
wants to merge 4 commits into from
Closed
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
113 changes: 113 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
name: Tests

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

# Allow job to be triggered manually.
workflow_dispatch:

# Cancel in-progress jobs when pushing to the same branch.
concurrency:
cancel-in-progress: true
group: ${{ github.workflow }}-${{ github.ref }}

jobs:
tests:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: ["ubuntu-latest"]
python-version: ["3.9", "3.10", "3.11"]
# In order to save resources, only run particular
# matrix slots on other OS than Linux.
include:
- os: "macos-latest"
python-version: "3.11"
- os: "windows-latest"
python-version: "3.11"
Comment on lines +20 to +31
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Let me know if you want to see any adjustments to the test matrix configuration.

I've not added Python 3.8 here, in order to save resources, and, in a similar spirit, the recipe will only run a single version of Python on non-Linux operating systems. I see that you designated Python 3.10 to be the "default" version supported by Herbie, but I think it is safe to bump that to Python 3.11.

On regular operations, you would toggle to fail-fast: true, in order to save further resources: It will cancel other jobs when a test job fails on one test matrix slot, because it does not make sense to continue running them.

Using fail-fast: false makes sense when working on the workflow recipe itself, in order to get the big picture if specific tests would only fail on Windows, for example, and you don't want them to cancel the jobs running on Linux.


env:
OS: ${{ matrix.os }}
PYTHON: ${{ matrix.python-version }}

defaults:
run:
shell: bash -el {0}

name: Python ${{ matrix.python-version }} on OS ${{ matrix.os }}
steps:

- name: Acquire sources
uses: actions/checkout@v3
with:
fetch-depth: 2

- name: CACHING - Anaconda packages
uses: actions/cache@v3
id: cache-pkg
with:
path: ~/conda_pkgs_dir
key:
conda-pkg-${{ runner.os }}-${{ runner.arch }}-py${{ matrix.python-version }}-${{
env.CACHE_NUMBER }}-${{ hashFiles('environment-test.yml') }}
env:
# Increase this value if `environment-test.yml` has not changed,
# but you still want to reset the cache.
CACHE_NUMBER: 0

- name: INSTALL - Anaconda setup (Mambaforge)
uses: conda-incubator/setup-miniconda@v2
with:
python-version: ${{ matrix.python-version }}
miniforge-variant: Mambaforge
miniforge-version: latest
mamba-version: "*"
use-mamba: true
channels: conda-forge,defaults
channel-priority: true
activate-environment: herbie-test
auto-activate-base: false
use-only-tar-bz2: true # IMPORTANT: This needs to be set for caching to work properly!

- name: CACHING - Anaconda environment
uses: actions/cache@v3
id: cache-env
with:
path: ${{ env.CONDA }}/envs
key:
conda-env-${{ runner.os }}-${{ runner.arch }}-py${{ matrix.python-version }}-${{
env.CACHE_NUMBER }}-${{ hashFiles('environment-test.yml') }}
env:
# Increase this value if `environment-test.yml` has not changed,
# but you still want to reset the cache.
CACHE_NUMBER: 0

- name: DEBUG - Anaconda info
run: conda info
- name: DEBUG - Anaconda configuration
run: conda config --show
- name: DEBUG - Environment variables
run: printenv | sort
- name: DEBUG - Program paths
run: |
command -v conda
command -v mamba

- name: INSTALL - Update Anaconda environment
run:
mamba env update --name herbie-test --file environment-test.yml
if: steps.cache-env.outputs.cache-hit != 'true'

- name: INSTALL - Project
run: |
pip install --editable=.

- name: Run tests
env:
TMPDIR: ${{ runner.temp }}
run: |
pytest -vvv -k test_ecmwf
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just running a single test here for the sake of saving resources while iterating on the baseline setup, and to see the full test matrix succeed faster. It think it can be adjusted within a subsequent iteration, after seeing the test suite succeed on your end.

2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ core.*
*.grib2
!sample_data/hrrr/20201214/subset_20201214_hrrr.t00z.wrfsfcf12.grib2

.idea
.venv*
sandbox/
sandbox*

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

![](https://img.shields.io/github/license/blaylockbk/Herbie)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
[![Tests](https://github.com/blaylockbk/Herbie/actions/workflows/tests.yml/badge.svg)](https://github.com/blaylockbk/Herbie/actions/workflows/tests.yml)
[![Conda Recipe](https://img.shields.io/badge/recipe-herbie--data-green.svg)](https://anaconda.org/conda-forge/herbie-data)
[![Conda Downloads](https://img.shields.io/conda/dn/conda-forge/herbie-data.svg)](https://anaconda.org/conda-forge/herbie-data)
[![Conda Platforms](https://img.shields.io/conda/pn/conda-forge/herbie-data.svg)](https://anaconda.org/conda-forge/herbie-data)
Expand Down
6 changes: 2 additions & 4 deletions environment-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ name: herbie-test
channels:
- conda-forge
dependencies:
- python>=3.10
- python>=3.8
- pip

#==============
Expand All @@ -17,6 +17,7 @@ dependencies:
- numpy
- pandas
- pygrib
- pytest
- requests
- toml
- xarray>=2022.6.0
Expand All @@ -28,6 +29,3 @@ dependencies:
- eccodes # required by cfgrib
- geos # required by cartopy
- proj # required by cartopy

- pip:
- herbie-data
Comment on lines -31 to -33
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've used the environment-test.yml file to setup the Conda environment, because it was already close to what was needed there. I see that you might have been using it differently, because it installed the herbie-data package from PyPI. However, on CI, when running code from a pull request, the code from the repository should be used.

Let me know if you can adjust your workflow, or if you have other suggestions.

9 changes: 9 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,12 @@ write_to = "herbie/_version.py"

[tool.isort]
profile = "black"

[tool.pytest.ini_options]
minversion = "2.0"
addopts = "-rsfEX -p pytester --strict-markers --verbosity=3"
log_level = "DEBUG"
testpaths = ["tests"]
xfail_strict = true
markers = [
]
61 changes: 32 additions & 29 deletions tests/test_hrrr.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
Tests for downloading HRRR model
"""
from datetime import datetime, timedelta
from shutil import which

import pytest

from herbie import Herbie, Path
import os
Expand All @@ -16,6 +19,9 @@
yesterday_str = yesterday.strftime("%Y-%m-%d %H:%M")
save_dir = Path("$TMPDIR/Herbie-Tests/").expand()

# Location of wgrib2 command, if it exists
wgrib2 = which("wgrib2")


def test_hrrr_aws1():
# Test HRRR with datetime.datetime date
Expand Down Expand Up @@ -78,39 +84,36 @@ def test_do_not_remove_file():
assert H.get_localFilePath(var).exists()


@pytest.mark.skipif(wgrib2 is None, reason="wgrib2 not installed")
def test_make_idx_with_wgrib():
import shutil

if shutil.which("wgrib2"):
H = Herbie(
"2022-12-13 6:00",
model="hrrr",
product="sfc",
save_dir=save_dir,
)
H.download(verbose=True)
H = Herbie(
"2022-12-13 6:00",
model="hrrr",
product="sfc",
save_dir=save_dir,
)
H.download(verbose=True)

# Pretent this was a local file
H.idx = None
H.idx_source = None
H.grib_source = "local"
# Pretent this was a local file
H.idx = None
H.idx_source = None
H.grib_source = "local"

# Generate IDX file
df = H.read_idx()
assert len(df), "Length of index file is 0."
assert H.idx_source == "generated", "Doesn't look like a generated idx file."
# Generate IDX file
df = H.read_idx()
assert len(df), "Length of index file is 0."
assert H.idx_source == "generated", "Doesn't look like a generated idx file."


@pytest.mark.skipif(wgrib2 is None, reason="wgrib2 not installed")
def test_create_idx_with_wgrib2():
"""Test that Herbie can make an index file with wgrib2 when an index file is not found"""
if os.name != "nt":
# If not windows (nt), then try using wgrib2
H = Herbie(
today_str,
model="hrrr",
product="sfc",
save_dir=save_dir,
)
H.download()
H.idx = None
assert len(H.index_as_dataframe) > 0
H = Herbie(
today_str,
model="hrrr",
product="sfc",
save_dir=save_dir,
)
H.download()
H.idx = None
assert len(H.index_as_dataframe) > 0