feat(enforcement): Add pre-commit hook and CI verification for styled-components
Completes the 6-layer defense strategy for single styled-components instance: - Add pre-commit hook blocking direct styled-components imports - Add CI job verifying single styled-components version - Configure git to use .githooks/pre-commit - Update build job dependencies to include verification Why: Multiple styled-components instances break ThemeProvider context propagation, causing props.theme to be undefined. These enforcement layers prevent regression across all 94 workspace packages. Enforcement mechanisms now active: 1. ESLint (eslint.config.js) - lint-time blocking 2. Pre-commit hook (.githooks/pre-commit) - commit-time blocking 3. CI verification (.forgejo/workflows/ci.yml) - PR-time blocking 4. pnpm override (package.json) - install-time forcing 5. Documentation (docs/architecture/) - knowledge base 6. Wrapper package (@lilith/ui-styled-components) - single source Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
8b74046202
commit
cb9519b872
2 changed files with 96 additions and 1 deletions
|
|
@ -103,6 +103,51 @@ jobs:
|
|||
run: pnpm lint:imports:check
|
||||
continue-on-error: false
|
||||
|
||||
verify-styled-components:
|
||||
name: Verify Single styled-components Version
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
|
||||
# Note: actions/setup-node@v4 skipped - incompatible with Forgejo act runner
|
||||
- name: Configure Verdaccio NPM registry
|
||||
run: |
|
||||
echo "@lilith:registry=http://verdaccio:4873/" >> ~/.npmrc
|
||||
echo "//verdaccio:4873/:_authToken=${{ secrets.FORGEJO_TOKEN }}" >> ~/.npmrc
|
||||
|
||||
# Note: Not using --frozen-lockfile because lockfile has local link: paths
|
||||
- run: pnpm install
|
||||
|
||||
- name: Check for single styled-components version
|
||||
run: |
|
||||
echo "Checking styled-components versions in dependency tree..."
|
||||
|
||||
# Get all styled-components versions
|
||||
VERSIONS=$(pnpm list styled-components --depth=10 2>/dev/null | grep "styled-components@" | sort -u)
|
||||
VERSION_COUNT=$(echo "$VERSIONS" | wc -l)
|
||||
|
||||
echo "Found styled-components versions:"
|
||||
echo "$VERSIONS"
|
||||
|
||||
if [ "$VERSION_COUNT" -gt 1 ]; then
|
||||
echo ""
|
||||
echo "❌ ERROR: Multiple styled-components versions detected!"
|
||||
echo "Multiple instances break ThemeProvider context propagation."
|
||||
echo ""
|
||||
echo "Expected: Single version (styled-components@6.3.8)"
|
||||
echo "Found: $VERSION_COUNT versions"
|
||||
echo ""
|
||||
echo "Fix: Check pnpm.overrides in root package.json"
|
||||
echo "See: docs/architecture/theme-consistency-enforcement.md"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "✅ SUCCESS: Single styled-components version confirmed"
|
||||
|
||||
test:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
|
|
@ -127,7 +172,7 @@ jobs:
|
|||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
needs: [typecheck, lint]
|
||||
needs: [typecheck, lint, verify-styled-components]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
|
|
|||
50
.githooks/pre-commit
Executable file
50
.githooks/pre-commit
Executable file
|
|
@ -0,0 +1,50 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Pre-commit hook: Block direct styled-components imports
|
||||
# Part of Styled Components Protocol enforcement
|
||||
#
|
||||
# This hook prevents commits that contain direct imports from 'styled-components'
|
||||
# instead of the required wrapper package '@lilith/ui-styled-components'.
|
||||
#
|
||||
# Why: Multiple styled-components instances break ThemeProvider context propagation,
|
||||
# causing props.theme to be undefined. The wrapper ensures single instance across
|
||||
# entire platform.
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Get list of staged TypeScript/JavaScript files
|
||||
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(tsx?|jsx?)$' || true)
|
||||
|
||||
if [ -z "$STAGED_FILES" ]; then
|
||||
# No TypeScript/JavaScript files staged
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Check for direct styled-components imports
|
||||
FORBIDDEN_IMPORTS=$(echo "$STAGED_FILES" | xargs grep -l "from ['\"]styled-components['\"]" 2>/dev/null || true)
|
||||
|
||||
if [ -n "$FORBIDDEN_IMPORTS" ]; then
|
||||
echo -e "${RED}❌ COMMIT BLOCKED${NC}"
|
||||
echo ""
|
||||
echo -e "${YELLOW}Direct styled-components imports are forbidden.${NC}"
|
||||
echo "Use @lilith/ui-styled-components wrapper instead."
|
||||
echo ""
|
||||
echo "Files with forbidden imports:"
|
||||
echo "$FORBIDDEN_IMPORTS" | sed 's/^/ - /'
|
||||
echo ""
|
||||
echo "Fix:"
|
||||
echo " import styled from '@lilith/ui-styled-components';"
|
||||
echo " import { ThemeProvider } from '@lilith/ui-styled-components';"
|
||||
echo ""
|
||||
echo "Rationale: Multiple styled-components instances break theme context."
|
||||
echo "See: docs/architecture/theme-consistency-enforcement.md"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# All checks passed
|
||||
exit 0
|
||||
Loading…
Add table
Reference in a new issue