Skip to content

Commit deb6222

Browse files
feat!: replace hash-based IDs with semantic versioning for variant ID generation (#163)
* feat!: replace hash-based IDs with semantic versioning for variant ID generation Add variant-based ID generation and registry management to the s2dm-publish GitHub Action. The workflow now automatically initializes or updates the registry based on schema changes detected via GraphQL Inspector diff. - Add new `registry` module with variant ID tracking using semantic versions - Add `variant_ids.py` with VariantEntry and VariantIDFile models - Add `graphql_inspector_diff.js` for automated schema change detection - Add `diff_parser.py` to process GraphQL Inspector output - Variant increments now tied to graphql-inspector detected changes - Update ID exporter to generate semantic version-based variant IDs - Update spec history exporter to work with new variant ID system - Move `skos_search.py` to registry module - Add variant counter tracking for concept modifications - Add support for marking concepts as removed in specific versions - Add 15 comprehensive tests for variant ID generation logic - Update E2E CLI tests for new registry commands BREAKING CHANGES: - Removed `idgen` module and hash-based ID generation - `registry id` command now requires `--version-tag` parameter - `registry id` command removed `--strict-mode` option - `registry init` command now requires `--version-tag` parameter - `registry update` command now requires `--version-tag` and `--previous-ids` - Variant IDs use semantic versioning format (Concept/vM.m) instead of hashes - Integrate variant registry into automated workflow - Remove dry_run parameter from IDExporter - Registry operations now require version tags and previous registry files from release artifacts. Signed-off-by: Mustafa Kaptan <mustafa.kaptan@motius.de> * refactor(graphql-inspector): add local dependencies and decorator pattern - Add package.json for local Node.js dependency management - Add @requires_graphql_inspector decorator for dependency injection - Add locate_graphql_inspector() to find node_modules automatically - Resolve CLI path once during initialization for performance - Improve dependency checking with runtime verification - Update CI/Actions to use npm install instead of global install - Update documentation in CONTRIBUTING.md and tools/README.md Replaces global npm install with local package.json management. The decorator pattern auto-injects inspector_path to CLI commands, eliminating repeated lookups and global state. Signed-off-by: Mustafa Kaptan <mustafa.kaptan@motius.de> * fix: Add missing elements in example schema Tools expect explicit references to all elements Signed-off-by: JD Alvarez <8550265+jdacoello@users.noreply.github.com> * fix: Add missing elements to updated example schema Tools expect now all elements explicitly. Signed-off-by: JD Alvarez <8550265+jdacoello@users.noreply.github.com> --------- Signed-off-by: Mustafa Kaptan <mustafa.kaptan@motius.de> Signed-off-by: JD Alvarez <8550265+jdacoello@users.noreply.github.com> Co-authored-by: JD Alvarez <8550265+jdacoello@users.noreply.github.com>
1 parent e294ed5 commit deb6222

39 files changed

+6054
-1756
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@ jobs:
2929
with:
3030
node-version: "20"
3131

32+
- name: install node dependencies
33+
run: npm install
34+
3235
- name: uv
3336
uses: astral-sh/setup-uv@v7
3437

35-
- name: npm install gql-inspector
36-
run: npm i --global @graphql-inspector/cli graphql
37-
3838
- name: sync
3939
run: |
4040
uv sync --frozen

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,4 +180,5 @@ cython_debug/
180180
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
181181
# and can be added to the global gitignore or merged into this file. For a more nuclear
182182
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
183-
#.idea/
183+
.idea/
184+
.cursor/

CONTRIBUTING.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,24 @@ uv sync
2525
```
2626

2727
It will create a virtual environment `.venv` in the root of the project.
28+
29+
### Node.js Dependencies
30+
31+
Some features require Node.js dependencies for GraphQL schema operations. Install them with:
32+
33+
```shell
34+
npm install
35+
```
36+
37+
This installs `@graphql-inspector/cli`, `@graphql-inspector/core`, and `graphql` packages required by:
38+
- `s2dm diff graphql` - Structured diff output
39+
- `s2dm check version-bump` - Version bump detection
40+
- `s2dm validate graphql` - Schema validation
41+
- `s2dm similar graphql` - Type similarity search
42+
- `s2dm registry init` and `s2dm registry update` - Registry functionality
43+
44+
> [!NOTE]
45+
> The `@requires_graphql_inspector` decorator automatically locates and injects the path to the local `node_modules` directory. Commands will fail with clear error messages if dependencies are missing. The GraphQL Inspector wrapper resolves the CLI path once during initialization for optimal performance.
2846
You can run things in the virtual environment by using a `uv run` prefix for commands, e.g.:
2947

3048
```shell
@@ -80,6 +98,42 @@ pytest --cov-report term-missing --cov=s2dm -vv
8098

8199
New code should ideally have tests and not break existing tests.
82100

101+
#### Skipping GraphQL Inspector Tests
102+
103+
Some tests require the `@graphql-inspector/cli` package to be installed via npm. These tests are marked with `@pytest.mark.graphql_inspector`.
104+
105+
**If you don't have Node.js dependencies installed:**
106+
107+
These tests will automatically be skipped with a message:
108+
```
109+
SKIPPED [9] tests/conftest.py:309: graphql-inspector not found. Run 'npm install' to install dependencies.
110+
```
111+
112+
**To explicitly skip these tests:**
113+
114+
```bash
115+
# Skip all graphql_inspector tests
116+
pytest -m "not graphql_inspector"
117+
118+
# Skip graphql_inspector tests with verbose output
119+
pytest -m "not graphql_inspector" -v
120+
121+
# Run only graphql_inspector tests
122+
pytest -m "graphql_inspector"
123+
```
124+
125+
**To run these tests:**
126+
127+
1. Install Node.js dependencies first:
128+
```bash
129+
npm install
130+
```
131+
132+
2. Then run all tests normally:
133+
```bash
134+
pytest
135+
```
136+
83137
### Type Checking
84138

85139
Simplified Semantic Data Modeling uses type annotations throughout, and `mypy` to do the checking.

actions/s2dm-publish/README.md

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ GitHub Action for automated artifact generation and publishing workflow through
55
## Features
66

77
- Automatic version bump detection
8-
- Units synchronization
98
- Registry management (init/update)
109
- GraphQL schema composition
1110
- JSON schema generation
@@ -178,14 +177,39 @@ Your repository must have:
178177
commit_args = ""
179178
```
180179

180+
## Registry and Variant IDs
181+
182+
The action automatically manages variant-based IDs for schema concepts:
183+
184+
- **Variant IDs**: Each concept gets a semantic version (e.g., `Vehicle.speed/v1.0`)
185+
- **Change Detection**: GraphQL Inspector detects schema changes and triggers version increments
186+
- **Breaking vs Non-Breaking**: Breaking changes increment major version (v1.0 → v2.0), non-breaking changes increment minor (v1.0 → v1.1)
187+
- **History Tracking**: All concept definitions are saved to a history directory for traceability
188+
189+
### Release Artifacts
190+
191+
Each release includes:
192+
- `registry.json` - Complete spec history with variant IDs
193+
- `variant_ids_<tag>.json` - Current variant ID mappings
194+
- `concept_uris_<tag>.json` - Concept URI definitions
195+
- `history/` - Directory with historical concept definitions
196+
181197
## How It Works
182198

183199
1. **Validation**: Validates that the spec directory exists and contains at least one .graphql file
184-
2. **Setup**: Checks out S2DM repository, installs Python 3.13, uv, and S2DM dependencies
185-
3. **Download Previous Release**: Downloads previous release artifacts (if available)
186-
4. **Version Check**: Compares current spec with previous schema to determine version bump type
187-
5. **Units Sync**: Synchronizes units definitions
188-
6. **Registry Management**: Initializes registry for first release or updates it for subsequent releases
189-
7. **Artifact Generation**: Generates all required artifacts (GraphQL, JSON Schema, SHACL, SKOS, VSpec) to temporary location outside repository
190-
8. **Version Bump**: Updates version using bump-my-version and creates git tag
191-
9. **Release Creation**: Creates GitHub release with all generated artifacts in a tarball
200+
1. **Setup**: Checks out S2DM repository, installs Python 3.13, Node.js 20, uv, and S2DM dependencies
201+
2. **Version Check**: Downloads previous release and compares current spec to determine version bump type
202+
3. **GraphQL Diff Generation**: Uses `s2dm diff graphql` (powered by @graphql-inspector/core) to detect schema changes (for updates)
203+
4. **Registry Management**:
204+
- For initial release: Initializes registry with variant IDs starting at v1.0
205+
- For updates: Increments variant IDs based on detected changes (major for breaking, minor for non-breaking)
206+
5. **Artifact Generation**: Generates all required artifacts (GraphQL, JSON Schema, SHACL, SKOS, VSpec)
207+
6. **Version Bump**: Updates version using bump-my-version and creates git tag
208+
7. **Release Creation**: Creates GitHub release with all generated artifacts including:
209+
- Composed GraphQL schema
210+
- JSON Schema
211+
- SHACL shapes
212+
- SKOS RDF
213+
- VSpec
214+
- Registry files (spec_history, variant_ids, concept_uris)
215+
- History directory with concept definitions

0 commit comments

Comments
 (0)