diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml new file mode 100644 index 0000000..cea7d8d --- /dev/null +++ b/.github/workflows/code-quality.yml @@ -0,0 +1,116 @@ +name: Code Quality + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + lint: + name: ESLint + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '18' + cache: 'yarn' + + - name: Install dependencies + run: yarn install --frozen-lockfile + + - name: Run ESLint + run: yarn eslint src/ --ext .ts --max-warnings 0 + continue-on-error: true + + format: + name: Prettier + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '18' + cache: 'yarn' + + - name: Install dependencies + run: yarn install --frozen-lockfile + + - name: Check formatting + run: yarn prettier --check "src/**/*.ts" + + typecheck: + name: TypeScript + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '18' + cache: 'yarn' + + - name: Install dependencies + run: yarn install --frozen-lockfile + + - name: Generate types + run: yarn codegen + + - name: TypeScript check + run: yarn tsc --noEmit + + complexity: + name: Code Complexity + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '18' + + - name: Install complexity checker + run: npm install -g complexity-report + + - name: Check complexity + run: | + cr src/**/*.ts --format json > complexity-report.json || true + HIGH_COMPLEXITY=$(cat complexity-report.json 2>/dev/null | jq '[.reports[].functions[] | select(.cyclomatic > 15)] | length' 2>/dev/null || echo "0") + if [ "$HIGH_COMPLEXITY" -gt 0 ]; then + echo "::warning::Found $HIGH_COMPLEXITY functions with cyclomatic complexity > 15" + fi + + duplicate-code: + name: Duplicate Code Detection + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '18' + + - name: Install jscpd + run: npm install -g jscpd + + - name: Check for duplicates + run: jscpd src/ --min-lines 10 --min-tokens 50 --threshold 5 + continue-on-error: true diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml new file mode 100644 index 0000000..7b6b8f9 --- /dev/null +++ b/.github/workflows/security.yml @@ -0,0 +1,102 @@ +name: Security + +on: + push: + branches: [main] + pull_request: + branches: [main] + schedule: + - cron: '0 6 * * 1' + +permissions: + contents: read + security-events: write + +jobs: + codeql: + name: CodeQL Analysis + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: typescript + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '18' + cache: 'yarn' + + - name: Install dependencies + run: yarn install --frozen-lockfile + + - name: Build + run: yarn build + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + + dependency-audit: + name: Dependency Audit + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '18' + cache: 'yarn' + + - name: Install dependencies + run: yarn install --frozen-lockfile + + - name: Run npm audit + run: yarn npm audit --all --recursive || true + + - name: Check for critical vulnerabilities + run: | + CRITICAL=$(yarn npm audit --all --recursive --json 2>/dev/null | jq '[.advisories // {} | to_entries[] | select(.value.severity == "critical")] | length' 2>/dev/null || echo "0") + if [ "$CRITICAL" -gt 0 ]; then + echo "::error::Found $CRITICAL critical vulnerabilities" + exit 1 + fi + + dependency-review: + name: Dependency Review + runs-on: ubuntu-latest + if: github.event_name == 'pull_request' + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Dependency Review + uses: actions/dependency-review-action@v4 + with: + fail-on-severity: high + deny-licenses: GPL-3.0, AGPL-3.0 + + secret-scan: + name: Secret Scan + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: TruffleHog Secret Scan + uses: trufflesecurity/trufflehog@main + with: + path: ./ + base: ${{ github.event.repository.default_branch }} + extra_args: --only-verified