Skip to content

Publish the VS Code extension as astro-tools.gmat-mission-script #70

Publish the VS Code extension as astro-tools.gmat-mission-script

Publish the VS Code extension as astro-tools.gmat-mission-script #70

Workflow file for this run

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 }})
runs-on: ${{ matrix.os }}
timeout-minutes: 20
strategy:
fail-fast: false
# 3 OSes × 3 Python minors. The build hook compiles the vendored grammar natively on each
# cell, so this also proves the C extension builds and loads on Linux, Windows, and macOS.
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ['3.10', '3.11', '3.12']
steps:
- uses: actions/checkout@v6
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
cache-dependency-glob: uv.lock
- name: Install project
run: uv sync --all-groups --all-extras
- name: Run pytest
run: uv run pytest -m "not corpus" --cov --cov-report=term-missing
lint:
name: lint
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: '3.12'
- uses: astral-sh/setup-uv@v7
with:
enable-cache: true
cache-dependency-glob: uv.lock
- run: uv sync --all-groups --all-extras
- 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@v6
- uses: actions/setup-python@v6
with:
python-version: '3.12'
- uses: astral-sh/setup-uv@v7
with:
enable-cache: true
cache-dependency-glob: uv.lock
- run: uv sync --all-groups --all-extras
- run: uv run mypy
# Smoke-check that `pip install .` builds the wheel (committed parser.c + a C compiler — no Node),
# installs only the runtime dependency, and that the vendored grammar loads with no dev tooling.
minimal-install:
name: minimal install smoke
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: '3.12'
- run: pip install .
- name: import + load grammar + queries on a clean install
run: |
python - <<'PY'
from importlib import resources
import gmat_script
from gmat_script._grammar import language
from tree_sitter import Language, Parser, Query
grammar = Language(language())
tree = Parser(grammar).parse(b"Create Spacecraft Sat;")
assert tree.root_node.type == "source_file" and not tree.root_node.has_error
# The vendored queries must travel in the wheel (the language server loads them) and stay
# compatible with the grammar — compiling them here is an install-time drift guard.
queries = resources.files("gmat_script._grammar") / "queries"
for name in ("locals.scm", "tags.scm", "highlights.scm"):
Query(grammar, (queries / name).read_text(encoding="utf-8"))
print("minimal install OK", gmat_script.__version__)
PY
# Regenerate the parser with the pinned tree-sitter CLI and fail if the committed src/ is stale
# (the ABI / drift detector), then run the grammar's corpus tests. This is the only Node job.
grammar-build:
name: grammar build + tree-sitter test
runs-on: ubuntu-latest
timeout-minutes: 10
defaults:
run:
working-directory: tree-sitter-gmat
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: '22'
- run: npm ci
- name: Regenerate parser and check it matches the committed source
run: |
npx tree-sitter generate
git diff --exit-code -- src/
- name: Run grammar corpus tests
run: npx tree-sitter test
# Corpus parse-coverage: the full stock GMAT R2026a sample corpus (162 .script + 9 .gmf) parses
# with zero ERROR/MISSING nodes and re-emits byte-for-byte, on every OS/Python cell — the Windows
# cells exercise the CRLF byte-exact path the -text gitattributes protect. check_corpus.py logs the
# file/error counts and fails on an incomplete corpus, so silent truncation is impossible; the
# `-m corpus` pytest run adds per-file attribution.
corpus-coverage:
name: corpus parse-coverage (${{ matrix.os }}, py${{ matrix.python-version }})
runs-on: ${{ matrix.os }}
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ['3.10', '3.11', '3.12']
steps:
- uses: actions/checkout@v6
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
cache-dependency-glob: uv.lock
- run: uv sync --all-groups --all-extras
- name: Validate corpus and log file/error counts
run: uv run python tests/check_corpus.py
- name: Per-file corpus tests
run: uv run pytest -m corpus -v
# Validate CITATION.cff against the Citation File Format v1.2.0 schema.
citation:
name: citation file (cffconvert)
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: '3.12'
- run: pip install cffconvert==2.0.0
- run: cffconvert --validate -i CITATION.cff
# Build and smoke-test the VS Code extension (editors/vscode/): lint, type-check, bundle, run the
# activation test in a headless VS Code (xvfb), and package the .vsix so a broken manifest fails
# here, not at release. Node-only, mirroring the grammar-build job's toolchain.
vscode:
name: vscode extension
runs-on: ubuntu-latest
timeout-minutes: 20
defaults:
run:
working-directory: editors/vscode
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: '22'
cache: npm
cache-dependency-path: editors/vscode/package-lock.json
- run: npm ci
- name: Lint, type-check, and run the activation smoke test (headless)
run: xvfb-run -a npm test
- name: Package the .vsix
run: npx @vscode/vsce package --out gmat-script.vsix
- uses: actions/upload-artifact@v7
with:
name: vscode-extension-vsix
path: editors/vscode/gmat-script.vsix
if-no-files-found: error