Skip to content

Commit 6daad06

Browse files
authored
Add GH action for running tests against upstream dev (#4583)
* Add Upstream dev GH action * Remove unnecessary dependencies * Add build matrix for different python versions * Use pypi nightly wheels for numpy, scipy, etc * Remove debugging statements * Trigger on pull request events * Cancel previous runs that are not completed * Test against Python 3.8 only * Put wheels installation commands into standalone script * if no candidate issue exists; create a new issue, else update an existing one * Update whats-new
1 parent a219215 commit 6daad06

File tree

4 files changed

+191
-0
lines changed

4 files changed

+191
-0
lines changed

.github/workflows/parse_logs.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# type: ignore
2+
import pathlib
3+
4+
files = pathlib.Path("logs").rglob("**/*-log")
5+
files = sorted(filter(lambda x: x.is_file(), files))
6+
7+
message = "\n"
8+
9+
print("Parsing logs ...")
10+
for file in files:
11+
with open(file) as fpt:
12+
print(f"Parsing {file.absolute()}")
13+
data = fpt.read().split("test summary info")[-1].splitlines()[1:-1]
14+
data = "\n".join(data)
15+
py_version = file.name.split("-")[1]
16+
message = f"{message}\n<details>\n<summary>\nPython {py_version} Test Summary Info\n</summary>\n\n```bash\n{data}\n```\n</details>\n"
17+
18+
output_file = pathlib.Path("pytest-logs.txt")
19+
with open(output_file, "w") as fpt:
20+
print(f"Writing output file to: {output_file.absolute()} ")
21+
fpt.write(message)
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
name: CI
2+
on:
3+
push:
4+
branches:
5+
- master
6+
pull_request:
7+
branches:
8+
- master
9+
schedule:
10+
- cron: "0 0 * * *" # Daily “At 00:00” UTC
11+
workflow_dispatch: # allows you to trigger the workflow run manually
12+
13+
jobs:
14+
upstream-dev:
15+
name: upstream-dev
16+
runs-on: ubuntu-latest
17+
defaults:
18+
run:
19+
shell: bash -l {0}
20+
strategy:
21+
fail-fast: false
22+
matrix:
23+
python-version: ["3.8"]
24+
steps:
25+
- name: Cancel previous runs
26+
uses: styfle/[email protected]
27+
with:
28+
access_token: ${{ github.token }}
29+
- uses: actions/checkout@v2
30+
- uses: conda-incubator/setup-miniconda@v2
31+
with:
32+
channels: conda-forge
33+
mamba-version: "*"
34+
activate-environment: xarray-tests
35+
auto-update-conda: false
36+
python-version: ${{ matrix.python-version }}
37+
- name: Set up conda environment
38+
run: |
39+
mamba env update -f ci/requirements/py38.yml
40+
bash ci/install-upstream-wheels.sh
41+
conda list
42+
- name: Run Tests
43+
run: |
44+
python -m pytest --verbose -rf > output-${{ matrix.python-version }}-log
45+
46+
- name: Upload artifacts
47+
if: "failure()&&(github.event_name == 'schedule')&&(github.repository == 'pydata/xarray')" # Check the exit code of previous step
48+
uses: actions/upload-artifact@v2
49+
with:
50+
name: output-${{ matrix.python-version }}-log
51+
path: output-${{ matrix.python-version }}-log
52+
retention-days: 5
53+
54+
report:
55+
name: report
56+
needs: upstream-dev
57+
if: "always()&&(github.event_name == 'schedule')&&(github.repository == 'pydata/xarray')"
58+
runs-on: ubuntu-latest
59+
defaults:
60+
run:
61+
shell: bash
62+
steps:
63+
- uses: actions/checkout@v2
64+
- uses: actions/setup-python@v2
65+
with:
66+
python-version: "3.x"
67+
- uses: actions/download-artifact@v2
68+
with:
69+
path: /tmp/workspace/logs
70+
- name: Move all log files into a single directory
71+
run: |
72+
rsync -a /tmp/workspace/logs/output-*/ ./logs
73+
ls -R ./logs
74+
- name: Parse logs
75+
run: |
76+
python .github/workflows/parse_logs.py
77+
- name: Report failures
78+
uses: actions/github-script@v3
79+
with:
80+
github-token: ${{ secrets.GITHUB_TOKEN }}
81+
script: |
82+
const fs = require('fs');
83+
const pytest_logs = fs.readFileSync('pytest-logs.txt', 'utf8');
84+
const title = "⚠️ Nightly upstream-dev CI failed ⚠️"
85+
const workflow_url = `https://github.com/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`
86+
const issue_body = `[Workflow Run URL](${workflow_url})\n${pytest_logs}`
87+
88+
// Run GraphQL query against GitHub API to find the most recent open issue used for reporting failures
89+
const query = `query($owner:String!, $name:String!, $creator:String!, $label:String!){
90+
repository(owner: $owner, name: $name) {
91+
issues(first: 1, states: OPEN, filterBy: {createdBy: $creator, labels: [$label]}, orderBy: {field: CREATED_AT, direction: DESC}) {
92+
edges {
93+
node {
94+
body
95+
id
96+
number
97+
}
98+
}
99+
}
100+
}
101+
}`;
102+
103+
const variables = {
104+
owner: context.repo.owner,
105+
name: context.repo.repo,
106+
label: 'CI',
107+
creator: "github-actions[bot]"
108+
}
109+
const result = await github.graphql(query, variables)
110+
const issue_info = result.repository.issues.edges[0].node
111+
112+
// If no issue is open, create a new issue, else update the
113+
// body of the existing issue.
114+
if (typeof issue_info.number === 'undefined') {
115+
github.issues.create({
116+
owner: variables.owner,
117+
repo: variables.name,
118+
body: issue_body,
119+
title: title,
120+
labels: [variables.label]
121+
})
122+
} else {
123+
github.issues.update({
124+
owner: variables.owner,
125+
repo: variables.name,
126+
issue_number: issue_info.number,
127+
body: issue_body
128+
})
129+
}

ci/install-upstream-wheels.sh

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#!/usr/bin/env bash
2+
3+
conda uninstall -y --force \
4+
numpy \
5+
scipy \
6+
pandas \
7+
matplotlib \
8+
dask \
9+
distributed \
10+
zarr \
11+
cftime \
12+
rasterio \
13+
pint \
14+
bottleneck \
15+
sparse
16+
python -m pip install \
17+
-i https://pypi.anaconda.org/scipy-wheels-nightly/simple \
18+
--no-deps \
19+
--pre \
20+
--upgrade \
21+
numpy \
22+
scipy \
23+
pandas
24+
python -m pip install \
25+
-f https://7933911d6844c6c53a7d-47bd50c35cd79bd838daf386af554a83.ssl.cf2.rackcdn.com \
26+
--no-deps \
27+
--pre \
28+
--upgrade \
29+
matplotlib
30+
python -m pip install \
31+
--no-deps \
32+
--upgrade \
33+
git+https://github.com/dask/dask \
34+
git+https://github.com/dask/distributed \
35+
git+https://github.com/zarr-developers/zarr \
36+
git+https://github.com/Unidata/cftime \
37+
git+https://github.com/mapbox/rasterio \
38+
git+https://github.com/hgrecco/pint \
39+
git+https://github.com/pydata/bottleneck

doc/whats-new.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ Internal Changes
126126
- Replace the internal use of ``pd.Index.__or__`` and ``pd.Index.__and__`` with ``pd.Index.union``
127127
and ``pd.Index.intersection`` as they will stop working as set operations in the future
128128
(:issue:`4565`). By `Mathias Hauser <https://github.com/mathause>`_.
129+
- Add GitHub action for running nightly tests against upstream dependencies (:pull:`4583`).
130+
By `Anderson Banihirwe <https://github.com/andersy005>`_.
129131

130132
.. _whats-new.0.16.1:
131133

0 commit comments

Comments
 (0)