Skip to content

Executable calculations, standard SysML v2 notation, variation/redefinition semantics, connectors, and typed Python bindings #5

Executable calculations, standard SysML v2 notation, variation/redefinition semantics, connectors, and typed Python bindings

Executable calculations, standard SysML v2 notation, variation/redefinition semantics, connectors, and typed Python bindings #5

Workflow file for this run

name: PR
# Pull requests only: pushes and tags are covered by the CircleCI config, and
# this workflow deliberately mirrors only its build-test workflow, not release.
on:
pull_request:
permissions:
contents: read
env:
# The OMG training corpus is not vendored. Requiring it here turns "corpus
# absent" into a test failure instead of a skip, so the gate cannot pass green
# without actually running (see internal/core/model/training_examples_test.go).
SYSTEMICA_REQUIRE_TRAINING_CORPUS: "1"
jobs:
build-and-test:
name: Build and test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
cache: true
- name: Download modules
run: go mod download
# Keyed on the download script, so a change to the pinned pilot tag or the
# layout invalidates the cache. A restored cache is still verified below.
- name: Cache the OMG training corpus
uses: actions/cache@v4
with:
path: examples/sysml-v2-training
key: training-corpus-${{ hashFiles('scripts/download-training-examples.sh') }}
- name: Download the OMG training corpus
run: ./scripts/download-training-examples.sh
- name: Verify the corpus is present
run: |
count=$(find examples/sysml-v2-training -name '*.sysml' | wc -l)
echo "training corpus: $count .sysml files"
if [ "$count" -eq 0 ]; then
echo "error: the training corpus is empty; the corpus gate would not run" >&2
exit 1
fi
- name: Check gofmt
run: |
unformatted=$(gofmt -l .)
if [ -n "$unformatted" ]; then
echo "The following files are not gofmt'd:"
echo "$unformatted"
exit 1
fi
- name: Run go vet
run: go vet ./...
- name: Run static analysis (staticcheck + gosec)
run: make lint
- name: Run tests
run: go test -v -race -coverprofile=coverage.txt -covermode=atomic ./...
# Re-run the corpus gate on its own so its verdict is legible in the log
# and a skip is impossible to miss.
- name: Corpus gate
run: |
set -o pipefail
go test -count=1 -v ./internal/core/model -run 'TestTrainingExamples' | tee corpus-gate.log
grep -E 'training files clean' corpus-gate.log
if grep -qE '^\s*--- SKIP' corpus-gate.log; then
echo "error: the corpus gate skipped" >&2
exit 1
fi
- name: Build binaries
run: |
make build \
VERSION="pr-${{ github.event.pull_request.number }}" \
COMMIT="$(git rev-parse --short HEAD)" \
BUILD_TIME="$(date -u '+%Y-%m-%d_%H:%M:%S')" \
GO_VERSION="$(go version | awk '{print $3}')"
- name: Verify binaries
run: |
./bin/sysml --version
./bin/sysml-lsp --version
ls -lh bin/
- uses: actions/upload-artifact@v4
with:
name: binaries
path: bin/
- uses: actions/upload-artifact@v4
with:
name: coverage
path: coverage.txt
python-test:
name: Python client tests
needs: build-and-test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
name: binaries
path: bin
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install sysml-grpc binary
run: |
mkdir -p ~/.pysysml/bin
cp bin/sysml-grpc ~/.pysysml/bin/
chmod +x ~/.pysysml/bin/sysml-grpc
- name: Install Python package
working-directory: python
run: |
pip install -e .
pip install pytest pytest-mock
- name: Run Python tests
working-directory: python
run: pytest tests/ -v
- name: Verify import
run: python3 -c "import pysysml; print(f'pysysml {pysysml.__version__} imported successfully')"