orbix 2.0.0__tar.gz → 3.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- orbix-3.0.0/.codespellrc +4 -0
- orbix-3.0.0/.editorconfig +15 -0
- orbix-3.0.0/.gitattributes +10 -0
- orbix-3.0.0/.github/dependabot.yml +30 -0
- orbix-3.0.0/.github/scripts/ci_summary.py +77 -0
- orbix-3.0.0/.github/sibling-pins.txt +5 -0
- orbix-3.0.0/.github/workflows/ci.yml +208 -0
- {orbix-2.0.0 → orbix-3.0.0}/.github/workflows/docs.yml +11 -4
- orbix-3.0.0/.github/workflows/hygiene.yml +40 -0
- {orbix-2.0.0 → orbix-3.0.0}/.github/workflows/publish-to-pypi.yml +14 -7
- {orbix-2.0.0 → orbix-3.0.0}/.github/workflows/release-please.yml +5 -3
- orbix-3.0.0/.github/workflows/upstream.yml +146 -0
- orbix-3.0.0/.github/zizmor.yml +6 -0
- {orbix-2.0.0 → orbix-3.0.0}/.gitignore +3 -0
- {orbix-2.0.0 → orbix-3.0.0}/.pre-commit-config.yaml +5 -1
- {orbix-2.0.0 → orbix-3.0.0}/CHANGELOG.md +52 -1
- {orbix-2.0.0 → orbix-3.0.0}/PKG-INFO +39 -12
- {orbix-2.0.0 → orbix-3.0.0}/README.md +11 -0
- orbix-3.0.0/SECURITY.md +9 -0
- {orbix-2.0.0 → orbix-3.0.0}/docs/conf.py +3 -0
- {orbix-2.0.0 → orbix-3.0.0}/docs/examples/orbits.md +9 -1
- {orbix-2.0.0 → orbix-3.0.0}/docs/examples/prepared.md +3 -1
- {orbix-2.0.0 → orbix-3.0.0}/docs/gallery.md +6 -0
- orbix-3.0.0/docs/index.md +70 -0
- orbix-3.0.0/pyproject.toml +119 -0
- {orbix-2.0.0 → orbix-3.0.0}/src/orbix/_version.py +2 -2
- {orbix-2.0.0 → orbix-3.0.0}/src/orbix/equations/__init__.py +1 -1
- {orbix-2.0.0 → orbix-3.0.0}/src/orbix/equations/lambert.py +7 -5
- {orbix-2.0.0 → orbix-3.0.0}/src/orbix/equations/orbit.py +55 -13
- {orbix-2.0.0 → orbix-3.0.0}/src/orbix/equations/propagation.py +37 -19
- {orbix-2.0.0 → orbix-3.0.0}/src/orbix/kepler/core.py +33 -22
- {orbix-2.0.0 → orbix-3.0.0}/src/orbix/kepler/shortcuts/fixed_e.py +4 -4
- {orbix-2.0.0 → orbix-3.0.0}/src/orbix/kepler/shortcuts/grid.py +26 -30
- {orbix-2.0.0 → orbix-3.0.0}/src/orbix/observatory/orbit.py +2 -2
- {orbix-2.0.0 → orbix-3.0.0}/src/orbix/orbit.py +42 -23
- {orbix-2.0.0 → orbix-3.0.0}/src/orbix/viz/_prepare.py +3 -2
- {orbix-2.0.0 → orbix-3.0.0}/src/orbix/viz/anim.py +5 -0
- {orbix-2.0.0 → orbix-3.0.0}/src/orbix/viz/orbit.py +19 -3
- orbix-3.0.0/tests/conftest.py +18 -0
- orbix-3.0.0/tests/test_dependency_floors.py +34 -0
- {orbix-2.0.0 → orbix-3.0.0}/tests/test_equations_grads.py +9 -4
- orbix-3.0.0/tests/test_fixed_e_solvers.py +85 -0
- orbix-3.0.0/tests/test_grid_solvers.py +160 -0
- orbix-3.0.0/tests/test_kepler_core.py +159 -0
- {orbix-2.0.0 → orbix-3.0.0}/tests/test_kepler_markley.py +62 -20
- {orbix-2.0.0 → orbix-3.0.0}/tests/test_lambert.py +1 -1
- {orbix-2.0.0 → orbix-3.0.0}/tests/test_observatory.py +68 -9
- {orbix-2.0.0 → orbix-3.0.0}/tests/test_orbit.py +162 -85
- orbix-3.0.0/tests/test_sky_convention.py +485 -0
- {orbix-2.0.0 → orbix-3.0.0}/tests/test_viz_anim.py +12 -3
- {orbix-2.0.0 → orbix-3.0.0}/tests/test_viz_orbit.py +43 -1
- {orbix-2.0.0 → orbix-3.0.0}/tests/test_viz_package.py +1 -1
- {orbix-2.0.0 → orbix-3.0.0}/tests/test_viz_prepared.py +20 -17
- orbix-2.0.0/.github/dependabot.yml +0 -6
- orbix-2.0.0/.github/workflows/tests.yml +0 -32
- orbix-2.0.0/docs/index.md +0 -44
- orbix-2.0.0/pyproject.toml +0 -66
- orbix-2.0.0/tests/conftest.py +0 -5
- orbix-2.0.0/tests/test_fixed_e_solvers.py +0 -32
- orbix-2.0.0/tests/test_grid_solvers.py +0 -55
- orbix-2.0.0/tests/test_kepler_core.py +0 -103
- {orbix-2.0.0 → orbix-3.0.0}/.python-version +0 -0
- {orbix-2.0.0 → orbix-3.0.0}/.readthedocs.yaml +0 -0
- {orbix-2.0.0 → orbix-3.0.0}/.zenodo.json +0 -0
- {orbix-2.0.0 → orbix-3.0.0}/CITATION.cff +0 -0
- {orbix-2.0.0 → orbix-3.0.0}/LICENSE +0 -0
- {orbix-2.0.0 → orbix-3.0.0}/src/orbix/__init__.py +0 -0
- {orbix-2.0.0 → orbix-3.0.0}/src/orbix/equations/phase.py +0 -0
- {orbix-2.0.0 → orbix-3.0.0}/src/orbix/kepler/__init__.py +0 -0
- {orbix-2.0.0 → orbix-3.0.0}/src/orbix/kepler/markley.py +0 -0
- {orbix-2.0.0 → orbix-3.0.0}/src/orbix/kepler/shortcuts/__init__.py +0 -0
- {orbix-2.0.0 → orbix-3.0.0}/src/orbix/kepler/shortcuts/guess.py +0 -0
- {orbix-2.0.0 → orbix-3.0.0}/src/orbix/observatory/__init__.py +0 -0
- {orbix-2.0.0 → orbix-3.0.0}/src/orbix/observatory/data/L2_halo_orbit_six_month.npz +0 -0
- {orbix-2.0.0 → orbix-3.0.0}/src/orbix/observatory/keepout.py +0 -0
- {orbix-2.0.0 → orbix-3.0.0}/src/orbix/observatory/observatory.py +0 -0
- {orbix-2.0.0 → orbix-3.0.0}/src/orbix/observatory/solar_system.py +0 -0
- {orbix-2.0.0 → orbix-3.0.0}/src/orbix/py.typed +0 -0
- {orbix-2.0.0 → orbix-3.0.0}/src/orbix/viz/__init__.py +0 -0
- {orbix-2.0.0 → orbix-3.0.0}/src/orbix/viz/_require.py +0 -0
- {orbix-2.0.0 → orbix-3.0.0}/tests/test_internal_refs_guard.py +0 -0
- {orbix-2.0.0 → orbix-3.0.0}/tests/test_kepler_grads.py +0 -0
- {orbix-2.0.0 → orbix-3.0.0}/tests/test_observatory_wrapper.py +0 -0
- {orbix-2.0.0 → orbix-3.0.0}/tests/test_vs_exosims.py +0 -0
- {orbix-2.0.0 → orbix-3.0.0}/tools/check_internal_refs.py +0 -0
orbix-3.0.0/.codespellrc
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Drop-in for every owned library. One config, low noise: one grouped pull request per month,
|
|
2
|
+
# new releases wait a week (cooldown) so a yanked or compromised release is seen before it lands.
|
|
3
|
+
# Security updates ignore the cooldown and are configured separately in repository settings.
|
|
4
|
+
version: 2
|
|
5
|
+
updates:
|
|
6
|
+
- package-ecosystem: "github-actions"
|
|
7
|
+
directory: "/"
|
|
8
|
+
schedule:
|
|
9
|
+
interval: "monthly"
|
|
10
|
+
cooldown:
|
|
11
|
+
default-days: 7
|
|
12
|
+
groups:
|
|
13
|
+
actions:
|
|
14
|
+
patterns: ["*"]
|
|
15
|
+
commit-message:
|
|
16
|
+
prefix: "ci" # conventional commit type that release-please ignores
|
|
17
|
+
|
|
18
|
+
# Only for repos with a committed uv.lock or a pre-commit config worth bumping.
|
|
19
|
+
# The libraries pin no lockfile, so the uv ecosystem is deliberately absent here.
|
|
20
|
+
- package-ecosystem: "pre-commit"
|
|
21
|
+
directory: "/"
|
|
22
|
+
schedule:
|
|
23
|
+
interval: "monthly"
|
|
24
|
+
cooldown:
|
|
25
|
+
default-days: 7
|
|
26
|
+
groups:
|
|
27
|
+
hooks:
|
|
28
|
+
patterns: ["*"]
|
|
29
|
+
commit-message:
|
|
30
|
+
prefix: "ci"
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"""Write a job summary from a pytest junit file and enforce a suite time budget.
|
|
2
|
+
|
|
3
|
+
Usage: python ci_summary.py junit.xml [--title TITLE] [--budget-seconds N]
|
|
4
|
+
|
|
5
|
+
Appends markdown to $GITHUB_STEP_SUMMARY (stdout when unset). Exits non-zero when the
|
|
6
|
+
summed test time exceeds the budget, or when any test was skipped (a skip hides a
|
|
7
|
+
missing dependency).
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import argparse
|
|
11
|
+
import os
|
|
12
|
+
import sys
|
|
13
|
+
import xml.etree.ElementTree as ET
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def main():
|
|
17
|
+
"""Summarize collected tests and check the requested budget and skip policy."""
|
|
18
|
+
parser = argparse.ArgumentParser()
|
|
19
|
+
parser.add_argument("junit")
|
|
20
|
+
parser.add_argument("--title", default="Tests")
|
|
21
|
+
parser.add_argument("--budget-seconds", type=float, default=0.0)
|
|
22
|
+
parser.add_argument("--allow-skips", action="store_true")
|
|
23
|
+
args = parser.parse_args()
|
|
24
|
+
|
|
25
|
+
if not os.path.exists(args.junit):
|
|
26
|
+
print(f"{args.junit} not found: the test step did not run")
|
|
27
|
+
return 1
|
|
28
|
+
root = ET.parse(args.junit).getroot()
|
|
29
|
+
cases = []
|
|
30
|
+
skipped = []
|
|
31
|
+
for case in root.iter("testcase"):
|
|
32
|
+
name = f"{case.get('classname', '')}::{case.get('name', '')}"
|
|
33
|
+
seconds = float(case.get("time", 0.0))
|
|
34
|
+
cases.append((seconds, name))
|
|
35
|
+
# Pytest records expected failures as skipped; pytest enforces strict xfails.
|
|
36
|
+
skip = case.find("skipped")
|
|
37
|
+
if skip is not None and skip.get("type") != "pytest.xfail":
|
|
38
|
+
skipped.append(name)
|
|
39
|
+
total = sum(s for s, _ in cases)
|
|
40
|
+
cases.sort(reverse=True)
|
|
41
|
+
|
|
42
|
+
lines = [
|
|
43
|
+
f"### {args.title}",
|
|
44
|
+
"",
|
|
45
|
+
f"- tests: {len(cases)}, skipped: {len(skipped)}",
|
|
46
|
+
f"- summed test time: {total:.1f} s"
|
|
47
|
+
+ (f" (budget {args.budget_seconds:.0f} s)" if args.budget_seconds else ""),
|
|
48
|
+
"",
|
|
49
|
+
"| slowest tests | seconds |",
|
|
50
|
+
"|---|---|",
|
|
51
|
+
]
|
|
52
|
+
lines += [f"| `{name}` | {seconds:.2f} |" for seconds, name in cases[:10]]
|
|
53
|
+
if skipped:
|
|
54
|
+
policy = "allowed" if args.allow_skips else "treated as a failure"
|
|
55
|
+
lines += ["", f"Skipped ({policy}):"]
|
|
56
|
+
lines += [f"- `{name}`" for name in skipped[:20]]
|
|
57
|
+
|
|
58
|
+
text = "\n".join(lines) + "\n"
|
|
59
|
+
target = os.environ.get("GITHUB_STEP_SUMMARY")
|
|
60
|
+
if target:
|
|
61
|
+
with open(target, "a", encoding="utf-8") as handle:
|
|
62
|
+
handle.write(text)
|
|
63
|
+
else:
|
|
64
|
+
print(text)
|
|
65
|
+
|
|
66
|
+
failed = False
|
|
67
|
+
if args.budget_seconds and total > args.budget_seconds:
|
|
68
|
+
print(f"suite time {total:.1f} s exceeds budget {args.budget_seconds:.0f} s")
|
|
69
|
+
failed = True
|
|
70
|
+
if skipped and not args.allow_skips:
|
|
71
|
+
print(f"{len(skipped)} tests were skipped")
|
|
72
|
+
failed = True
|
|
73
|
+
return 1 if failed else 0
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
if __name__ == "__main__":
|
|
77
|
+
sys.exit(main())
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Unreleased sibling libraries, applied as uv overrides so each is installed at a pinned main
|
|
2
|
+
# commit whatever version bounds other packages declare (a breaking change waiting for its
|
|
3
|
+
# release tag reports the old major version). Move a pin deliberately; drop it once PyPI covers it.
|
|
4
|
+
hwoutils @ git+https://github.com/CoreySpohn/hwoutils@20f6973e39954321feba7efcf781fc217016a46f
|
|
5
|
+
eyepiece @ git+https://github.com/CoreySpohn/eyepiece@c7a4bea5a34b8751b4791bf74ea35bcd9da54cb1
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
# Replaces tests.yml. Quick tier on every push and pull request, docs with executed
|
|
4
|
+
# examples, and the slow tier on a nightly schedule. No secrets are used: the default
|
|
5
|
+
# GITHUB_TOKEN with read access is enough because every sibling library is public.
|
|
6
|
+
|
|
7
|
+
on:
|
|
8
|
+
push:
|
|
9
|
+
branches: [ main ]
|
|
10
|
+
pull_request:
|
|
11
|
+
branches: [ main ]
|
|
12
|
+
schedule:
|
|
13
|
+
- cron: "17 7 * * *" # nightly, 07:17 UTC (default branch only)
|
|
14
|
+
workflow_dispatch:
|
|
15
|
+
inputs:
|
|
16
|
+
tier:
|
|
17
|
+
description: "Test selection for a manual run"
|
|
18
|
+
default: "not slow"
|
|
19
|
+
type: choice
|
|
20
|
+
options: [ "not slow", "slow", "all" ]
|
|
21
|
+
|
|
22
|
+
permissions:
|
|
23
|
+
contents: read
|
|
24
|
+
|
|
25
|
+
concurrency:
|
|
26
|
+
group: ci-${{ github.workflow }}-${{ github.ref }}
|
|
27
|
+
cancel-in-progress: ${{ github.event_name != 'schedule' }}
|
|
28
|
+
|
|
29
|
+
env:
|
|
30
|
+
JAX_PLATFORMS: cpu
|
|
31
|
+
EYEPIECE_REQUIRE_MANIM: "1"
|
|
32
|
+
# Batched programs can stall on 2-vCPU runners with the default Eigen threading.
|
|
33
|
+
XLA_FLAGS: --xla_cpu_multi_thread_eigen=false intra_op_parallelism_threads=1
|
|
34
|
+
JAX_COMPILATION_CACHE_DIR: ${{ github.workspace }}/.jax_cache
|
|
35
|
+
JAX_PERSISTENT_CACHE_MIN_COMPILE_TIME_SECS: "1"
|
|
36
|
+
PYTHONHASHSEED: "0"
|
|
37
|
+
|
|
38
|
+
jobs:
|
|
39
|
+
quick:
|
|
40
|
+
name: Quick tier (py${{ matrix.python-version }})
|
|
41
|
+
if: github.event_name != 'schedule' && (github.event_name != 'workflow_dispatch' || inputs.tier != 'slow')
|
|
42
|
+
runs-on: ubuntu-latest
|
|
43
|
+
timeout-minutes: 20
|
|
44
|
+
strategy:
|
|
45
|
+
fail-fast: false
|
|
46
|
+
matrix:
|
|
47
|
+
python-version: ["3.12"]
|
|
48
|
+
steps:
|
|
49
|
+
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
|
50
|
+
with:
|
|
51
|
+
persist-credentials: false
|
|
52
|
+
|
|
53
|
+
- uses: astral-sh/setup-uv@eb1897b8dc4b5d5bfe39a428a8f2304605e0983c # v7.0.0
|
|
54
|
+
with:
|
|
55
|
+
python-version: ${{ matrix.python-version }}
|
|
56
|
+
enable-cache: true
|
|
57
|
+
cache-dependency-glob: "pyproject.toml"
|
|
58
|
+
|
|
59
|
+
- name: Restore the JAX compile cache
|
|
60
|
+
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
|
61
|
+
with:
|
|
62
|
+
path: .jax_cache
|
|
63
|
+
key: jax-${{ runner.os }}-py${{ matrix.python-version }}-${{ hashFiles('pyproject.toml') }}-${{ github.sha }}
|
|
64
|
+
restore-keys: |
|
|
65
|
+
jax-${{ runner.os }}-py${{ matrix.python-version }}-${{ hashFiles('pyproject.toml') }}-
|
|
66
|
+
jax-${{ runner.os }}-py${{ matrix.python-version }}-
|
|
67
|
+
|
|
68
|
+
# Manim's Python extensions need Cairo and Pango headers at install time.
|
|
69
|
+
- name: Install renderer build dependencies
|
|
70
|
+
run: |
|
|
71
|
+
sudo apt-get update
|
|
72
|
+
sudo apt-get install --no-install-recommends -y libcairo2-dev libpango1.0-dev pkg-config
|
|
73
|
+
|
|
74
|
+
- name: Install the package and test tools
|
|
75
|
+
run: |
|
|
76
|
+
uv venv .venv --python ${{ matrix.python-version }}
|
|
77
|
+
echo "VIRTUAL_ENV=$PWD/.venv" >> "$GITHUB_ENV"
|
|
78
|
+
echo "$PWD/.venv/bin" >> "$GITHUB_PATH"
|
|
79
|
+
# One resolve, so pinned siblings satisfy the package floors.
|
|
80
|
+
uv pip install --python .venv/bin/python -e ".[test]" --override .github/sibling-pins.txt ruff==0.15.18 deptry ty==0.0.96
|
|
81
|
+
|
|
82
|
+
- name: Lint and formatting
|
|
83
|
+
run: |
|
|
84
|
+
ruff check src/orbix tests
|
|
85
|
+
ruff format --check src/orbix tests
|
|
86
|
+
|
|
87
|
+
- name: Check dependencies
|
|
88
|
+
run: deptry src/orbix
|
|
89
|
+
|
|
90
|
+
- name: Check types (advisory)
|
|
91
|
+
continue-on-error: true
|
|
92
|
+
run: ty check src/orbix
|
|
93
|
+
|
|
94
|
+
- name: Quick tier
|
|
95
|
+
run: |
|
|
96
|
+
pytest tests/ -m "not slow" -ra --tb=short \
|
|
97
|
+
--timeout=300 --fail-slow=30s \
|
|
98
|
+
--durations=15 --durations-min=1.0 \
|
|
99
|
+
--junitxml=junit-quick.xml
|
|
100
|
+
|
|
101
|
+
- name: Job summary
|
|
102
|
+
if: always()
|
|
103
|
+
run: python .github/scripts/ci_summary.py junit-quick.xml --title "Quick tier" --budget-seconds 600
|
|
104
|
+
|
|
105
|
+
docs:
|
|
106
|
+
name: Docs with executed examples
|
|
107
|
+
if: github.event_name != 'schedule' && (github.event_name != 'workflow_dispatch' || inputs.tier != 'slow')
|
|
108
|
+
runs-on: ubuntu-latest
|
|
109
|
+
timeout-minutes: 20
|
|
110
|
+
steps:
|
|
111
|
+
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
|
112
|
+
with:
|
|
113
|
+
persist-credentials: false
|
|
114
|
+
fetch-depth: 0 # hatch-vcs needs tags for the docs version
|
|
115
|
+
|
|
116
|
+
- uses: astral-sh/setup-uv@eb1897b8dc4b5d5bfe39a428a8f2304605e0983c # v7.0.0
|
|
117
|
+
with:
|
|
118
|
+
python-version: "3.12"
|
|
119
|
+
enable-cache: true
|
|
120
|
+
cache-dependency-glob: "pyproject.toml"
|
|
121
|
+
|
|
122
|
+
- uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
|
123
|
+
with:
|
|
124
|
+
path: .jax_cache
|
|
125
|
+
key: jax-docs-${{ hashFiles('pyproject.toml') }}-${{ github.sha }}
|
|
126
|
+
restore-keys: jax-docs-${{ hashFiles('pyproject.toml') }}-
|
|
127
|
+
|
|
128
|
+
# Manim's Python extensions need Cairo and Pango headers at install time.
|
|
129
|
+
- name: Install renderer build dependencies
|
|
130
|
+
run: |
|
|
131
|
+
sudo apt-get update
|
|
132
|
+
sudo apt-get install --no-install-recommends -y libcairo2-dev libpango1.0-dev pkg-config
|
|
133
|
+
|
|
134
|
+
- name: Install docs dependencies
|
|
135
|
+
run: |
|
|
136
|
+
uv venv .venv --python 3.12
|
|
137
|
+
echo "$PWD/.venv/bin" >> "$GITHUB_PATH"
|
|
138
|
+
# One resolve, so pinned siblings satisfy the package floors.
|
|
139
|
+
uv pip install --python .venv/bin/python -e ".[docs,test]" --override .github/sibling-pins.txt
|
|
140
|
+
|
|
141
|
+
# Every Python fence in README.md and docs runs as a test. A block that cannot run on a
|
|
142
|
+
# runner carries the info string `python notest` and a one-line reason above it.
|
|
143
|
+
- name: Execute fenced code blocks
|
|
144
|
+
run: |
|
|
145
|
+
pytest README.md docs --markdown-docs --markdown-docs-syntax=superfences \
|
|
146
|
+
-p no:cacheprovider --timeout=120 -ra --tb=short \
|
|
147
|
+
--junitxml=junit-docs.xml
|
|
148
|
+
|
|
149
|
+
# Executes {code-cell} blocks and notebooks, and fails on any Sphinx warning.
|
|
150
|
+
- name: Build docs with execution forced
|
|
151
|
+
run: |
|
|
152
|
+
sphinx-build -W --keep-going -b html \
|
|
153
|
+
-D nb_execution_mode=force -D nb_execution_raise_on_error=1 \
|
|
154
|
+
docs docs/_build/html
|
|
155
|
+
|
|
156
|
+
- name: Job summary
|
|
157
|
+
if: always()
|
|
158
|
+
run: python .github/scripts/ci_summary.py junit-docs.xml --title "Docs examples" --budget-seconds 300 --allow-skips
|
|
159
|
+
|
|
160
|
+
slow:
|
|
161
|
+
name: Slow tier
|
|
162
|
+
if: github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && inputs.tier != 'not slow')
|
|
163
|
+
runs-on: ubuntu-latest
|
|
164
|
+
timeout-minutes: 90
|
|
165
|
+
steps:
|
|
166
|
+
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
|
167
|
+
with:
|
|
168
|
+
persist-credentials: false
|
|
169
|
+
|
|
170
|
+
- uses: astral-sh/setup-uv@eb1897b8dc4b5d5bfe39a428a8f2304605e0983c # v7.0.0
|
|
171
|
+
with:
|
|
172
|
+
python-version: "3.12"
|
|
173
|
+
enable-cache: true
|
|
174
|
+
cache-dependency-glob: "pyproject.toml"
|
|
175
|
+
|
|
176
|
+
- uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
|
177
|
+
with:
|
|
178
|
+
path: .jax_cache
|
|
179
|
+
key: jax-slow-${{ hashFiles('pyproject.toml') }}-${{ github.sha }}
|
|
180
|
+
restore-keys: jax-slow-${{ hashFiles('pyproject.toml') }}-
|
|
181
|
+
|
|
182
|
+
# Manim's Python extensions need Cairo and Pango headers at install time.
|
|
183
|
+
- name: Install renderer build dependencies
|
|
184
|
+
run: |
|
|
185
|
+
sudo apt-get update
|
|
186
|
+
sudo apt-get install --no-install-recommends -y libcairo2-dev libpango1.0-dev pkg-config
|
|
187
|
+
|
|
188
|
+
- name: Install the package and test tools
|
|
189
|
+
run: |
|
|
190
|
+
uv venv .venv --python 3.12
|
|
191
|
+
echo "$PWD/.venv/bin" >> "$GITHUB_PATH"
|
|
192
|
+
# One resolve, so pinned siblings satisfy the package floors.
|
|
193
|
+
uv pip install --python .venv/bin/python -e ".[test]" --override .github/sibling-pins.txt
|
|
194
|
+
|
|
195
|
+
- name: Slow tier (hypothesis nightly profile)
|
|
196
|
+
env:
|
|
197
|
+
HYPOTHESIS_PROFILE: nightly
|
|
198
|
+
run: |
|
|
199
|
+
status=0
|
|
200
|
+
pytest tests/ -m slow -ra --tb=short --timeout=900 \
|
|
201
|
+
--durations=25 --junitxml=junit-slow.xml || status=$?
|
|
202
|
+
if [ "$status" -ne 0 ] && [ "$status" -ne 5 ]; then
|
|
203
|
+
exit "$status"
|
|
204
|
+
fi
|
|
205
|
+
|
|
206
|
+
- name: Job summary
|
|
207
|
+
if: always()
|
|
208
|
+
run: python .github/scripts/ci_summary.py junit-slow.xml --title "Slow tier" --allow-skips
|
|
@@ -7,15 +7,22 @@ on:
|
|
|
7
7
|
branches: [ main ]
|
|
8
8
|
workflow_dispatch:
|
|
9
9
|
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
|
|
10
13
|
jobs:
|
|
11
14
|
docs:
|
|
12
15
|
name: Build docs
|
|
13
16
|
runs-on: ubuntu-latest
|
|
17
|
+
timeout-minutes: 20
|
|
14
18
|
steps:
|
|
15
|
-
- uses: actions/checkout@
|
|
19
|
+
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
|
20
|
+
with:
|
|
21
|
+
persist-credentials: false
|
|
22
|
+
fetch-depth: 0
|
|
16
23
|
|
|
17
24
|
- name: Install uv
|
|
18
|
-
uses: astral-sh/setup-uv@v7
|
|
25
|
+
uses: astral-sh/setup-uv@eb1897b8dc4b5d5bfe39a428a8f2304605e0983c # v7.0.0
|
|
19
26
|
with:
|
|
20
27
|
enable-cache: true
|
|
21
28
|
|
|
@@ -23,7 +30,7 @@ jobs:
|
|
|
23
30
|
run: uv venv .venv --python 3.12
|
|
24
31
|
|
|
25
32
|
- name: Install package with docs dependencies
|
|
26
|
-
run: uv pip install -e ".[docs]"
|
|
33
|
+
run: uv pip install --python .venv/bin/python -e ".[docs]" --override .github/sibling-pins.txt
|
|
27
34
|
env:
|
|
28
35
|
VIRTUAL_ENV: ${{ github.workspace }}/.venv
|
|
29
36
|
|
|
@@ -31,4 +38,4 @@ jobs:
|
|
|
31
38
|
# nb_execution_raise_on_error, so a cell that stops working fails here
|
|
32
39
|
# rather than on the documentation host.
|
|
33
40
|
- name: Build the documentation
|
|
34
|
-
run: .venv/bin/sphinx-build -b html docs docs/_build/html
|
|
41
|
+
run: .venv/bin/sphinx-build -W --keep-going -b html -D nb_execution_mode=force -D nb_execution_raise_on_error=1 docs docs/_build/html
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
name: hygiene
|
|
2
|
+
|
|
3
|
+
# Checks that do not depend on JAX: workflow security, spelling, and hooks.
|
|
4
|
+
on:
|
|
5
|
+
push:
|
|
6
|
+
branches: [main]
|
|
7
|
+
pull_request:
|
|
8
|
+
branches: [main]
|
|
9
|
+
schedule:
|
|
10
|
+
- cron: "41 6 * * 1" # weekly, so the repo has activity and new lint rules are noticed
|
|
11
|
+
workflow_dispatch:
|
|
12
|
+
|
|
13
|
+
permissions:
|
|
14
|
+
contents: read
|
|
15
|
+
|
|
16
|
+
concurrency:
|
|
17
|
+
group: hygiene-${{ github.ref }}
|
|
18
|
+
cancel-in-progress: true
|
|
19
|
+
|
|
20
|
+
jobs:
|
|
21
|
+
hygiene:
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
timeout-minutes: 10
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
|
26
|
+
with:
|
|
27
|
+
persist-credentials: false
|
|
28
|
+
|
|
29
|
+
- uses: astral-sh/setup-uv@eb1897b8dc4b5d5bfe39a428a8f2304605e0983c # v7.0.0
|
|
30
|
+
|
|
31
|
+
- name: Lint workflows (zizmor)
|
|
32
|
+
run: uvx zizmor --format=github --min-severity=medium .github
|
|
33
|
+
|
|
34
|
+
- name: Spelling (codespell)
|
|
35
|
+
run: uvx codespell --check-hidden
|
|
36
|
+
|
|
37
|
+
- name: Pre-commit hooks
|
|
38
|
+
run: uvx pre-commit run --all-files --show-diff-on-failure
|
|
39
|
+
env:
|
|
40
|
+
SKIP: conventional-pre-commit # only runs with a commit message
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
name: Publish to PyPI
|
|
2
2
|
|
|
3
|
-
on:
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ["v*"]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
4
9
|
|
|
5
10
|
jobs:
|
|
6
11
|
build:
|
|
@@ -8,9 +13,11 @@ jobs:
|
|
|
8
13
|
runs-on: ubuntu-latest
|
|
9
14
|
|
|
10
15
|
steps:
|
|
11
|
-
- uses: actions/checkout@
|
|
16
|
+
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
|
17
|
+
with:
|
|
18
|
+
persist-credentials: false
|
|
12
19
|
- name: Set up Python
|
|
13
|
-
uses: actions/setup-python@
|
|
20
|
+
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
|
|
14
21
|
with:
|
|
15
22
|
python-version: "3.x"
|
|
16
23
|
- name: Install pypa/build
|
|
@@ -22,7 +29,7 @@ jobs:
|
|
|
22
29
|
- name: Build a binary wheel and a source tarball
|
|
23
30
|
run: python3 -m build
|
|
24
31
|
- name: Store the distribution packages
|
|
25
|
-
uses: actions/upload-artifact@v7
|
|
32
|
+
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
|
26
33
|
with:
|
|
27
34
|
name: python-package-distributions
|
|
28
35
|
path: dist/
|
|
@@ -30,7 +37,7 @@ jobs:
|
|
|
30
37
|
publish-to-pypi:
|
|
31
38
|
name: >-
|
|
32
39
|
Publish Python distribution to PyPI
|
|
33
|
-
if: startsWith(github.ref, 'refs/tags/')
|
|
40
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
34
41
|
needs:
|
|
35
42
|
- build
|
|
36
43
|
runs-on: ubuntu-latest
|
|
@@ -42,9 +49,9 @@ jobs:
|
|
|
42
49
|
|
|
43
50
|
steps:
|
|
44
51
|
- name: Download all the dists
|
|
45
|
-
uses: actions/download-artifact@v8
|
|
52
|
+
uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0
|
|
46
53
|
with:
|
|
47
54
|
name: python-package-distributions
|
|
48
55
|
path: dist/
|
|
49
56
|
- name: Publish distribution to PyPI
|
|
50
|
-
uses: pypa/gh-action-pypi-publish@
|
|
57
|
+
uses: pypa/gh-action-pypi-publish@7245906fb61fa33a13554f9d5fb856fe61758086 # v1.14.3
|
|
@@ -4,16 +4,18 @@ on:
|
|
|
4
4
|
- main
|
|
5
5
|
|
|
6
6
|
permissions:
|
|
7
|
-
contents:
|
|
8
|
-
pull-requests: write
|
|
7
|
+
contents: read
|
|
9
8
|
|
|
10
9
|
name: release-please
|
|
11
10
|
|
|
12
11
|
jobs:
|
|
13
12
|
release-please:
|
|
14
13
|
runs-on: ubuntu-latest
|
|
14
|
+
permissions:
|
|
15
|
+
contents: write
|
|
16
|
+
pull-requests: write
|
|
15
17
|
steps:
|
|
16
|
-
- uses: googleapis/release-please-action@
|
|
18
|
+
- uses: googleapis/release-please-action@16a9c90856f42705d54a6fda1823352bdc62cf38 # v4.4.0
|
|
17
19
|
with:
|
|
18
20
|
# this assumes that you have created a personal access token
|
|
19
21
|
# (PAT) and configured it as a GitHub action secret named
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
name: Upstream canary
|
|
2
|
+
|
|
3
|
+
# Exercise upstream releases before a relock, and the declared dependency floors.
|
|
4
|
+
on:
|
|
5
|
+
schedule:
|
|
6
|
+
- cron: "23 5 * * 1,4" # Monday and Thursday, 05:23 UTC
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
concurrency:
|
|
13
|
+
group: ci-${{ github.workflow }}-${{ github.ref }}
|
|
14
|
+
cancel-in-progress: ${{ github.event_name != 'schedule' }}
|
|
15
|
+
|
|
16
|
+
env:
|
|
17
|
+
JAX_PLATFORMS: cpu
|
|
18
|
+
EYEPIECE_REQUIRE_MANIM: "1"
|
|
19
|
+
# Batched programs can stall on 2-vCPU runners with the default Eigen threading.
|
|
20
|
+
XLA_FLAGS: --xla_cpu_multi_thread_eigen=false intra_op_parallelism_threads=1
|
|
21
|
+
JAX_COMPILATION_CACHE_DIR: ${{ github.workspace }}/.jax_cache
|
|
22
|
+
JAX_PERSISTENT_CACHE_MIN_COMPILE_TIME_SECS: "1"
|
|
23
|
+
PYTHONHASHSEED: "0"
|
|
24
|
+
|
|
25
|
+
jobs:
|
|
26
|
+
upstream-dev:
|
|
27
|
+
name: Upstream pre-releases (py3.12)
|
|
28
|
+
runs-on: ubuntu-latest
|
|
29
|
+
timeout-minutes: 30
|
|
30
|
+
steps:
|
|
31
|
+
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
|
32
|
+
with:
|
|
33
|
+
persist-credentials: false
|
|
34
|
+
|
|
35
|
+
- uses: astral-sh/setup-uv@eb1897b8dc4b5d5bfe39a428a8f2304605e0983c # v7.0.0
|
|
36
|
+
with:
|
|
37
|
+
python-version: "3.12"
|
|
38
|
+
enable-cache: true
|
|
39
|
+
cache-dependency-glob: "pyproject.toml"
|
|
40
|
+
|
|
41
|
+
# Manim's Python extensions need Cairo and Pango headers at install time.
|
|
42
|
+
- name: Install renderer build dependencies
|
|
43
|
+
run: |
|
|
44
|
+
sudo apt-get update
|
|
45
|
+
sudo apt-get install --no-install-recommends -y libcairo2-dev libpango1.0-dev pkg-config
|
|
46
|
+
|
|
47
|
+
- name: Install the package and upstream pre-releases
|
|
48
|
+
run: |
|
|
49
|
+
uv venv .venv --python 3.12
|
|
50
|
+
echo "VIRTUAL_ENV=$PWD/.venv" >> "$GITHUB_ENV"
|
|
51
|
+
echo "$PWD/.venv/bin" >> "$GITHUB_PATH"
|
|
52
|
+
uv pip install --python .venv/bin/python -e ".[test]" --override .github/sibling-pins.txt
|
|
53
|
+
uv pip install --python .venv/bin/python --upgrade --prerelease=allow \
|
|
54
|
+
jax jaxlib numpy scipy astropy --override .github/sibling-pins.txt
|
|
55
|
+
# Nightly-only index verified against the JAX installation docs:
|
|
56
|
+
# https://docs.jax.dev/en/latest/installation.html#jax-nightly-installation
|
|
57
|
+
uv pip install --python .venv/bin/python --upgrade --prerelease=allow \
|
|
58
|
+
--index https://us-python.pkg.dev/ml-oss-artifacts-published/jax-public-nightly-artifacts-registry/simple/ \
|
|
59
|
+
jax jaxlib --override .github/sibling-pins.txt
|
|
60
|
+
uv pip freeze --python .venv/bin/python
|
|
61
|
+
|
|
62
|
+
- name: Quick tier with warnings as errors
|
|
63
|
+
run: |
|
|
64
|
+
for test_file in tests/test_*.py; do
|
|
65
|
+
pytest "$test_file" -m "not slow" -q -p no:cacheprovider --timeout=300
|
|
66
|
+
done
|
|
67
|
+
|
|
68
|
+
lowest-direct:
|
|
69
|
+
name: Lowest direct dependencies (py3.12)
|
|
70
|
+
runs-on: ubuntu-latest
|
|
71
|
+
timeout-minutes: 30
|
|
72
|
+
steps:
|
|
73
|
+
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
|
74
|
+
with:
|
|
75
|
+
persist-credentials: false
|
|
76
|
+
|
|
77
|
+
- uses: astral-sh/setup-uv@eb1897b8dc4b5d5bfe39a428a8f2304605e0983c # v7.0.0
|
|
78
|
+
with:
|
|
79
|
+
python-version: "3.12"
|
|
80
|
+
enable-cache: true
|
|
81
|
+
cache-dependency-glob: "pyproject.toml"
|
|
82
|
+
|
|
83
|
+
# Manim's Python extensions need Cairo and Pango headers at install time.
|
|
84
|
+
- name: Install renderer build dependencies
|
|
85
|
+
run: |
|
|
86
|
+
sudo apt-get update
|
|
87
|
+
sudo apt-get install --no-install-recommends -y libcairo2-dev libpango1.0-dev pkg-config
|
|
88
|
+
|
|
89
|
+
- name: Install the lowest direct dependencies
|
|
90
|
+
run: |
|
|
91
|
+
uv venv .venv --python 3.12
|
|
92
|
+
echo "VIRTUAL_ENV=$PWD/.venv" >> "$GITHUB_ENV"
|
|
93
|
+
echo "$PWD/.venv/bin" >> "$GITHUB_PATH"
|
|
94
|
+
uv pip install --python .venv/bin/python --resolution lowest-direct -e ".[docs,test]" --override .github/sibling-pins.txt
|
|
95
|
+
uv pip freeze --python .venv/bin/python
|
|
96
|
+
|
|
97
|
+
- name: Quick tier
|
|
98
|
+
run: |
|
|
99
|
+
for test_file in tests/test_*.py; do
|
|
100
|
+
pytest "$test_file" -m "not slow" -q -p no:cacheprovider --timeout=300
|
|
101
|
+
done
|
|
102
|
+
|
|
103
|
+
report:
|
|
104
|
+
name: Update the tracking issue
|
|
105
|
+
needs: [upstream-dev, lowest-direct]
|
|
106
|
+
if: always()
|
|
107
|
+
runs-on: ubuntu-latest
|
|
108
|
+
timeout-minutes: 5
|
|
109
|
+
# Manual runs on other branches share the same tracking issue.
|
|
110
|
+
concurrency:
|
|
111
|
+
group: upstream-canary-report
|
|
112
|
+
cancel-in-progress: false
|
|
113
|
+
permissions:
|
|
114
|
+
issues: write # This job alone maintains the canary tracking issue.
|
|
115
|
+
steps:
|
|
116
|
+
- name: Open, update or close the tracking issue
|
|
117
|
+
env:
|
|
118
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
119
|
+
GH_REPO: ${{ github.repository }}
|
|
120
|
+
UPSTREAM_RESULT: ${{ needs.upstream-dev.result }}
|
|
121
|
+
LOWEST_RESULT: ${{ needs.lowest-direct.result }}
|
|
122
|
+
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
|
123
|
+
run: |
|
|
124
|
+
title="Upstream canary failing"
|
|
125
|
+
# Match the exact title and reuse closed issues on a later regression.
|
|
126
|
+
issue=$(gh issue list --state all --search "\"$title\" in:title" --limit 100 \
|
|
127
|
+
--json number,title,state --jq 'map(select(.title == "Upstream canary failing")) | first // empty')
|
|
128
|
+
number=$(jq -r '.number // empty' <<< "$issue")
|
|
129
|
+
state=$(jq -r '.state // empty' <<< "$issue")
|
|
130
|
+
body=$(printf 'Upstream pre-releases: %s\nLowest direct dependencies: %s\n\nLatest run: %s\n' \
|
|
131
|
+
"$UPSTREAM_RESULT" "$LOWEST_RESULT" "$RUN_URL")
|
|
132
|
+
if [ "$UPSTREAM_RESULT" = "failure" ] || [ "$LOWEST_RESULT" = "failure" ]; then
|
|
133
|
+
if [ -n "$number" ]; then
|
|
134
|
+
gh issue edit "$number" --body "$body"
|
|
135
|
+
if [ "$state" = "CLOSED" ]; then
|
|
136
|
+
gh issue reopen "$number"
|
|
137
|
+
fi
|
|
138
|
+
else
|
|
139
|
+
gh issue create --title "$title" --body "$body"
|
|
140
|
+
fi
|
|
141
|
+
elif [ "$UPSTREAM_RESULT" = "success" ] && [ "$LOWEST_RESULT" = "success" ]; then
|
|
142
|
+
if [ -n "$number" ] && [ "$state" = "OPEN" ]; then
|
|
143
|
+
gh issue edit "$number" --body "$body"
|
|
144
|
+
gh issue close "$number" --comment "Both canary jobs are passing: $RUN_URL"
|
|
145
|
+
fi
|
|
146
|
+
fi
|