1313 issues : write
1414
1515 steps :
16+ # -----------------------------------------------------------------------
1617 - name : Checkout
1718 uses : actions/checkout@v4
1819
2122 with :
2223 python-version : " 3.12"
2324
25+ # -----------------------------------------------------------------------
26+ - name : Cache pip
27+ uses : actions/cache@v4
28+ with :
29+ path : ~/.cache/pip
30+ key : ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}
31+ restore-keys : ${{ runner.os }}-pip-
32+
33+ - name : Cache sentence-transformers model
34+ uses : actions/cache@v4
35+ with :
36+ path : ~/.cache/huggingface/hub
37+ key : hf-minilm-v2
38+ restore-keys : hf-
39+
40+ # Embeddings cache keyed on all schemas — new schema busts the cache and
41+ # forces a recompute, unchanged schemas reuse their cached vectors.
42+ - name : Cache embeddings
43+ uses : actions/cache@v4
44+ with :
45+ path : data/embeddings.parquet
46+ key : embeddings-${{ hashFiles('schemas/*.yml') }}-${{ github.run_id }}
47+ restore-keys : embeddings-${{ hashFiles('schemas/*.yml') }}-
48+ embeddings-
49+
50+ # -----------------------------------------------------------------------
2451 - name : Install dependencies
2552 run : pip install -r requirements.txt
2653
54+ # -----------------------------------------------------------------------
2755 - name : Parse issue metadata
2856 id : meta
2957 run : |
@@ -32,16 +60,17 @@ jobs:
3260 SCHEMA_NAME=$(echo "$SCHEMA_NAME" | xargs | tr ' ' '-' | tr '[:upper:]' '[:lower:]')
3361 echo "schema_name=$SCHEMA_NAME" >> $GITHUB_OUTPUT
3462
35- # Determine bump type:
36- # label "breaking" → major, default → minor
3763 LABELS='${{ toJson(github.event.issue.labels.*.name) }}'
3864 if echo "$LABELS" | grep -q "breaking"; then
3965 echo "bump=major" >> $GITHUB_OUTPUT
4066 else
4167 echo "bump=minor" >> $GITHUB_OUTPUT
4268 fi
4369
44- - name : Extract and convert schema from issue body
70+ # -----------------------------------------------------------------------
71+ # Write the submitted schema to schemas/{name}.yml so it's picked up
72+ # by pipeline.py alongside all previously committed schemas.
73+ - name : Extract and write schema file
4574 env :
4675 ISSUE_BODY : ${{ github.event.issue.body }}
4776 SCHEMA_NAME : ${{ steps.meta.outputs.schema_name }}
5382 body = os.environ["ISSUE_BODY"]
5483 name = os.environ["SCHEMA_NAME"]
5584
56- # Detect format from the code-fence language tag:
57- # ```linkml / ```yaml / ```yml → already LinkML
58- # ```json / ```json-schema → JSON Schema, needs conversion
5985 fenced = re.search(r'```([\w-]*)\s*\n(.*?)```', body, re.DOTALL)
6086 if fenced:
6187 lang = (fenced.group(1) or "yaml").lower()
@@ -65,13 +91,12 @@ jobs:
6591 content = body.strip()
6692
6793 json_schema_langs = {"json", "json-schema", "jsonschema"}
68- linkml_langs = {"yaml", "yml", "linkml", ""}
6994
7095 os.makedirs("schemas", exist_ok=True)
7196 out_path = f"schemas/{name}.yml"
7297
7398 if lang in json_schema_langs:
74- print(f"Detected format: JSON Schema (lang= {lang!r}) — converting to LinkML …")
99+ print(f"Detected format: JSON Schema ({lang!r}) — converting…")
75100 sys.path.insert(0, ".")
76101 from neuro_ghost.converters.from_jsonschema import convert as js2lm
77102 try:
@@ -82,54 +107,36 @@ jobs:
82107 with open(out_path, "w") as f:
83108 yaml.dump(linkml_dict, f, default_flow_style=False,
84109 allow_unicode=True, sort_keys=False)
85- print(f"Converted → {out_path} "
86- f"({len(linkml_dict['classes'])} classes, "
87- f"{len(linkml_dict['slots'])} slots)")
88- elif lang in linkml_langs or lang not in json_schema_langs:
89- print(f"Detected format: LinkML (lang={lang!r})")
110+ print(f"Converted → {out_path} "
111+ f"({len(linkml_dict['classes'])} classes)")
112+ else:
113+ print(f"Detected format: LinkML ({lang!r})")
90114 with open(out_path, "w") as f:
91115 f.write(content)
92116 print(f"Wrote {out_path}")
93- else:
94- print(f"ERROR: Unsupported schema format '{lang}'. "
95- "Use ```yaml (LinkML) or ```json (JSON Schema).")
96- sys.exit(1)
97117 PYEOF
98118
119+ # -----------------------------------------------------------------------
99120 - name : Validate LinkML schema
100121 run : |
101- python neuro_ghost/validate_schema.py schemas/${{ steps.meta.outputs.schema_name }}.yml
102-
103- - name : Seed schema.org (if DB not cached)
122+ python neuro_ghost/validate_schema.py \
123+ schemas/${{ steps.meta.outputs.schema_name }}.yml
124+
125+ # -----------------------------------------------------------------------
126+ # Full rebuild from all schemas/*.yml in the repo (including the new one
127+ # written above). --skip-converters keeps CI fast — external schemas
128+ # (BIDS/NWB/DANDI/…) are refreshed by the weekly publish_registry.yml.
129+ - name : Rebuild registry (all local schemas)
104130 run : |
105- python neuro_ghost/seed.py \
106- --db registry.lbug \
107- --registry-version 1.0.0
108-
109- - name : Ingest schema
110- run : |
111- python neuro_ghost/ingest_linkml.py \
112- --file schemas/${{ steps.meta.outputs.schema_name }}.yml \
113- --db registry.lbug \
131+ python neuro_ghost/pipeline.py \
132+ --fresh \
133+ --skip-converters \
134+ --bump ${{ steps.meta.outputs.bump }} \
114135 --issue ${{ github.event.issue.number }} \
115136 --agent "${{ github.event.issue.user.login }}"
116137
117- - name : Run alignment
118- run : |
119- python neuro_ghost/align.py \
120- --source ${{ steps.meta.outputs.schema_name }} \
121- --db registry.lbug
122-
123- - name : Export + version registry
124- run : |
125- python neuro_ghost/export_json.py \
126- --db registry.lbug \
127- --bump ${{ steps.meta.outputs.bump }} \
128- --issue ${{ github.event.issue.number }} \
129- --agent "${{ github.event.issue.user.login }}" \
130- --schema ${{ steps.meta.outputs.schema_name }}
131-
132- - name : Commit all artifacts
138+ # -----------------------------------------------------------------------
139+ - name : Commit registry + schema file
133140 run : |
134141 git config user.name "github-actions[bot]"
135142 git config user.email "github-actions[bot]@users.noreply.github.com"
@@ -139,23 +146,24 @@ jobs:
139146 data/versions/ \
140147 data/provenance.json
141148 git diff --cached --quiet || git commit -m \
142- "feat(registry): ingest ${{ steps.meta.outputs.schema_name }} from issue #${{ github.event.issue.number }}"
149+ "feat(registry): ingest ${{ steps.meta.outputs.schema_name }} ( issue #${{ github.event.issue.number }}) "
143150 git push
144151
152+ # -----------------------------------------------------------------------
145153 - name : Comment success
146154 if : success()
147155 uses : actions/github-script@v7
148156 with :
149157 script : |
150- const name = "${{ steps.meta.outputs.schema_name }}";
151- const pagesUrl = ` https://${context.repo.owner}.github.io/${context.repo.repo}` ;
158+ const name = "${{ steps.meta.outputs.schema_name }}";
159+ const pagesUrl = " https://sensein.group/NeuroGhost/" ;
152160 await github.rest.issues.createComment({
153161 owner: context.repo.owner, repo: context.repo.repo,
154162 issue_number: context.issue.number,
155163 body: [
156164 `✅ **\`${name}\` ingested successfully.**`,
157165 ``,
158- `- Classes, properties, and alignments committed .`,
166+ `- All schemas rebuilt and aligned .`,
159167 `- Provenance logged to \`data/provenance.json\`.`,
160168 `- Archived snapshot in \`data/versions/\`.`,
161169 ``,
@@ -178,8 +186,7 @@ jobs:
178186 body: [
179187 `❌ **Ingestion failed.**`,
180188 ``,
181- `Check the run log for the specific LinkML validation error (e.g. an undefined slot, ` +
182- `\`is_a\` parent, or range reference).`,
189+ `Check the run log for validation errors (undefined slot, \`is_a\` parent, or range).`,
183190 ``,
184191 `[View run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})`,
185192 ].join("\n"),
0 commit comments