Contributing to Gemara
August 27, 2026 ยท View on GitHub
The project welcomes your contributions whether they be:
- reporting an issue
- making a code contribution (create a fork)
- updating our docs
PR guidelines
All changes to the repository should be made via PR (OSPS-AC-03).
PRs MUST meet the following criteria:
- Clear title that conforms to the Conventional Commits spec
- Descriptive commit message
- DCO signoff (via
git commit -s-- OSPS-LE-01) - All checks must pass (OSPS-QA-04)
Useful make tasks when making schema changes
Make sure to update schema-nav.yml in the website repository, after making any changes to the schemas in the layer.cue files
For instance:
You have added a new schema 'newschema' in layerN.cue( where N is a number from 1 - 7), the website's schema-nav.yml should look like:
- title: "Layer N"
filename: "layer-N"
schemas:
- "SchemaA"
- "SchemaB"
- "SchemaC"
- newschema //new schema added
Use cue fmt . and make cuefmtcheck to ensure proper formatting and make lintcue to validate the syntax of your changes. If you forget to do this before opening a PR and your changes are invalid, the CI workflow will fail and alert you.
Adding a new artifact type
Adding a new artifact type requires schema changes, test data, and documentation updates. Follow the checklist below.
| Step | Action |
|---|---|
| 1 | Define the new #YourArtifact definition in the appropriate layer-N.cue file |
| 2 | Add "YourArtifact" to the #ArtifactType enum in base.cue |
| 3 | Add new enum or alias types to schema-nav.yml in the website repo under the correct layer |
| 4 | Create a valid test data file in test/test-data/ (prefix with good-) |
| 5 | Add positive and/or negative test cases to test/schema_test.go |
| 6 | Run cue vet -d '#YourArtifact' . test/test-data/good-your-artifact.yaml to validate locally |
| 7 | Run cue fmt . and make cuefmtcheck to verify formatting |
| 8 | Run make lintcue and make test to confirm all checks pass |
Schema compatibility
The schemas form a public contract. A CI gate compares an OpenAPI projection of the current
schema against the latest released v1 baseline and fails the check on any backward-incompatible
change. The gate enforces compatibility in both directions: it is consumer-safe (a response
may not drop a property or a guarantee that existing readers depend on) and producer-safe (a request
may not add a new requirement that existing writers cannot satisfy).
Run the check locally before opening a PR:
make breaking-check
This generates the OpenAPI projection, fetches the latest v1 release as the baseline, and reports
any breaking changes with their oasdiff check IDs.
Making an intentional breaking change
Sometimes a breaking change is deliberate. There are exactly two sanctioned ways to introduce one:
-
Bump the module major version to
@v2. A major bump establishes a new baseline lineage, sov1consumers are never silently broken. Use this when the breaking change is part of a broader, intentional evolution of the contract. -
Allowlist the specific change. Add the offending exception to a
.oasdiff-allowfile at the repository root;make breaking-checkpasses it to the check via--allowautomatically when the file exists. Each entry is a schema-scoped<check-id> <schema>pair, one per line, so the exception applies only to that one schema. The check ID and schema are both printed for every reported change, so you can copy them straight from the output โ e.g. a change reported as:ERR[request-property-enum-value-removed] ControlEvaluation: removed the enum value ...is allowlisted with:
request-property-enum-value-removed ControlEvaluationThis MUST be done in a reviewed PR, and the file MUST include a justification comment (lines beginning with
#) explaining why the change is acceptable. Use this for narrowly scoped, well-understood exceptions.
Do not work around the gate by any other means.
Releases
Releases are automatically created when a PR is merged into main with the release label. To trigger a release:
- Add the
releaselabel to your PR before merging - Merge the PR into
main
The release workflow will automatically:
- Create a GitHub release with the appropriate version tag
- Generate release notes from the PR using release-drafter
- Publish the CUE module to the central registry
Note: Only PRs merged into main with the release label will trigger a release. Other labels (such as breaking, feature, or vuln) will not trigger releases.