Skip to content

[SETUP] Complete Repository Configuration - Post-PR#1 TasksΒ #2

@kevalyq

Description

@kevalyq

🎯 Objective

Complete repository setup according to SecPal standards after merging PR #1.

⚠️ CRITICAL: These steps MUST be completed before first production commit!


1️⃣ Create Symlinks (DRY Principle - MANDATORY)

WHY: Avoid duplication, single source of truth for governance files.

HOW:

cd ~/code/SecPal/frontend

# Governance files (symlinks to .github repo)
ln -sf ../.github/CONTRIBUTING.md .
ln -sf ../.github/SECURITY.md .
ln -sf ../.github/CODE_OF_CONDUCT.md .
ln -sf ../.github/CODEOWNERS .
ln -sf ../.github/.editorconfig .editorconfig
ln -sf ../.github/.gitattributes .gitattributes

# VALIDATION
file CONTRIBUTING.md  # MUST show: symbolic link to ../.github/CONTRIBUTING.md
file SECURITY.md      # MUST show: symbolic link to ../.github/SECURITY.md
file CODE_OF_CONDUCT.md  # MUST show: symbolic link
file CODEOWNERS       # MUST show: symbolic link
file .editorconfig    # MUST show: symbolic link
file .gitattributes   # MUST show: symbolic link

# Commit symlinks
git add CONTRIBUTING.md SECURITY.md CODE_OF_CONDUCT.md CODEOWNERS .editorconfig .gitattributes
git commit -m "feat: add symlinks to governance files (DRY principle)"
git push origin main

2️⃣ Create LICENSES/ Directory

cd ~/code/SecPal/frontend

mkdir -p LICENSES
cp ../.github/LICENSES/AGPL-3.0-or-later.txt LICENSES/
cp ../.github/LICENSES/CC0-1.0.txt LICENSES/
cp ../.github/LICENSES/MIT.txt LICENSES/

git add LICENSES/
git commit -m "feat: add license files for REUSE compliance"
git push origin main

3️⃣ Add GitHub Workflows

Create .github/workflows/ directory and add the following files:

.github/workflows/reuse.yml

Click to expand
# SPDX-FileCopyrightText: 2025 SecPal
# SPDX-License-Identifier: AGPL-3.0-or-later

name: REUSE Compliance

on:
  pull_request:
    branches:
      - main
  push:
    branches:
      - main

permissions:
  contents: read

jobs:
  reuse:
    name: Check REUSE Compliance
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v5

      - name: REUSE Compliance Check
        uses: fsfe/reuse-action@v6

.github/workflows/license-compatibility.yml

Click to expand

Copy from: SecPal/.github/.github/workflows/license-compatibility.yml

.github/workflows/quality.yml

Click to expand
# SPDX-FileCopyrightText: 2025 SecPal
# SPDX-License-Identifier: AGPL-3.0-or-later

name: Quality Gates

on:
  pull_request:
    branches:
      - main
  push:
    branches:
      - main

permissions:
  contents: read

jobs:
  formatting:
    name: Formatting Check
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v5

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "20"
          cache: "npm"

      - name: Install dependencies
        run: npm ci

      - name: Check formatting with Prettier
        run: npm run format:check

      - name: Lint Markdown
        run: npx markdownlint-cli2 "**/*.md"

  actionlint:
    name: GitHub Actions Lint
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v5

      - name: Run actionlint
        uses: reviewdog/action-actionlint@v1
        with:
          level: error

  lint:
    name: ESLint
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v5

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "20"
          cache: "npm"

      - name: Install dependencies
        run: npm ci

      - name: Run ESLint
        run: npm run lint

  typecheck:
    name: TypeScript Check
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v5

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "20"
          cache: "npm"

      - name: Install dependencies
        run: npm ci

      - name: Run TypeScript type checking
        run: npm run typecheck

  test:
    name: Vitest Tests
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v5

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "20"
          cache: "npm"

      - name: Install dependencies
        run: npm ci

      - name: Run tests
        run: npm test

      - name: Generate coverage report
        run: npm run test:coverage

      - name: Upload coverage to artifacts
        uses: actions/upload-artifact@v4
        with:
          name: coverage
          path: coverage/

  pr-size:
    name: PR Size Check
    runs-on: ubuntu-latest
    if: github.event_name == 'pull_request'
    steps:
      - name: Checkout repository
        uses: actions/checkout@v5
        with:
          fetch-depth: 0

      - name: Check PR size
        run: |
          BASE_BRANCH="${{ github.base_ref }}"
          HEAD_BRANCH="${{ github.head_ref }}"
          
          git fetch origin "$BASE_BRANCH"
          MERGE_BASE=$(git merge-base "origin/$BASE_BRANCH" HEAD)
          
          CHANGED=$(git diff --numstat "$MERGE_BASE"..HEAD | awk '{ins+=$1; del+=$2} END {print ins+del+0}')
          
          echo "Changed lines: $CHANGED"
          
          if [ "$CHANGED" -gt 600 ]; then
            echo "::error::PR too large ($CHANGED > 600 lines). Please split into smaller PRs."
            exit 1
          fi
          
          echo "::notice::PR size OK ($CHANGED lines)"

