From 669c7a857a02720a8234d6f1b3501a203d45e427 Mon Sep 17 00:00:00 2001 From: Thomas Hanke Date: Thu, 16 Apr 2026 11:22:28 +0200 Subject: [PATCH 1/2] feat: split qc.yml into fast PR checks + full build jobs - pr-checks job runs on every PR (no path filter): ODK fast gates (validate_idranges, reason_test, sparql_test, robot_reports) + OWL DL profile validation + upserted PR comment with report - ontology-build job replaces old single job (push/dispatch only) - README: document both jobs, customisation options (SPARQL queries, make flags, profile, memory, disabling PR comment) --- .github/workflows/qc.yml | 478 ++++++++++++++++++++------------------- README.md | 87 ++++++- 2 files changed, 330 insertions(+), 235 deletions(-) diff --git a/.github/workflows/qc.yml b/.github/workflows/qc.yml index 29c957a..88f21c1 100644 --- a/.github/workflows/qc.yml +++ b/.github/workflows/qc.yml @@ -1,25 +1,46 @@ # ============================================================================== # WORKFLOW: Build Ontology (Quality Control) # ============================================================================== -# Purpose: Builds ontology release assets and performs quality control checks +# Purpose: Two-phase CI — fast PR checks on every pull request, full build on +# push/dispatch. # -# This workflow: -# 1. Refreshes imports to ensure consistency with upstream ontologies -# 2. Generates release artifacts (OWL, JSON-LD, Turtle, etc.) -# 3. Runs quality control checks (syntax, consistency, reasoning) -# 4. Commits generated assets back to the repository -# 5. Triggers the documentation workflow to continue the chain +# ┌─────────────────────────────────────────────────────────────────────┐ +# │ Job 1: pr-checks (pull_request events only) │ +# │ ───────────────────────────────────────────────────────────────── │ +# │ Fast ODK quality gates run on every PR regardless of which files │ +# │ changed. Results are posted as a comment on the PR. │ +# │ │ +# │ Checks performed: │ +# │ • validate_idranges — IRI ranges in *-idranges.owl are intact │ +# │ • reason_test — ontology is consistent (ELK reasoner) │ +# │ • sparql_test — SPARQL unit tests in src/ontology/sparql/ │ +# │ • robot_reports — ROBOT report (missing labels, etc.) │ +# │ • validate-profile DL — ontology is valid OWL DL │ +# │ │ +# │ Customisation: │ +# │ Add *.sparql files to src/ontology/sparql/ to extend checks. │ +# │ See README § "Customising PR Quality Checks". │ +# │ │ +# │ To disable a check, pass its make flag as false, e.g.: │ +# │ make IMP=false PAT=false COMP=false MIR=false reason_test │ +# ├─────────────────────────────────────────────────────────────────────┤ +# │ Job 2: ontology-build (push / dispatch events) │ +# │ ───────────────────────────────────────────────────────────────── │ +# │ Full build triggered only when ontology source files change on │ +# │ main (or via workflow/repository dispatch). │ +# │ │ +# │ Steps: │ +# │ 1. make refresh-imports — re-extract SLME modules │ +# │ 2. make all_assets — generate OWL/TTL/JSON release files │ +# │ 3. Commit release artifacts back to main │ +# │ 4. Dispatch trigger-docs to start docs.yml │ +# └─────────────────────────────────────────────────────────────────────┘ # -# This is the core build workflow that transforms the edit file -# (*-edit.owl) into production-ready ontology releases in multiple formats. -# -# Execution Chain Position: -# setup-repo → [BUILD/QC] → docs -# update-repo → [BUILD/QC] → docs -# [BUILD/QC] → docs (on direct push to main) -# -# Read more about ODK builds: -# https://github.com/INCATools/ontology-development-kit#building-the-ontology +# Execution chain: +# setup-repo → [ontology-build] → docs +# update-repo → [ontology-build] → docs +# push to main (ontology files) → [ontology-build] → docs +# any PR → [pr-checks] # ============================================================================== name: Build Ontology @@ -27,74 +48,15 @@ name: Build Ontology # ============================================================================== # WORKFLOW TRIGGERS # ============================================================================== -# This workflow can be triggered in four ways: -# 1. Via repository_dispatch from setup-repo or update-repo workflow -# 2. Automatically on pushes to main that modify ontology source files -# 3. Automatically on pull requests that modify ontology source files -# 4. Manually via workflow_dispatch for forced builds -# -# Path filters ensure the workflow only runs when ontology files change, -# preventing unnecessary builds on unrelated commits (README, docs, etc.). -# -# IMPORTANT: The push trigger here only monitors ontology source/edit files. -# The refresh-imports workflow independently monitors import-related files -# and is used only for standalone import refreshes (workflow_dispatch / -# repository_dispatch). This prevents double-triggering on import changes. -# -# IMPORTANT: Push triggers skip commits made by github-actions[bot] to prevent -# duplicate runs when the workflow chain is triggered via repository_dispatch. -# ============================================================================== on: - # ============================================================================ - # TRIGGER 1: Repository Dispatch (from setup-repo or update-repo workflow) - # ============================================================================ - # Listens for 'trigger-qc' event dispatched by: - # - setup-repo.yml (after full ontology scaffolding) - # - update-repo.yml (after ODK config regeneration) - # This ensures build runs immediately after those workflows complete. - # ============================================================================ + # ── Trigger from setup-repo / update-repo ────────────────────────────────── repository_dispatch: types: [trigger-qc] - # ============================================================================ - # TRIGGER 2: Push Events (for regular development on main) - # ============================================================================ - # Triggers when core ontology files are pushed to main branch. - # - # Why main branch only? - # - Prevents unnecessary builds on feature/dev branches - # - Production artifacts are built from main - # - # Path filter rationale: - # - *-edit.owl : The primary ontology edit file being developed - # - components/**: Component OWL modules (classes, properties, axioms) - # - imports/** : Import module definitions and extracted term files - # - Makefile : Core ODK build configuration - # - *-Makefile : User-extended Makefile overrides - # - # NOTE: Bot commits from this workflow are NOT skipped here via 'if' - # conditions on the job. Instead, we avoid the infinite loop by design: - # the workflow commits to main, but that commit only touches release - # artifacts (*.owl, *.json, *.ttl) — NOT the paths monitored below. - # So there is no re-trigger from bot commits. - # ============================================================================ + # ── Push to main: full build (path-filtered to ontology source files) ─────── + # Bot commits from this workflow touch only release artifacts (*.owl, *.ttl, + # *.json) which are NOT in the paths list below, so there is no infinite loop. push: - branches: ["main"] - paths: - - 'src/ontology/*-edit.owl' # Main edit file changes - - 'src/ontology/components/**' # Component module changes - - 'src/ontology/imports/**' # Import-related file changes - - 'src/ontology/Makefile' # Core Makefile changes - - 'src/ontology/*-Makefile' # User-generated Makefile changes - - # ============================================================================ - # TRIGGER 3: Pull Request Events (for PR validation before merge) - # ============================================================================ - # Triggers a dry-run build on pull requests targeting main. - # Commits are skipped for PRs (see commit step condition below). - # This catches build errors and QC failures before code lands on main. - # ============================================================================ - pull_request: branches: ["main"] paths: - 'src/ontology/*-edit.owl' @@ -103,200 +65,260 @@ on: - 'src/ontology/Makefile' - 'src/ontology/*-Makefile' - # ============================================================================ - # TRIGGER 4: Manual Trigger (for forced builds or debugging) - # ============================================================================ - # Allows manual execution via GitHub UI or API. - # Useful for: - # - Forcing rebuild after external changes (e.g. upstream ontology update) - # - Troubleshooting build issues without touching source files - # - Testing the complete pipeline end-to-end - # ============================================================================ + # ── Pull request: fast PR checks (no path filter — runs on every PR) ──────── + pull_request: + branches: ["main"] + + # ── Manual trigger ────────────────────────────────────────────────────────── workflow_dispatch: # ============================================================================== -# ENVIRONMENT VARIABLES -# ============================================================================== -# Global variables available to all jobs in this workflow +# ENVIRONMENT # ============================================================================== env: - # Default branch for git operations (used in some ODK make targets) DEFAULT_BRANCH: main # ============================================================================== # JOBS # ============================================================================== jobs: + # ============================================================================ - # JOB: ontology_qc + # JOB 1: pr-checks # ============================================================================ - # Main job that performs the complete build and QC process. - # - # Process Flow: - # 1. Checkout repository with full history - # 2. Build ontology (runs make refresh-imports + all_assets inside ODK container) - # 3. Commit generated release files back to the repository - # 4. Trigger documentation generation workflow (docs.yml) + # Runs ONLY on pull_request events. Performs fast ODK quality gates and + # posts a summary comment on the PR. # - # Container: obolibrary/odkfull:v1.6 - # - Includes ROBOT, OWLTools, make, Java, Python, reasoning tools - # - Version pinned for reproducibility + # Flags explained: + # IMP=false — skip import refresh (use committed imports as-is) + # PAT=false — skip pattern expansion + # COMP=false — skip component rebuild + # MIR=false — skip mirror downloads # - # Permissions: contents: write (required for committing release artifacts) + # These flags keep the PR check fast (< 3 min typically) by skipping the + # heavy steps that are only needed for a full release build. # ============================================================================ - ontology_qc: + pr-checks: + name: PR Quality Checks + if: github.event_name == 'pull_request' runs-on: ubuntu-latest + container: obolibrary/odkfull:v1.6 - # Grant write permissions for committing generated release assets back to repo permissions: - contents: write + contents: read + pull-requests: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + # ── Fast ODK quality gates ───────────────────────────────────────────── + # Targets: + # validate_idranges checks *-idranges.owl is consistent with edit file + # reason_test runs ELK reasoner; also produces tmp/merged-*.ofn + # sparql_test runs all *.sparql tests in src/ontology/sparql/ + # robot_reports ROBOT report: missing labels, synonyms, definitions + # + # Add custom SPARQL checks by placing *.sparql files in: + # src/ontology/sparql/ + # ODK automatically discovers and runs them via sparql_test. + # ────────────────────────────────────────────────────────────────────── + - name: ODK fast quality checks + run: | + cd src/ontology + make IMP=false PAT=false COMP=false MIR=false \ + validate_idranges reason_test sparql_test robot_reports + + # ── OWL DL profile validation ────────────────────────────────────────── + # Uses the merged ontology file produced by reason_test above. + # Fails the job if the ontology violates OWL DL constraints. + # To target a different profile (e.g. EL), change --profile EL. + # ────────────────────────────────────────────────────────────────────── + - name: Validate OWL DL profile + run: | + cd src/ontology + # ODK's reason_test writes the merged ontology to tmp/ + MERGED=$(ls tmp/merged-*-edit.ofn 2>/dev/null | head -1) + if [ -z "$MERGED" ]; then + echo "No merged file found in tmp/ — skipping DL profile check." + exit 0 + fi + robot validate-profile \ + --profile DL \ + --input "$MERGED" \ + --output ../../validation.txt \ + || { cat ../../validation.txt; exit 1; } - # Use ODK container for a consistent, reproducible build environment. - # odkfull includes: ROBOT (OWL reasoner + transformer), make, Java, Python, - # yq (YAML processor), and all ODK tooling required for ontology builds. + # ── Collect ROBOT report and post PR comment ─────────────────────────── + # Reads the report TSV produced by robot_reports and posts a markdown + # summary both to the GitHub Step Summary and as a PR comment. + # + # The comment is upserted: if a previous run already posted a comment + # with the marker it will be updated in place + # rather than creating a new comment on every push to the PR branch. + # + # To disable the PR comment (keep only the Step Summary), remove the + # gh pr comment / gh api call at the end of the Python block below. + # ────────────────────────────────────────────────────────────────────── + - name: Post QC report as PR comment + if: always() + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + python3 - <<'EOF' + import csv, os, glob, subprocess + + def read_report(pattern): + files = glob.glob(pattern) + if not files: + return [] + rows = [] + with open(files[0], newline="") as f: + reader = csv.DictReader(f, delimiter="\t") + for row in reader: + rows.append(row) + return rows + + def severity_emoji(level): + return {"ERROR": "🔴", "WARN": "🟡", "INFO": "🔵"}.get(level.upper(), "⚪") + + report_rows = read_report("src/ontology/*.report.tsv") + + if not report_rows: + issues_md = "_No issues found — all ROBOT report checks passed._" + else: + errors = [r for r in report_rows if r.get("Level","").upper() == "ERROR"] + warnings = [r for r in report_rows if r.get("Level","").upper() == "WARN"] + infos = [r for r in report_rows if r.get("Level","").upper() == "INFO"] + + lines = [] + if errors: + lines.append(f"**🔴 Errors: {len(errors)}**") + if warnings: + lines.append(f"**🟡 Warnings: {len(warnings)}**") + if infos: + lines.append(f"**🔵 Info: {len(infos)}**") + + if errors or warnings: + lines.append("") + lines.append("| Level | Subject | Property | Value |") + lines.append("| --- | --- | --- | --- |") + for r in (errors + warnings)[:50]: # cap at 50 rows + lvl = severity_emoji(r.get("Level","")) + " " + r.get("Level","") + subj = r.get("Subject", r.get("Entity","")) + prop = r.get("Property","") + val = r.get("Value", r.get("Note","")) + lines.append(f"| {lvl} | {subj} | {prop} | {val} |") + if len(errors + warnings) > 50: + lines.append(f"_… and {len(errors+warnings)-50} more. Download the full report artifact._") + issues_md = "\n".join(lines) + + # Read DL validation result if present + dl_md = "" + if os.path.exists("validation.txt"): + content = open("validation.txt").read().strip() + if content: + dl_md = f"\n\n### OWL DL Profile\n```\n{content[:2000]}\n```" + + marker = "" + md = ( + f"{marker}\n" + f"## Ontology Quality Check\n\n" + f"### ROBOT Report\n{issues_md}" + f"{dl_md}\n" + ) + + # Write to GitHub Step Summary + summary_path = os.environ.get("GITHUB_STEP_SUMMARY", "") + if summary_path: + with open(summary_path, "a") as f: + f.write(md) + + # Post / update PR comment + pr_ref = os.environ.get("GITHUB_REF", "") + pr_num = pr_ref.replace("refs/pull/", "").replace("/merge", "") + if not pr_num.isdigit(): + print("Not a PR context — skipping comment.") + else: + repo = os.environ["GITHUB_REPOSITORY"] + result = subprocess.run( + ["gh", "api", f"repos/{repo}/issues/{pr_num}/comments", + "--jq", f'[.[] | select(.body | startswith("{marker}")) | .id][0]'], + capture_output=True, text=True + ) + comment_id = result.stdout.strip() + if comment_id and comment_id != "null": + subprocess.run( + ["gh", "api", f"repos/{repo}/issues/comments/{comment_id}", + "-X", "PATCH", "-f", f"body={md}"], + check=True + ) + else: + subprocess.run( + ["gh", "pr", "comment", pr_num, "--repo", repo, "--body", md], + check=True + ) + EOF + + # ── Archive reports ──────────────────────────────────────────────────── + - name: Archive QC reports + if: always() + uses: actions/upload-artifact@v4 + with: + name: qc-reports + path: | + src/ontology/*.report.tsv + validation.txt + retention-days: 14 + + # ============================================================================ + # JOB 2: ontology-build + # ============================================================================ + # Runs for push / repository_dispatch / workflow_dispatch events. + # Performs the full ODK build and commits release artifacts to main. + # ============================================================================ + ontology-build: + name: Build Ontology + if: github.event_name != 'pull_request' + runs-on: ubuntu-latest container: obolibrary/odkfull:v1.6 + permissions: + contents: write + steps: - # ======================================================================== - # STEP 1: Checkout Repository - # ======================================================================== - # Fetch complete repository with full git history. - # - # Why fetch-depth: 0 (full history)? - # - ODK make targets may inspect git history for versioning - # - Ensures accurate version numbers in release artifacts - # - Allows git operations (log, describe) within build scripts - # ======================================================================== - name: Checkout repository uses: actions/checkout@v4 with: - fetch-depth: 0 # Full git history required for ODK builds + fetch-depth: 0 - # ======================================================================== - # STEP 2: Build Ontology (Refresh Imports + Generate All Artifacts) - # ======================================================================== - # Runs two ODK make targets inside the odkfull container: + # ── Full ODK build ───────────────────────────────────────────────────── + # refresh-imports: re-download upstream ontologies and extract SLME modules + # all_assets: generate OWL/TTL/JSON release files + QC reports # - # Target 1: refresh-imports - # - Downloads and extracts terms from upstream ontologies - # - Updates all import module OWL files (imports/*_import.owl) - # - Uses SLME (Syntactic Locality Module Extraction) for minimal imports - # - Reads term lists from imports/*_terms.txt - # - # Target 2: all_assets - # Generates all release artifacts: - # - {id}-full.owl : Complete ontology (all imports merged) - # - {id}-base.owl : Core ontology without transitive imports - # - {id}.owl : Main release file - # - {id}.json : JSON-LD serialization - # - {id}.ttl : Turtle serialization - # - {id}-simple.owl : Simplified version (if configured) - # - {id}-non-classified.owl : Pre-reasoning version (if configured) - # - Component OWL files, QC reports, statistics - # - # Memory configuration (ROBOT_ENV): - # ROBOT_ENV is consumed by the ODK Makefile as a prefix to the ROBOT - # command: `$(ROBOT_ENV) robot ...`. Setting ROBOT_JAVA_ARGS=-Xmx6G - # allocates 6GB Java heap to ROBOT, which is required for reasoning - # over large ontologies. Increase to -Xmx8G if you see OutOfMemory errors. - # ======================================================================== + # Memory: ROBOT_JAVA_ARGS=-Xmx6G is sufficient for most ontologies. + # Increase to -Xmx8G / -Xmx12G if you hit OutOfMemory errors. + # ────────────────────────────────────────────────────────────────────── - name: Build ontology (refresh imports + generate all release assets) env: - # Configure ROBOT Java heap: 6GB is sufficient for most ontologies. - # Increase to -Xmx8G or -Xmx12G if OOM errors occur during reasoning. ROBOT_ENV: 'ROBOT_JAVA_ARGS=-Xmx6G' run: | - # Navigate to the ODK ontology source directory cd src/ontology - - echo "=== Starting ODK build ===" - echo "Step 2a: Refreshing ontology imports..." - echo "Step 2b: Generating all release assets..." - - # Run both ODK targets: - # - refresh-imports : Mirrors external ontologies and extracts SLME modules - # - all_assets : Generates all release serializations and runs QC make refresh-imports all_assets - echo "=== Build complete ===" - - # ======================================================================== - # STEP 3: Commit Ontology Release Assets - # ======================================================================== - # Commits the generated release files back to the repository so they are - # versioned alongside the source and available for the docs workflow. - # - # Conditions: - # - SKIPPED for pull requests: PR contributors should review changes manually - # before merge; artifacts are not committed on PR runs. - # - Only commits if there are actual changes (EndBug/add-and-commit@v9 - # automatically skips empty commits). - # - # Files committed: - # - src/ontology/*.owl : All OWL serializations (full, base, simple, etc.) - # - src/ontology/*.json : JSON-LD serializations - # - src/ontology/*.ttl : Turtle serializations - # - src/ontology/imports/*.owl : Updated import modules - # - # Why --force? - # - ODK generates these files but they may be listed in .gitignore - # - --force overrides .gitignore so release artifacts are versioned - # - This is intentional: release assets should be tracked for distribution - # - # Commit identity: - # - Author set to github-actions[bot] to distinguish automated commits - # from human developer commits in git log - # ======================================================================== + # ── Commit release artifacts ─────────────────────────────────────────── - name: Commit ontology release assets - # Only commit for push and dispatch events — skip for pull requests - if: github.event_name != 'pull_request' uses: EndBug/add-and-commit@v9 with: - # Descriptive message — visible in git log, easy to filter message: "Building the ontology from the edits" - - # Repository root as working directory cwd: "." - - # Add all generated files; --force bypasses .gitignore for artifacts add: "src/ontology/*.owl src/ontology/*.json src/ontology/*.ttl src/ontology/imports/*.owl --force" - - # Commit as the GitHub Actions bot (standard identity for CI commits) default_author: github_actions - - # Push directly to the current branch push: true - # ======================================================================== - # STEP 4: Trigger Documentation Workflow - # ======================================================================== - # After the ontology is successfully built and committed, dispatch a - # repository event to start the Widoco documentation generation workflow. - # - # Workflow chain: - # setup-repo ─→ [this: BUILD/QC] ─→ docs - # update-repo ─→ [this: BUILD/QC] ─→ docs - # push to main ─→ [this: BUILD/QC] ─→ docs - # - # Why repository_dispatch and not a direct workflow call? - # - Maintains clean separation between workflow stages - # - Avoids nested workflow complexity (GitHub has limits on chained calls) - # - Ensures docs always build from the committed artifact, not mid-run state - # - Prevents race conditions between build commit and docs generation - # - # The 'trigger-docs' event is listened for by docs.yml. - # - # Condition: Only dispatch for non-PR events. - # - PRs do not deploy to Pages; docs are rebuilt after PR merge to main. - # ======================================================================== + # ── Trigger documentation workflow ───────────────────────────────────── - name: Trigger Documentation Workflow - # Skip for pull requests — docs will be regenerated after PR merge - if: github.event_name != 'pull_request' uses: peter-evans/repository-dispatch@v3 with: - # GITHUB_TOKEN is automatically available with the 'contents: write' - # permission set on this job. No PAT required. token: ${{ secrets.GITHUB_TOKEN }} - - # Event type that docs.yml listens for via repository_dispatch trigger event-type: trigger-docs diff --git a/README.md b/README.md index 5102d8a..04b4bd8 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,7 @@ application-ontology-template/ │ ├── .github/workflows/ # CI/CD pipeline (5 workflows) │ ├── setup-repo.yml # Initial ontology scaffolding (22 steps) -│ ├── qc.yml # Build + quality control +│ ├── qc.yml # PR quality checks + full build │ ├── refresh-imports.yml # Re-extract external imports via SLME │ ├── update-repo.yml # Sync repo structure from ODK config │ └── docs.yml # Generate Widoco HTML documentation @@ -285,11 +285,82 @@ Five GitHub Actions workflows automate the entire ontology lifecycle: | **What it does** | Reads config files → configures ODK → seeds repo scaffold → creates import stubs → patches catalog → generates shared OWL backbone → extracts imports via SLME → creates ROBOT templates → injects annotations → validates → commits → triggers QC build | | **Container** | `obolibrary/odkfull:v1.6` | -### `qc.yml` — Build Ontology +### `qc.yml` — Build Ontology + PR Quality Checks + +`qc.yml` runs two different jobs depending on the event type: + +#### Job 1: `pr-checks` — Fast quality gates on every pull request + +| | | +|:---|:---| +| **Trigger** | Every pull request targeting `main` (no path filter) | +| **Container** | `obolibrary/odkfull:v1.6` | +| **What it does** | Runs fast ODK quality checks → validates OWL DL profile → posts report as PR comment | + +Checks performed (in order): + +| Check | ODK target / tool | What it catches | +|:---|:---|:---| +| ID range validation | `make validate_idranges` | IRI conflicts outside allocated ranges | +| Consistency (ELK) | `make reason_test` | Unsatisfiable classes, logical contradictions | +| SPARQL unit tests | `make sparql_test` | Custom SPARQL checks in `src/ontology/sparql/` | +| ROBOT report | `make robot_reports` | Missing labels, definitions, synonyms | +| OWL DL profile | `robot validate-profile` | OWL DL violations (undeclared entities, etc.) | + +Results are posted as a **comment on the PR** and also appear in the GitHub Actions Step Summary. If a previous run already posted a comment, it is updated in place rather than creating a new one. + +#### Job 2: `ontology-build` — Full build on push to main + | | | |:---|:---| -| **Trigger** | Push to `main` / `repository_dispatch: trigger-qc` | -| **What it does** | Runs `make test` (reasoner + syntax checks) → `make refresh-imports` → builds release artifacts (OWL, TTL, JSON) → commits results → triggers docs | +| **Trigger** | Push to `main` (ontology source files only) / `repository_dispatch: trigger-qc` / `workflow_dispatch` | +| **Container** | `obolibrary/odkfull:v1.6` | +| **What it does** | `make refresh-imports` → `make all_assets` → commits release artifacts → triggers `docs.yml` | + +#### Customising PR Quality Checks + +**Add custom SPARQL checks** + +Place any `.sparql` `ASK` or `SELECT` query in `src/ontology/sparql/`. ODK's `sparql_test` target picks them up automatically: + +``` +src/ontology/sparql/ +├── my-check-no-orphans.sparql +└── my-check-required-annotations.sparql +``` + +**Disable a specific ODK check** + +Pass the corresponding flag as `false` in the `make` call inside `qc.yml`: + +```yaml +# Example: skip pattern expansion and mirror downloads +make IMP=false PAT=false COMP=false MIR=false validate_idranges reason_test sparql_test robot_reports +``` + +| Flag | Default | Effect when `false` | +|:---|:---|:---| +| `IMP` | true | Skip import refresh | +| `PAT` | true | Skip pattern expansion | +| `COMP` | true | Skip component rebuild | +| `MIR` | true | Skip upstream mirror downloads | + +**Change the OWL profile checked** + +In `qc.yml`, find the `robot validate-profile` step and change `--profile DL` to `--profile EL` or `--profile RL` as needed. + +**Disable the PR comment** (keep only GitHub Step Summary) + +In `qc.yml`, remove or comment out the `gh pr comment` / `gh api` call at the end of the `Post QC report as PR comment` step's Python block. + +**Increase ROBOT memory** (for large upstream ontologies) + +In the `ontology-build` job, change `ROBOT_JAVA_ARGS=-Xmx6G` to a larger value: + +```yaml +env: + ROBOT_ENV: 'ROBOT_JAVA_ARGS=-Xmx12G' +``` ### `refresh-imports.yml` — Refresh Ontology Imports | | | @@ -312,9 +383,11 @@ Five GitHub Actions workflows automate the entire ontology lifecycle: ### Workflow Chain ``` -setup-repo ──► qc (build) ──► docs (Widoco) - ▲ - push to main ───┘ +setup-repo ──► qc (ontology-build) ──► docs (Widoco) + ▲ + push to main ───────┘ + +any pull_request ──► qc (pr-checks) ──► PR comment ``` --- From 0135a286ffefd071b964d6ddb91fdd51410431dd Mon Sep 17 00:00:00 2001 From: Thomas Hanke Date: Thu, 16 Apr 2026 11:27:54 +0200 Subject: [PATCH 2/2] fix: skip ODK checks when src/ontology not yet scaffolded --- .github/workflows/qc.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.github/workflows/qc.yml b/.github/workflows/qc.yml index 88f21c1..833fda8 100644 --- a/.github/workflows/qc.yml +++ b/.github/workflows/qc.yml @@ -123,7 +123,22 @@ jobs: # src/ontology/sparql/ # ODK automatically discovers and runs them via sparql_test. # ────────────────────────────────────────────────────────────────────── + # ── Guard: skip ODK checks if repo not yet set up ───────────────────── + # src/ontology/ only exists after the setup-repo workflow has run. + # PRs against the template itself (before setup) skip all ODK steps. + # ────────────────────────────────────────────────────────────────────── + - name: Check ontology scaffold exists + id: scaffold + run: | + if [ -d "src/ontology" ] && [ -f "src/ontology/Makefile" ]; then + echo "present=true" >> $GITHUB_OUTPUT + else + echo "present=false" >> $GITHUB_OUTPUT + echo "src/ontology not found — skipping ODK checks (repo not yet set up)." + fi + - name: ODK fast quality checks + if: steps.scaffold.outputs.present == 'true' run: | cd src/ontology make IMP=false PAT=false COMP=false MIR=false \ @@ -135,6 +150,7 @@ jobs: # To target a different profile (e.g. EL), change --profile EL. # ────────────────────────────────────────────────────────────────────── - name: Validate OWL DL profile + if: steps.scaffold.outputs.present == 'true' run: | cd src/ontology # ODK's reason_test writes the merged ontology to tmp/