@@ -12,43 +12,54 @@ The dashboard is published to
1212[ astropy.github.io/astropy-integration-testing] ( https://astropy.github.io/astropy-integration-testing/ )
1313after each scheduled run.
1414
15+ The harness itself is not astropy-specific: ` core_package ` in
16+ ` packages.yaml ` defines the ecosystem's core package, so the same code
17+ can drive integration testing for another ecosystem (e.g. sunpy) just
18+ by pointing the config at a different core package and package list.
19+
1520How it works
1621------------
1722
1823The ` variant ` job runs on a schedule (and on ` workflow_dispatch ` ) as a
19- matrix over astropy variant and Python version. The three variants are:
20-
21- | Variant | Astropy | Each package |
22- | ----------| -----------------------------------------------------| ----------------------------------------|
23- | ` stable ` | Latest non-pre-release on PyPI | Latest non-pre-release on PyPI |
24- | ` pre ` | Latest including pre-releases (` --prerelease=allow ` )| Latest including pre-releases |
25- | ` dev ` | Latest dev wheel from the astropy/simple channel | ` git+<repo_url> ` (HEAD of main branch) |
26-
27- Within each matrix job, a single shared venv is built and packages are
28- installed one at a time in a deterministic order (coordinated first,
29- alphabetical within each tier). If a package can't be installed
30- alongside the existing venv (e.g., it pins ` astropy<7 ` but we already
31- installed astropy 8), it's skipped and recorded; the rest of the venv
32- is untouched. After installs, ` pytest --pyargs <module> ` runs for each
33- package that installed successfully.
34-
35- The ` dashboard ` job then downloads the per-matrix-job result JSONs and
36- publishes the dashboard to ` gh-pages ` .
24+ matrix over the * columns* configured in ` packages.yaml ` . Each column is
25+ an independent (Python version, variant) pair — the two axes are not a
26+ cross-product, so you can test e.g. ` 3.12 + stable ` , ` 3.13 + pre ` and
27+ ` 3.14 + dev ` if you want. The three variants are:
28+
29+ | Variant | Core package | Each package |
30+ | ----------| -------------------------------------------------------| ----------------------------------------|
31+ | ` stable ` | Latest non-pre-release on PyPI | Latest non-pre-release on PyPI |
32+ | ` pre ` | Latest including pre-releases (` --prerelease=allow ` ) | Latest including pre-releases |
33+ | ` dev ` | Latest dev wheel from ` core_package.dev_index_urls ` (or ` git+repo_url ` if unset) | ` git+<repo_url> ` (HEAD of main branch) |
34+
35+ Within each matrix job, a single shared venv is built: the core package
36+ is installed first, then each package one at a time in a deterministic
37+ order (coordinated first, alphabetical within each tier). If a package
38+ can't be installed alongside the existing venv (e.g., it pins
39+ ` astropy<7 ` but we already installed astropy 8), it's skipped and
40+ recorded; the rest of the venv is untouched. After installs, `pytest
41+ --pyargs <module >` runs for each package that installed successfully.
42+
43+ A small ` setup ` job parses ` columns: ` from ` packages.yaml ` and emits it
44+ as the workflow matrix, so the column list has a single source of
45+ truth. The ` dashboard ` job then downloads the per-matrix-job result
46+ JSONs and publishes the dashboard to ` gh-pages ` .
3747
3848What's in the repo
3949------------------
4050
4151| File | Purpose |
4252| ---------------------------------------| ------------------------------------------------------|
43- | ` packages.yaml ` | The list of packages tested + ` python_versions ` to test against. |
44- | ` astropy_integration/run.py ` | Runs one or more (variant, python) combos: resolve specs, install, test, write ` results/<variant>__<python>.json ` . |
53+ | ` packages.yaml ` | The config: ` core_package ` , the ` columns ` to test, and the ` packages ` list. |
54+ | ` astropy_integration/config.py ` | Loads and validates ` packages.yaml ` (shared by ` run ` and ` dashboard ` ). |
55+ | ` astropy_integration/run.py ` | Runs one or more columns: resolve specs, install, test, write ` results/<variant>__<python>.json ` . |
4556| ` astropy_integration/dashboard.py ` | Reads ` results/*.json ` , renders ` site/index.html ` (single self-contained page). |
4657| ` astropy_integration/cli.py ` | Console entry point that dispatches the ` run ` and ` dashboard ` subcommands. |
4758| ` astropy_integration/status.py ` | Shared status vocabulary (used by both ` run ` and ` dashboard ` ). |
4859| ` astropy_integration/templates/ ` | HTML/CSS for the dashboard (loaded as package data). |
4960| ` pyproject.toml ` | Package metadata; declares the ` astropy-integration ` console script. |
5061| ` conftest.py ` | Repo-root pytest plugin that caps each package to the first ` PYTEST_LIMIT_N ` tests for PR previews. |
51- | ` .github/workflows/integration.yml ` | The matrix workflow (variant x python + dashboard). |
62+ | ` .github/workflows/integration.yml ` | The matrix workflow (` setup ` builds the matrix, ` variant ` runs each column, ` dashboard ` publishes). |
5263| ` .github/workflows/preview-link.yml ` | Companion that posts the "View dashboard preview" status check on PRs. |
5364| ` sunpy_pytest.ini ` | Custom pytest config referenced by sunpy's ` pytest_args ` (sunpy's own config requires plugins we don't install). |
5465
@@ -78,23 +89,49 @@ python -m http.server -d site 8000
7889Results land in ` results/<variant>__<python>.json ` ; the dashboard in
7990` site/ ` . Both directories are gitignored.
8091
81- Python versions
82- ---------------
92+ Core package
93+ ------------
94+
95+ ` packages.yaml ` has a top-level ` core_package ` block — the package
96+ installed into the shared venv before everything else:
97+
98+ ``` yaml
99+ core_package :
100+ pypi_name : astropy
101+ module : astropy
102+ repo_url : https://github.com/astropy/astropy.git
103+ # dev variant: install nightly wheels from these indexes.
104+ # omit to install the dev version from git+repo_url instead.
105+ dev_index_urls :
106+ - https://pypi.anaconda.org/astropy/simple
107+ - https://pypi.anaconda.org/liberfa/simple
108+ ` ` `
109+
110+ To retarget the harness at a different ecosystem, point ` core_package`
111+ at that ecosystem's core package and replace the `packages` list.
112+ ` dashboard_title` (also top-level) sets the dashboard's heading.
113+
114+ Columns
115+ -------
83116
84- ` packages.yaml ` has a top-level ` python_versions ` list (uv notation,
85- so ` "3.14t" ` means the free-threaded 3.14 build):
117+ ` packages.yaml` has a top-level `columns` list. Each column is one
118+ (Python version, variant) pair and becomes one dashboard column;
119+ Python version and variant are independent, so list whatever
120+ combinations you want (uv notation for Python, so `"3.14t"` is the
121+ free-threaded 3.14 build) :
86122
87123` ` ` yaml
88- python_versions :
89- - " 3.12"
90- - " 3.14t"
124+ columns:
125+ - {python: "3.12", variant: stable}
126+ - {python: "3.13", variant: pre}
127+ - {python: "3.14t", variant: dev}
91128` ` `
92129
93- The runner tests every ( variant x python_version) combination. The
94- dashboard renders Python versions as grouped header columns above the
95- three variants. **Keep the ` matrix. python` list in
96- ` .github/workflows/integration.yml ` in sync** with this — the CI uses
97- its own matrix because GitHub Actions can't read it from YAML directly .
130+ The runner tests every column; `-- variant` / `--python` narrow that to
131+ a subset. The dashboard groups consecutive columns that share a Python
132+ version under a spanning header, so a classic ` python x variant`
133+ layout still renders as grouped columns. The CI matrix is generated
134+ from this list by the `setup` job, so there's nothing to keep in sync .
98135
99136Adding or disabling a package
100137-----------------------------
@@ -118,15 +155,15 @@ Triggering a run from GitHub
118155
1191561. Actions tab -> `integration-matrix` workflow.
1201572. "Run workflow" dropdown -> green button.
121- 3. The matrix expands to `len(variants) x len(python_versions)`
122- parallel jobs; the `dashboard ` job waits for them and publishes
123- to `gh-pages`.
158+ 3. The `setup` job reads `columns:` from `packages.yaml` and the
159+ matrix expands to one parallel `variant ` job per column; the
160+ ` dashboard ` job waits for them and publishes to `gh-pages`.
124161
125162PR previews
126163-----------
127164
128- ` integration-matrix` also runs on pull requests. Same three-variant
129- matrix as the scheduled run, just with a different final step : the
165+ ` integration-matrix` also runs on pull requests. Same column matrix
166+ as the scheduled run, just with a different final step : the
130167` dashboard` job uploads `site/index.html` as a non-zipped artifact
131168(`actions/upload-artifact@v7` with `archive : false`) instead of
132169publishing to gh-pages. The companion `preview-link` workflow
0 commit comments