ci: implement comprehensive CI/CD and workflow automation

- Add GitHub Actions workflows for CI, release, and deployment
- Configure Renovate for automated dependency updates
- Set up Husky pre-commit hooks with lint-staged
- Add commitlint for enforcing Conventional Commits
- Configure semantic-release for automated versioning
- Add Prettier configuration for consistent formatting
- Reformat codebase with new formatting rules
This commit is contained in:
2025-10-22 02:45:58 -05:00
parent 2c1f882cd9
commit c17f733da1
48 changed files with 5453 additions and 2422 deletions

85
.github/renovate.json vendored Normal file
View File

@@ -0,0 +1,85 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:recommended",
":dependencyDashboard",
":semanticCommits",
":automergeDigest",
":automergeMinor"
],
"schedule": ["after 10pm every weekday", "before 5am every weekday", "every weekend"],
"timezone": "America/Chicago",
"prConcurrentLimit": 3,
"prCreation": "not-pending",
"rebaseWhen": "behind-base-branch",
"semanticCommitScope": "deps",
"vulnerabilityAlerts": {
"labels": ["security"],
"automerge": true,
"schedule": ["at any time"]
},
"packageRules": [
{
"description": "Automerge dev dependencies",
"matchDepTypes": ["devDependencies"],
"automerge": true,
"automergeType": "pr",
"minimumReleaseAge": "3 days"
},
{
"description": "Automerge TypeScript type packages",
"matchPackagePatterns": ["^@types/"],
"automerge": true,
"automergeType": "pr"
},
{
"description": "Group ESLint packages together",
"matchPackagePatterns": ["^eslint", "^@typescript-eslint/"],
"groupName": "eslint packages",
"automerge": true
},
{
"description": "Group testing packages together",
"matchPackagePatterns": ["^vitest", "^@vitest/", "^@testing-library/"],
"groupName": "testing packages",
"automerge": true
},
{
"description": "Group Next.js related packages",
"matchPackageNames": ["next", "eslint-config-next"],
"groupName": "Next.js packages",
"minimumReleaseAge": "7 days"
},
{
"description": "Group React packages",
"matchPackageNames": ["react", "react-dom", "@types/react", "@types/react-dom"],
"groupName": "React packages",
"minimumReleaseAge": "7 days"
},
{
"description": "Pin Node.js major versions",
"matchPackageNames": ["node"],
"enabled": false
},
{
"description": "Group Tailwind CSS packages",
"matchPackagePatterns": [
"^tailwindcss",
"^@tailwindcss/",
"prettier-plugin-tailwindcss"
],
"groupName": "Tailwind CSS packages"
},
{
"description": "Group font packages",
"matchPackagePatterns": ["^@fontsource"],
"groupName": "font packages",
"automerge": true
}
],
"postUpdateOptions": ["pnpmDedupe"],
"lockFileMaintenance": {
"enabled": true,
"schedule": ["before 5am on monday"]
}
}

165
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,165 @@
name: CI
on:
push:
branches: [master]
pull_request:
branches: [master]
env:
NODE_VERSION: "20"
PNPM_VERSION: "9.0.0"
jobs:
# Code quality checks
quality:
name: Code Quality
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: "pnpm"
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Run linting
run: pnpm lint
- name: Type checking
run: pnpm type-check
- name: Check formatting
run: pnpm prettier --check .
# Testing
test:
name: Test Suite
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: "pnpm"
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Run unit tests
run: pnpm test:run
- name: Run integration tests
run: pnpm test:integration
- name: Upload coverage
uses: codecov/codecov-action@v4
if: always()
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./coverage/coverage-final.json
flags: unittests
name: codecov-umbrella
fail_ci_if_error: false
# Build verification
build:
name: Build Application
needs: [quality, test]
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: "pnpm"
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build application
run: pnpm build
env:
NODE_ENV: production
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: next-build
path: |
.next/
out/
retention-days: 7
if-no-files-found: warn
# Security scanning
security:
name: Security Scan
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: "pnpm"
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Run security audit
run: pnpm audit --audit-level=moderate
continue-on-error: true
- name: Check for known vulnerabilities
uses: aquasecurity/trivy-action@master
with:
scan-type: "fs"
scan-ref: "."
format: "sarif"
output: "trivy-results.sarif"
severity: "CRITICAL,HIGH"
exit-code: 0
- name: Upload Trivy results
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: "trivy-results.sarif"

71
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,71 @@
name: Release
on:
push:
branches:
- master
permissions:
contents: write
issues: write
pull-requests: write
jobs:
release:
name: Create Release
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false
- name: Check for skip ci
id: check_skip
run: |
if git log -1 --pretty=%B | grep -q '\[skip ci\]'; then
echo "skip=true" >> $GITHUB_OUTPUT
else
echo "skip=false" >> $GITHUB_OUTPUT
fi
- name: Setup pnpm
if: steps.check_skip.outputs.skip == 'false'
uses: pnpm/action-setup@v4
with:
version: 9.0.0
- name: Setup Node.js
if: steps.check_skip.outputs.skip == 'false'
uses: actions/setup-node@v4
with:
node-version: 20
cache: "pnpm"
- name: Install dependencies
if: steps.check_skip.outputs.skip == 'false'
run: pnpm install --frozen-lockfile
- name: Build application
if: steps.check_skip.outputs.skip == 'false'
run: pnpm build
env:
NODE_ENV: production
- name: Run semantic release
if: steps.check_skip.outputs.skip == 'false'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: pnpm semantic-release
- name: Upload release artifacts
if: steps.check_skip.outputs.skip == 'false'
uses: actions/upload-artifact@v4
with:
name: release-build
path: |
.next/
out/
retention-days: 30