Make Results.converged tolerate an unparseable solver log #172
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| concurrency: | |
| group: ci-${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} | |
| jobs: | |
| test: | |
| name: test (${{ matrix.os }}, py${{ matrix.python-version }}, ${{ matrix.gmat-version }}) | |
| runs-on: ${{ matrix.os }} | |
| timeout-minutes: 30 | |
| strategy: | |
| fail-fast: false | |
| # Full cross-product: 3 OSes × 3 Python minors × 2 GMAT releases = 18 cells. | |
| # R2026a is the primary target; R2025a is the previous release we still | |
| # support. R2022a–R2024a stay out of CI: R2022a's gmatpy ABI floor is | |
| # Python 3.9, below this project's `python>=3.10` pin (see | |
| # docs/known-limitations.md). | |
| matrix: | |
| os: [ubuntu-latest, windows-latest, macos-latest] | |
| python-version: ['3.10', '3.11', '3.12'] | |
| gmat-version: [R2025a, R2026a] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v4 | |
| with: | |
| enable-cache: true | |
| cache-dependency-glob: uv.lock | |
| - uses: astro-tools/setup-gmat@v0 | |
| with: | |
| version: ${{ matrix.gmat-version }} | |
| cache: true | |
| - name: Install project | |
| run: uv sync --all-groups | |
| - name: Run pytest | |
| # `-m "integration or not integration"` overrides the default | |
| # marker filter in pyproject.toml so CI runs both unit and | |
| # integration suites in a single invocation. | |
| run: uv run pytest -m "integration or not integration" --cov --cov-report=term-missing | |
| # Threshold gates run on a single matrix combination — the .coverage | |
| # data is identical across runners, so there's no point re-asserting | |
| # it on every cell. Per-package gate (parsers/) matches the v0.1 | |
| # charter DoD; overall gate is the project-wide floor. | |
| - name: Enforce overall coverage (>=90%) | |
| if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12' && matrix.gmat-version == 'R2026a' | |
| run: uv run coverage report --fail-under=90 | |
| - name: Enforce parsers coverage (>=95%) | |
| if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12' && matrix.gmat-version == 'R2026a' | |
| run: uv run coverage report --include='src/gmat_run/parsers/*' --fail-under=95 | |
| # Smoke-execute the example notebook end-to-end. This catches the | |
| # "someone changed Mission/Results and forgot to refresh the committed | |
| # notebook" regression. One matrix combo is enough — the underlying | |
| # script path is covered cross-platform by test_round_trip. | |
| - name: Smoke-execute example notebooks | |
| if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12' && matrix.gmat-version == 'R2026a' | |
| run: | | |
| uv sync --all-groups --extra examples | |
| uv run jupyter execute docs/examples/01_load_run_plot.ipynb | |
| uv run jupyter execute docs/examples/02_parameter_sweep.ipynb | |
| uv run jupyter execute docs/examples/03_ground_track.ipynb | |
| uv run jupyter execute docs/examples/04_export_oem.ipynb | |
| uv run jupyter execute docs/examples/05_time_scales.ipynb | |
| uv run jupyter execute docs/examples/06_solver_iterations.ipynb | |
| lint: | |
| name: lint | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - uses: astral-sh/setup-uv@v4 | |
| with: | |
| enable-cache: true | |
| cache-dependency-glob: uv.lock | |
| - run: uv sync --all-groups | |
| - run: uv run ruff check | |
| - run: uv run ruff format --check | |
| typecheck: | |
| name: typecheck | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - uses: astral-sh/setup-uv@v4 | |
| with: | |
| enable-cache: true | |
| cache-dependency-glob: uv.lock | |
| - run: uv sync --all-groups | |
| - run: uv run mypy | |
| # Smoke-check that `pip install gmat-run` (no extras, no dev group) imports | |
| # cleanly. Catches an extras-only dependency leaking into the default install | |
| # path. The full test job above already exercises every extra via the dev | |
| # group; this is a small canary, not a matrix concern. | |
| minimal-install: | |
| name: minimal install smoke | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - run: pip install . | |
| - run: python -c "import gmat_run" | |
| # Drift canary for the canonical GMAT image published by setup-gmat. The | |
| # main `test` job runs in action-mode (`setup-gmat@v0`) on bare runners; a | |
| # downstream user running container-mode CI inside `ghcr.io/astro-tools/gmat` | |
| # would never benefit from that signal if the image and the action drifted | |
| # apart. This single cell exercises the load → run → DataFrame round-trip | |
| # inside the image, so a future image rebuild that strips a plugin, mangles | |
| # `gmat_startup_file.txt`, drops a Python ABI from the bundled gmatpy set, | |
| # or silently retags `:R2026a` breaks here before downstream users hit it. | |
| # Tag pinned to R2026a (the test job's primary GMAT version); a R2025a cell | |
| # is a follow-up after the multi-version image axis lands. | |
| canonical-image-smoke: | |
| name: canonical image smoke | |
| runs-on: ubuntu-latest | |
| container: ghcr.io/astro-tools/gmat:R2026a | |
| timeout-minutes: 5 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - run: pip install . | |
| - run: python tests/canonical_image_smoke.py | |
| # Validate CITATION.cff against the Citation File Format v1.2.0 schema. | |
| # cffconvert is installed standalone (not via uv sync) because it is a | |
| # CI-only schema check, not part of the dev or runtime dependency graph. | |
| citation: | |
| name: citation file (cffconvert) | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - run: pip install cffconvert==2.0.0 | |
| - run: cffconvert --validate -i CITATION.cff |