2121 # ---------------------------------------------------------------------------
2222 a2ml-validate :
2323 name : Validate A2ML manifests
24- runs-on : ubuntu-latest
24+ runs-on : ubuntu-24.04
2525
2626 steps :
2727 - name : Checkout repository
6565 # ---------------------------------------------------------------------------
6666 k9-validate :
6767 name : Validate K9 contracts
68- runs-on : ubuntu-latest
68+ runs-on : ubuntu-24.04
6969
7070 steps :
7171 - name : Checkout repository
@@ -114,7 +114,7 @@ jobs:
114114 # ---------------------------------------------------------------------------
115115 empty-lint :
116116 name : Empty-linter (invisible characters)
117- runs-on : ubuntu-latest
117+ runs-on : ubuntu-24.04
118118
119119 steps :
120120 - name : Checkout repository
@@ -206,7 +206,7 @@ jobs:
206206 # ---------------------------------------------------------------------------
207207 groove-check :
208208 name : Groove manifest check
209- runs-on : ubuntu-latest
209+ runs-on : ubuntu-24.04
210210
211211 steps :
212212 - name : Checkout repository
@@ -264,7 +264,7 @@ jobs:
264264 # ---------------------------------------------------------------------------
265265 eclexiaiser-validate :
266266 name : Validate eclexiaiser manifest
267- runs-on : ubuntu-latest
267+ runs-on : ubuntu-24.04
268268
269269 steps :
270270 - name : Checkout repository
@@ -284,28 +284,34 @@ jobs:
284284
285285 echo "has_manifest=true" >> "$GITHUB_OUTPUT"
286286
287- # Validate TOML structure using Python 3.11+ tomllib
288- python3 -c "
289- import tomllib, sys
290- with open('eclexiaiser.toml', 'rb') as f:
291- data = tomllib.load(f)
292- project = data.get('project', {})
293- if not project.get('name', '').strip():
294- print('ERROR: project.name is required', file=sys.stderr)
295- sys.exit(1)
296- functions = data.get('functions', [])
297- if not functions:
298- print('ERROR: at least one [[functions]] entry is required', file=sys.stderr)
299- sys.exit(1)
300- for fn in functions:
301- if not fn.get('name', '').strip():
302- print('ERROR: function name cannot be empty', file=sys.stderr)
303- sys.exit(1)
304- if not fn.get('source', '').strip():
305- print(f'ERROR: function {fn[\"name\"]} has no source path', file=sys.stderr)
306- sys.exit(1)
307- print(f'Valid: {project[\"name\"]} ({len(functions)} function(s))')
308- " || {
287+ # Validate TOML structure using pre-installed yq
288+ (
289+ PROJECT_NAME=$(yq -e '.project.name // ""' eclexiaiser.toml)
290+ if [ -z "$PROJECT_NAME" ]; then
291+ echo "ERROR: project.name is required" >&2
292+ exit 1
293+ fi
294+
295+ FUNCTIONS_LEN=$(yq -e '.functions | length' eclexiaiser.toml)
296+ if [ -z "$FUNCTIONS_LEN" ] || [ "$FUNCTIONS_LEN" -eq 0 ]; then
297+ echo "ERROR: at least one [[functions]] entry is required" >&2
298+ exit 1
299+ fi
300+
301+ for i in $(seq 0 $((FUNCTIONS_LEN - 1))); do
302+ FN_NAME=$(yq -e ".functions[$i].name // \"\"" eclexiaiser.toml)
303+ if [ -z "$FN_NAME" ]; then
304+ echo "ERROR: function name cannot be empty" >&2
305+ exit 1
306+ fi
307+ FN_SRC=$(yq -e ".functions[$i].source // \"\"" eclexiaiser.toml)
308+ if [ -z "$FN_SRC" ]; then
309+ echo "ERROR: function $FN_NAME has no source path" >&2
310+ exit 1
311+ fi
312+ done
313+ echo "Valid: $PROJECT_NAME ($FUNCTIONS_LEN function(s))"
314+ ) || {
309315 echo "::error file=eclexiaiser.toml::Invalid eclexiaiser.toml — see step output for details"
310316 exit 1
311317 }
@@ -327,7 +333,7 @@ jobs:
327333 # ---------------------------------------------------------------------------
328334 dogfood-summary :
329335 name : Dogfooding compliance summary
330- runs-on : ubuntu-latest
336+ runs-on : ubuntu-24.04
331337 needs : [a2ml-validate, k9-validate, empty-lint, groove-check, eclexiaiser-validate]
332338 if : always()
333339
0 commit comments