.github/workflows/codeql.yml

Click to expand
# SPDX-FileCopyrightText: 2025 SecPal
# SPDX-License-Identifier: AGPL-3.0-or-later

name: CodeQL Analysis

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  schedule:
    - cron: "0 4 * * 1" # Weekly on Monday at 04:00 CET

permissions:
  security-events: write
  contents: read

jobs:
  analyze:
    name: Analyze with CodeQL
    runs-on: ubuntu-latest

    strategy:
      fail-fast: false
      matrix:
        language: ["javascript-typescript"]

    steps:
      - name: Checkout repository
        uses: actions/checkout@v5

      - name: Initialize CodeQL
        uses: github/codeql-action/init@v3
        with:
          languages: ${{ matrix.language }}

      - name: Perform CodeQL Analysis
        uses: github/codeql-action/analyze@v3
        with:
          category: "/language:${{ matrix.language }}"

Commit:

git add .github/workflows/
git commit -m "feat: add GitHub Actions workflows (REUSE, Quality, CodeQL)"
git push origin main

4️⃣ Dependabot Configuration

Create .github/dependabot.yml:

# SPDX-FileCopyrightText: 2025 SecPal
# SPDX-License-Identifier: CC0-1.0

version: 2
updates:
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "daily"
      time: "04:00"
      timezone: "Europe/Berlin"
    open-pull-requests-limit: 10
    reviewers:
      - "SecPal/maintainers"
    labels:
      - "dependencies"
      - "dependabot"

  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly"
      day: "monday"
      time: "04:00"
      timezone: "Europe/Berlin"
    open-pull-requests-limit: 5
    reviewers:
      - "SecPal/maintainers"
    labels:
      - "dependencies"
      - "dependabot"
      - "github-actions"

Commit:

git add .github/dependabot.yml
git commit -m "feat: add Dependabot configuration (daily npm, weekly actions)"
git push origin main

5️⃣ ESLint Configuration

Create eslint.config.js:

// SPDX-FileCopyrightText: 2025 SecPal
// SPDX-License-Identifier: CC0-1.0

import js from "@eslint/js";
import globals from "globals";
import reactHooks from "eslint-plugin-react-hooks";
import reactRefresh from "eslint-plugin-react-refresh";
import tseslint from "typescript-eslint";

export default tseslint.config(
  { ignores: ["dist"] },
  {
    extends: [js.configs.recommended, ...tseslint.configs.recommended],
    files: ["**/*.{ts,tsx}"],
    languageOptions: {
      ecmaVersion: 2020,
      globals: globals.browser,
    },
    plugins: {
      "react-hooks": reactHooks,
      "react-refresh": reactRefresh,
    },
    rules: {
      ...reactHooks.configs.recommended.rules,
      "react-refresh/only-export-components": [
        "warn",
        { allowConstantExport: true },
      ],
    },
  }
);

Update package.json to add missing ESLint dependencies:

npm install --save-dev globals typescript-eslint

Commit:

git add eslint.config.js package.json package-lock.json
git commit -m "feat: add ESLint configuration with React + TypeScript rules"
git push origin main

6️⃣ Copilot Instructions

Create .github/copilot-instructions.md:

Copy complete content from:
SecPal/.github/.github/instructions/frontend.instructions.md

Commit:

