Skip to content
97 changes: 97 additions & 0 deletions .github/workflows/_pytest.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
---
# Reusable test runner. To be called from other workflows.
name: pytest

on:
workflow_call:
inputs:
test-files:
description: "Space-separated pytest paths or options/arguments (empty = whole suite)"
type: string
default: ""
python-versions:
description: "JSON array of Python versions for the matrix"
type: string
default: '["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]'
install-native-toolchains:
description: "Install compilers/tools to build & run generated bindings"
type: boolean
default: true
install-go:
description: >-
Install Go via brew on macOS. Default false since Go is
preinstalled on Linux runners and only the golang job needs it.
type: boolean
default: false
install-rust-clippy:
description: "Install the clippy component (needed by tests/test_rust.py's static analysis test)"
type: boolean
default: false
install-go-staticcheck:
description: "Install staticcheck (needed by tests/test_golang.py's static analysis test)"
type: boolean
default: false

jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
python-version: ${{ fromJSON(inputs.python-versions) }}
include:
- os: macos-latest
python-version: "3.10"
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: ${{ matrix.python-version }}
# jsonld-cli is used by the tests (incl. core), so always install it.
- name: Setup Node
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 24
- name: Install Python build tooling
run: |
python -m pip install --upgrade pip
pip install build
- name: Install jsonld-cli
run: |
npm install -g jsonld-cli
- name: Install Node test/build scripts
run: |
npm --prefix scripts ci
- name: Install Linux packages
if: ${{ inputs.install-native-toolchains && runner.os == 'Linux' }}
run: |
sudo apt update
sudo apt install -y build-essential cppcheck doxygen graphviz
- name: Install macOS packages
if: ${{ inputs.install-native-toolchains && runner.os == 'macOS' }}
run: |
brew update
brew install cppcheck doxygen gcc graphviz
- name: Install Go (macOS)
if: ${{ inputs.install-go && runner.os == 'macOS' }}
run: |
brew install go
- name: Install Rust static analysis tools
if: ${{ inputs.install-rust-clippy }}
run: |
rustup component add clippy
- name: Install Go static analysis tools
if: ${{ inputs.install-go-staticcheck }}
run: |
echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH"
go install honnef.co/go/tools/cmd/staticcheck@latest
- name: Build package
run: |
python -m build
- name: Install package
run: |
pip install -e .[dev]
- name: Run tests
run: |
pytest -v ${{ inputs.test-files }}
18 changes: 13 additions & 5 deletions .github/workflows/coverage-generate.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,18 @@ name: Generate coverage

on:
pull_request:
# Skip docs and edits to other workflows; later patterns override earlier.
paths: &trigger-paths
- "**"
- "!**/*.md"
- "!LICENSE"
- "!.github/ISSUE_TEMPLATE/**"
- "!.github/workflows/**"
- ".github/workflows/coverage-generate.yaml"
push:
branches:
- "main"
paths: *trigger-paths

permissions:
contents: read
Expand All @@ -23,9 +32,9 @@ jobs:
# comments (to avoid publishing multiple comments in the same PR)
contents: write
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # v4.7.1
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.11"
- name: Setup Node
Expand All @@ -52,15 +61,14 @@ jobs:
pytest -v
- name: Coverage comment
id: coverage_comment
uses: py-cov-action/python-coverage-comment-action@2b84cfb222691291ba358a586c13606f0a9c172c # v3
uses: py-cov-action/python-coverage-comment-action@5d8df5979747514c914e1c5a12335a7cf9a2745f # v4.1
with:
GITHUB_TOKEN: ${{ github.token }}
- name: Store Pull Request comment to be posted
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: steps.coverage_comment.outputs.COMMENT_FILE_WRITTEN == 'true'
with:
# If you use a different name, update COMMENT_ARTIFACT_NAME accordingly
name: python-coverage-comment-action
# If you use a different name, update COMMENT_FILENAME accordingly
path: python-coverage-comment-action.txt

163 changes: 114 additions & 49 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,68 +10,133 @@ on:
- "!.github/ISSUE_TEMPLATE/**"
- "!.github/workflows/**"
- ".github/workflows/test.yaml"
- ".github/workflows/_pytest.yaml"
pull_request:
paths: *trigger-paths
workflow_call:

jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
include:
- os: macos-latest
python-version: "3.10"
# Check which language bindings are affected by the change
changes:
runs-on: ubuntu-latest
outputs:
cpp: ${{ steps.filter.outputs.cpp }}
golang: ${{ steps.filter.outputs.golang }}
jsonschema: ${{ steps.filter.outputs.jsonschema }}
python: ${{ steps.filter.outputs.python }}
rust: ${{ steps.filter.outputs.rust }}
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: ${{ matrix.python-version }}
- name: Setup Node
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
- uses: dorny/paths-filter@7b450fff21473bca461d4b92ce414b9d0420d706 # v4.0.2
id: filter
with:
node-version: 24
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install build
npm install -g jsonld-cli
npm --prefix scripts ci
- name: Install Linux packages
if: runner.os == 'Linux'
run: |
sudo apt update
sudo apt install -y build-essential cppcheck doxygen graphviz
- name: Install macOS packages
if: runner.os == 'macOS'
run: |
brew update
brew install cppcheck doxygen gcc go graphviz
- name: Install Go static analysis tools
run: |
echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH"
go install honnef.co/go/tools/cmd/staticcheck@latest
- name: Install Rust static analysis tools
run: |
rustup component add clippy
- name: Build package
run: |
python -m build
- name: Install package
run: |
pip install -e .[dev]
- name: Run tests
run: |
pytest -v
filters: |
common: &common
- '.github/workflows/_pytest.yaml'
- '.github/workflows/test.yaml'
- 'src/shacl2code/*.py'
- 'src/shacl2code/lang/__init__.py'
- 'src/shacl2code/lang/common.py'
- 'src/shacl2code/lang/jinja.py'
- 'src/shacl2code/lang/lang.py'
- 'pyproject.toml'
- 'tests/conftest.py'
- 'tests/data/**'
- 'testfixtures/**'
cpp:
- *common
- 'src/shacl2code/lang/cpp.py'
- 'src/shacl2code/lang/sources/cpp/**'
- 'src/shacl2code/lang/templates/cpp/**'
- 'tests/test_cpp.py'
golang:
- *common
- 'src/shacl2code/lang/golang.py'
- 'src/shacl2code/lang/sources/golang/**'
- 'src/shacl2code/lang/templates/golang/**'
- 'tests/test_golang.py'
jsonschema:
- *common
- 'scripts/**'
- 'src/shacl2code/lang/jsonschema.py'
- 'src/shacl2code/lang/sources/jsonschema/**'
- 'src/shacl2code/lang/templates/jsonschema.j2'
- 'tests/test_jsonschema.py'
python:
- *common
- 'src/shacl2code/lang/python.py'
- 'src/shacl2code/lang/sources/python/**'
- 'src/shacl2code/lang/templates/python/**'
- 'tests/test_python.py'
rust:
- *common
- 'src/shacl2code/lang/rust.py'
- 'src/shacl2code/lang/templates/rust/**'
- 'tests/test_rust.py'

# Always run core (ignores language-specific test suites)
core:
uses: ./.github/workflows/_pytest.yaml
with:
install-native-toolchains: false
test-files: >-
tests
--ignore=tests/test_cpp.py
--ignore=tests/test_golang.py
--ignore=tests/test_jsonschema.py
--ignore=tests/test_python.py
--ignore=tests/test_rust.py

cpp:
needs: changes
if: needs.changes.outputs.cpp == 'true'
uses: ./.github/workflows/_pytest.yaml
with:
install-native-toolchains: true
test-files: tests/test_cpp.py

golang:
needs: changes
if: needs.changes.outputs.golang == 'true'
uses: ./.github/workflows/_pytest.yaml
with:
install-native-toolchains: false
install-go: true
install-go-staticcheck: true
test-files: tests/test_golang.py

jsonschema:
needs: changes
if: needs.changes.outputs.jsonschema == 'true'
uses: ./.github/workflows/_pytest.yaml
with:
install-native-toolchains: false
test-files: tests/test_jsonschema.py

python:
needs: changes
if: needs.changes.outputs.python == 'true'
uses: ./.github/workflows/_pytest.yaml
with:
install-native-toolchains: false
test-files: tests/test_python.py

rust:
needs: changes
if: needs.changes.outputs.rust == 'true'
uses: ./.github/workflows/_pytest.yaml
with:
# `rust`/`cargo` preinstalled on runners
install-native-toolchains: false
install-rust-clippy: true
test-files: tests/test_rust.py

lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Setup Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
# Black in this Python version must support all target-versions listed in pyproject.toml
python-version: "3.14"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ shacl2code generate \
--input model-draft.ttl \
--context-url context-draft.jsonld https://example.com/context.jsonld \
jsonschema \
--output schema.json
--output schema.json
```

## Developing
Expand Down
Loading