Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .githooks/pre-push
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env bash
# Pre-push hook: run gitleaks to detect secrets before pushing.
# Install: git config core.hooksPath .githooks
set -euo pipefail

if ! command -v gitleaks &>/dev/null; then
echo "gitleaks not found — skipping secret scan (install from https://github.com/gitleaks/gitleaks)"
exit 0
fi

echo "Running gitleaks secret scan..."
gitleaks protect --staged --config .gitleaks.toml --verbose
130 changes: 130 additions & 0 deletions .github/workflows/license-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
name: License Compliance Check

on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]

jobs:
rust-licenses-contracts:
name: Rust License Check — contracts/predict-iq
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install Rust
uses: dtolnay/rust-toolchain@stable

- name: Cache cargo registry
uses: actions/cache@v5
with:
path: |
~/.cargo/registry
~/.cargo/git
key: ${{ runner.os }}-cargo-deny-contracts-${{ hashFiles('**/Cargo.lock') }}

- name: Install cargo-deny
run: cargo install cargo-deny --locked

- name: Check licenses — contracts workspace
run: cargo deny check licenses
working-directory: contracts/predict-iq

rust-licenses-api:
name: Rust License Check — services/api
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install Rust
uses: dtolnay/rust-toolchain@stable

- name: Cache cargo registry
uses: actions/cache@v5
with:
path: |
~/.cargo/registry
~/.cargo/git
key: ${{ runner.os }}-cargo-deny-api-${{ hashFiles('services/api/Cargo.lock') }}

- name: Install cargo-deny
run: cargo install cargo-deny --locked

- name: Check licenses — services/api
run: cargo deny check licenses
working-directory: services/api

npm-licenses-frontend:
name: NPM License Check — frontend
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: "18"
cache: "npm"
cache-dependency-path: frontend/package-lock.json

- name: Install dependencies
run: npm ci
working-directory: frontend

- name: Install license-checker
run: npm install -g license-checker

- name: Check licenses — frontend
run: |
license-checker \
--onlyAllow "$(node -e "
const cfg = require('./.license-checker.json');
process.stdout.write(cfg.onlyAllow.join(';'));
")" \
--excludePrivatePackages \
--production
working-directory: frontend

npm-licenses-tts:
name: NPM License Check — services/tts
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: "18"
cache: "npm"
cache-dependency-path: services/tts/package-lock.json

- name: Install dependencies
run: npm ci
working-directory: services/tts

- name: Install license-checker
run: npm install -g license-checker

- name: Check licenses — services/tts
run: |
license-checker \
--onlyAllow "$(node -e "
const cfg = require('./.license-checker.json');
process.stdout.write(cfg.onlyAllow.join(';'));
")" \
--excludePrivatePackages \
--production
working-directory: services/tts

all-license-checks-passed:
name: All License Checks Passed
needs:
- rust-licenses-contracts
- rust-licenses-api
- npm-licenses-frontend
- npm-licenses-tts
runs-on: ubuntu-latest
steps:
- name: Success
run: echo "All dependency licenses are compliant."
82 changes: 82 additions & 0 deletions .github/workflows/openapi-validation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
name: OpenAPI Spec Validation

on:
push:
branches: [main, develop]
paths:
- "services/api/openapi.yaml"
- "services/api/src/**"
- "services/api/tests/openapi_contract_test.rs"
pull_request:
branches: [main, develop]
paths:
- "services/api/openapi.yaml"
- "services/api/src/**"
- "services/api/tests/openapi_contract_test.rs"

jobs:
spectral-lint:
name: Spectral — OpenAPI structural lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: "18"

- name: Install Spectral
run: npm install -g @stoplight/spectral-cli

- name: Lint openapi.yaml
run: spectral lint services/api/openapi.yaml --ruleset @stoplight/spectral-oas

- name: Fail on errors
if: failure()
run: |
echo "Spectral found structural issues in services/api/openapi.yaml."
echo "Run 'spectral lint services/api/openapi.yaml --ruleset @stoplight/spectral-oas' locally to see details."
exit 1

contract-tests:
name: OpenAPI Contract Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install Rust
uses: dtolnay/rust-toolchain@stable

- name: Cache cargo dependencies
uses: actions/cache@v5
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-api-openapi-${{ hashFiles('services/api/Cargo.lock') }}

- name: Run OpenAPI contract tests
run: cargo test --test openapi_contract_test -- --nocapture
working-directory: services/api

- name: Fail if spec and routes diverge
if: failure()
run: |
echo "OpenAPI contract tests failed."
echo "The spec (services/api/openapi.yaml) and SPEC_ROUTES in"
echo "services/api/tests/openapi_contract_test.rs have diverged."
echo ""
echo "To fix:"
echo " 1. If you added/removed a route in Rust: update openapi.yaml to match."
echo " 2. If you updated openapi.yaml: update SPEC_ROUTES in the contract test."
exit 1

all-openapi-checks-passed:
name: All OpenAPI Checks Passed
needs: [spectral-lint, contract-tests]
runs-on: ubuntu-latest
steps:
- name: Success
run: echo "OpenAPI spec is valid and in sync with routes."
Loading