diff --git a/.github/workflows/cargo-audit.yml b/.github/workflows/cargo-audit.yml index bf6fd47c..19424271 100644 --- a/.github/workflows/cargo-audit.yml +++ b/.github/workflows/cargo-audit.yml @@ -21,23 +21,35 @@ jobs: audit: name: Dependency audit runs-on: ubuntu-latest - if: hashFiles('Cargo.lock') != '' steps: - name: Checkout repository uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + - name: Detect Cargo.lock + id: detect + run: | + if [ -f Cargo.lock ]; then + echo "present=true" >> "$GITHUB_OUTPUT" + else + echo "present=false" >> "$GITHUB_OUTPUT" + echo "No Cargo.lock — skipping dependency audit." >> "$GITHUB_STEP_SUMMARY" + fi + - name: Install Rust toolchain + if: steps.detect.outputs.present == 'true' uses: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable - name: Install cargo-audit + if: steps.detect.outputs.present == 'true' run: cargo install cargo-audit --locked - name: Run cargo audit + if: steps.detect.outputs.present == 'true' run: cargo audit - name: Write summary - if: always() + if: always() && steps.detect.outputs.present == 'true' run: | echo "## Cargo Audit Results" >> "$GITHUB_STEP_SUMMARY" echo "" >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/dogfood-gate.yml b/.github/workflows/dogfood-gate.yml index 680b1b25..501ee675 100644 --- a/.github/workflows/dogfood-gate.yml +++ b/.github/workflows/dogfood-gate.yml @@ -256,31 +256,37 @@ 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 Python 3.11+ tomllib. + # The Python heredoc body sits at the YAML block-scalar base + # indentation, so after GitHub strips the block's common indent + # the interpreter receives it column-aligned (no sed dedent — + # a sed-based dedent breaks because YAML removes the block's + # leading indent before the script ever reaches the shell). + if ! python3 - <<'PY' + 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))') + PY + then echo "::error file=eclexiaiser.toml::Invalid eclexiaiser.toml — see step output for details" exit 1 - } + fi - name: Write summary run: | diff --git a/.github/workflows/secret-scanner.yml b/.github/workflows/secret-scanner.yml index fd62c4f8..352ab8dc 100644 --- a/.github/workflows/secret-scanner.yml +++ b/.github/workflows/secret-scanner.yml @@ -38,11 +38,21 @@ jobs: # Rust-specific: Check for hardcoded crypto values rust-secrets: runs-on: ubuntu-latest - if: hashFiles('**/Cargo.toml') != '' steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + - name: Detect Rust sources + id: detect + run: | + if find . -name Cargo.toml -print -quit | grep -q .; then + echo "present=true" >> "$GITHUB_OUTPUT" + else + echo "present=false" >> "$GITHUB_OUTPUT" + echo "No Cargo.toml — skipping Rust secret heuristics." >> "$GITHUB_STEP_SUMMARY" + fi + - name: Check for hardcoded secrets in Rust + if: steps.detect.outputs.present == 'true' run: | # Patterns that suggest hardcoded secrets PATTERNS=(