diff --git a/.github/workflows/dogfood-gate.yml b/.github/workflows/dogfood-gate.yml index bc802c7..9cac50a 100644 --- a/.github/workflows/dogfood-gate.yml +++ b/.github/workflows/dogfood-gate.yml @@ -22,7 +22,7 @@ jobs: # --------------------------------------------------------------------------- a2ml-validate: name: Validate A2ML manifests - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 timeout-minutes: 15 steps: @@ -67,7 +67,7 @@ jobs: # --------------------------------------------------------------------------- k9-validate: name: Validate K9 contracts - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 timeout-minutes: 15 steps: @@ -117,7 +117,7 @@ jobs: # --------------------------------------------------------------------------- empty-lint: name: Empty-linter (invisible characters) - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 timeout-minutes: 15 steps: @@ -182,7 +182,7 @@ jobs: # --------------------------------------------------------------------------- groove-check: name: Groove manifest check - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 timeout-minutes: 15 steps: @@ -241,7 +241,7 @@ jobs: # --------------------------------------------------------------------------- eclexiaiser-validate: name: Validate eclexiaiser manifest - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 timeout-minutes: 15 steps: @@ -262,28 +262,34 @@ jobs: echo "has_manifest=true" >> "$GITHUB_OUTPUT" - # Validate TOML structure using Python 3.11+ tomllib - python3 -c " - import tomllib, sys - with open('eclexiaiser.toml', 'rb') as f: - data = tomllib.load(f) - project = data.get('project', {}) - if not project.get('name', '').strip(): - print('ERROR: project.name is required', file=sys.stderr) - sys.exit(1) - functions = data.get('functions', []) - if not functions: - print('ERROR: at least one [[functions]] entry is required', file=sys.stderr) - sys.exit(1) - for fn in functions: - if not fn.get('name', '').strip(): - print('ERROR: function name cannot be empty', file=sys.stderr) - sys.exit(1) - if not fn.get('source', '').strip(): - print(f'ERROR: function {fn[\"name\"]} has no source path', file=sys.stderr) - sys.exit(1) - print(f'Valid: {project[\"name\"]} ({len(functions)} function(s))') - " || { + # Validate TOML structure using pre-installed yq + ( + PROJECT_NAME=$(yq -e '.project.name // ""' eclexiaiser.toml) + if [ -z "$PROJECT_NAME" ]; then + echo "ERROR: project.name is required" >&2 + exit 1 + fi + + FUNCTIONS_LEN=$(yq -e '.functions | length' eclexiaiser.toml) + if [ -z "$FUNCTIONS_LEN" ] || [ "$FUNCTIONS_LEN" -eq 0 ]; then + echo "ERROR: at least one [[functions]] entry is required" >&2 + exit 1 + fi + + for i in $(seq 0 $((FUNCTIONS_LEN - 1))); do + FN_NAME=$(yq -e ".functions[$i].name // \"\"" eclexiaiser.toml) + if [ -z "$FN_NAME" ]; then + echo "ERROR: function name cannot be empty" >&2 + exit 1 + fi + FN_SRC=$(yq -e ".functions[$i].source // \"\"" eclexiaiser.toml) + if [ -z "$FN_SRC" ]; then + echo "ERROR: function $FN_NAME has no source path" >&2 + exit 1 + fi + done + echo "Valid: $PROJECT_NAME ($FUNCTIONS_LEN function(s))" + ) || { echo "::error file=eclexiaiser.toml::Invalid eclexiaiser.toml — see step output for details" exit 1 } @@ -305,7 +311,7 @@ jobs: # --------------------------------------------------------------------------- dogfood-summary: name: Dogfooding compliance summary - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 timeout-minutes: 15 needs: [a2ml-validate, k9-validate, empty-lint, groove-check, eclexiaiser-validate] if: always() diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 8669254..99da11e 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -7,9 +7,9 @@ on: workflow_dispatch: permissions: - actions: read contents: read - + security-events: write + id-token: write jobs: scorecard: uses: hyperpolymath/standards/.github/workflows/scorecard-reusable.yml@7fdc2705df74b4e352d2a1cde3e87a5923fdf329 diff --git a/.github/workflows/secret-scanner.yml b/.github/workflows/secret-scanner.yml index 995692b..6a2e53a 100644 --- a/.github/workflows/secret-scanner.yml +++ b/.github/workflows/secret-scanner.yml @@ -8,7 +8,6 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true permissions: - actions: read contents: read jobs: scan: diff --git a/.mise.toml b/.mise.toml new file mode 100644 index 0000000..db3d9ee --- /dev/null +++ b/.mise.toml @@ -0,0 +1,2 @@ +[tools] +elixir = "1.19.5-otp-28" diff --git a/.tool-versions b/.tool-versions deleted file mode 100644 index 2f7c62e..0000000 --- a/.tool-versions +++ /dev/null @@ -1 +0,0 @@ -elixir 1.19.5-otp-28