git add .github/copilot-instructions.md
git commit -m "feat: add Copilot instructions for frontend development"
git push origin main

7️⃣ Enable Branch Protection (CRITICAL)

Via GitHub CLI:

gh api repos/SecPal/frontend/branches/main/protection \
  --method PUT \
  --field required_status_checks='{"strict":true,"contexts":["Check REUSE Compliance","Formatting Check","GitHub Actions Lint","ESLint","TypeScript Check","Vitest Tests","Check License Compatibility","Analyze with CodeQL"]}' \
  --field enforce_admins=true \
  --field required_pull_request_reviews='{"required_approving_review_count":0,"require_code_owner_reviews":false}' \
  --field required_linear_history=true \
  --field allow_force_pushes=false \
  --field allow_deletions=false \
  --field required_conversation_resolution=true \
  --field restrictions=null

Via GitHub UI:

  1. Go to Settings β†’ Branches
  2. Click Add rule
  3. Branch name pattern: main
  4. Enable:
    • βœ… Require a pull request before merging
    • βœ… Require status checks to pass before merging
      • βœ… Require branches to be up to date before merging
      • Add status checks:
        • Check REUSE Compliance
        • Formatting Check
        • GitHub Actions Lint
        • ESLint
        • TypeScript Check
        • Vitest Tests
        • Check License Compatibility
        • Analyze with CodeQL
    • βœ… Require conversation resolution before merging
    • βœ… Require signed commits
    • βœ… Require linear history
    • βœ… Do not allow bypassing the above settings (enforce admins)
    • βœ… Restrict who can push to matching branches (leave empty for admins-only)

8️⃣ Configure Repository Settings

General Settings

Settings β†’ General β†’ Pull Requests:

  • βœ… Allow squash merging (ENABLE)
  • ❌ Allow merge commits (DISABLE)
  • ❌ Allow rebase merging (DISABLE)
  • βœ… Automatically delete head branches (ENABLE)

Security Settings

Settings β†’ Security β†’ Code security and analysis:

  • βœ… Dependency graph (should be enabled by default)
  • βœ… Dependabot alerts (ENABLE)
  • βœ… Dependabot security updates (ENABLE)
  • βœ… Grouped security updates (ENABLE)
  • βœ… Secret scanning (ENABLE)
  • βœ… Push protection (ENABLE)
  • βœ… CodeQL analysis (automatically enabled via workflow)

9️⃣ Team & CODEOWNERS Setup

Create GitHub Team (if not exists):

gh api orgs/SecPal/teams -f name="maintainers" -f privacy="secret"

Add yourself to team:

gh api orgs/SecPal/teams/maintainers/memberships/kevalyq -f role="maintainer"

βœ… Validation Checklist

Run these commands to verify setup:

cd ~/code/SecPal/frontend

# 1. Verify symlinks
file CONTRIBUTING.md | grep "symbolic link"
file SECURITY.md | grep "symbolic link"
file CODE_OF_CONDUCT.md | grep "symbolic link"
file CODEOWNERS | grep "symbolic link"
file .editorconfig | grep "symbolic link"
file .gitattributes | grep "symbolic link"

# 2. Verify LICENSES
ls -la LICENSES/ | grep -E "(AGPL-3.0-or-later|CC0-1.0|MIT).txt"

# 3. Verify workflows
ls -la .github/workflows/ | grep -E "(reuse|license-compatibility|quality|codeql|dependabot-auto-merge).yml"

# 4. Run REUSE lint
reuse lint

# 5. Run preflight script
./scripts/preflight.sh

# 6. Verify npm scripts work
npm install
npm run lint
npm run typecheck
npm test
npm run format:check

# 7. Verify git hooks
./scripts/setup-pre-commit.sh
ls -la .git/hooks/ | grep pre-push

πŸ“š References


⚠️ CRITICAL REMINDER

ZERO EXCEPTIONS:

  1. All symlinks MUST be created (no plain files)
  2. Branch protection MUST have enforce_admins: true
  3. All workflows MUST have permissions: contents: read (or more restrictive)
  4. Secret scanning + push protection MUST be enabled
  5. Squash merge ONLY (no merge commits, no rebase)

Failure to comply = Repository setup incomplete = Production deployment blocked.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions