Skip to content

Commit fe9d9d7

Browse files
sylvansysclaude
andauthored
Comprehensive CI Architecture with Dependency Chain (#7)
* Add comprehensive CI architecture with dependency chain Implements new 4-workflow CI system: - Basic CI: Runs lint/typecheck/vitest on changed files for all commits to any branch - E2E Tests: Playwright tests with path filtering, blocked by Basic CI - Reviews: Orchestrates all 6 review types (requirements, rules, project-memory, agents, skills, playwright-ui) - Deployment CI: Monitors Vercel/Cloudflare/Supabase deployments (skips in repos without deployment config) Key features: - Changed-file detection for efficient CI (only checks edited files) - Clear dependency chain: Basic CI → E2E → Reviews → Deployment - Reviews run on every commit (not just PRs) - Deployment monitoring via platform APIs (not triggering) - Conditional execution based on .github/ci-config.yml Also: - Fix playwright-ui-review.yml npm cache error - Add changed-files composite action - Install github-context and project-context plugins 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Fix changed-files action bash syntax error Replace [[ ]] syntax with simpler [ -n ] tests to avoid syntax errors when COUNT contains newlines. Use clearer conditional logic for flags. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Fix reviews workflow: checkout before path filter Move actions/checkout@v4 before dorny/paths-filter@v3 for all review jobs. Path filter action requires git repository to be checked out first. Fixes: project-memory-review, agents-review, skills-review, playwright-ui-review 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 1d8d866 commit fe9d9d7

8 files changed

Lines changed: 2421 additions & 1 deletion

File tree

.claude/settings.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"enabledPlugins": {
3+
"github-context@constellos": true,
4+
"project-context@constellos": true
5+
}
6+
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
name: Detect Changed Files
2+
description: Smart file change detection for efficient CI
3+
4+
inputs:
5+
pattern:
6+
description: 'Regex pattern to filter files'
7+
required: false
8+
default: '.*'
9+
10+
outputs:
11+
changed_files:
12+
description: 'Newline-separated list of changed files'
13+
value: ${{ steps.detect.outputs.changed_files }}
14+
has_changes:
15+
description: 'Whether any matching files changed'
16+
value: ${{ steps.detect.outputs.has_changes }}
17+
file_count:
18+
description: 'Number of changed files'
19+
value: ${{ steps.detect.outputs.file_count }}
20+
has_ts_files:
21+
description: 'Whether any TypeScript files changed'
22+
value: ${{ steps.detect.outputs.has_ts_files }}
23+
has_test_files:
24+
description: 'Whether any test files changed'
25+
value: ${{ steps.detect.outputs.has_test_files }}
26+
ts_files:
27+
description: 'List of TypeScript files'
28+
value: ${{ steps.detect.outputs.ts_files }}
29+
test_files:
30+
description: 'List of test files'
31+
value: ${{ steps.detect.outputs.test_files }}
32+
33+
runs:
34+
using: composite
35+
steps:
36+
- name: Detect changed files
37+
id: detect
38+
shell: bash
39+
run: |
40+
# Get changed files based on event type
41+
if [ "${{ github.event_name }}" = "pull_request" ]; then
42+
CHANGED=$(git diff --name-only \
43+
${{ github.event.pull_request.base.sha }} \
44+
${{ github.sha }})
45+
elif [ "${{ github.event_name }}" = "push" ]; then
46+
if [ "${{ github.event.before }}" = "0000000000000000000000000000000000000000" ]; then
47+
# New branch
48+
CHANGED=$(git diff --name-only origin/main...HEAD 2>/dev/null || git ls-files)
49+
else
50+
CHANGED=$(git diff --name-only ${{ github.event.before }} ${{ github.sha }})
51+
fi
52+
else
53+
CHANGED=$(git diff --name-only HEAD~1 HEAD 2>/dev/null || git ls-files)
54+
fi
55+
56+
# Apply pattern filter
57+
PATTERN="${{ inputs.pattern }}"
58+
if [ "$PATTERN" != ".*" ]; then
59+
FILTERED=$(echo "$CHANGED" | grep -E "$PATTERN" || echo "")
60+
else
61+
FILTERED="$CHANGED"
62+
fi
63+
64+
# TypeScript files
65+
TS_FILES=$(echo "$CHANGED" | grep -E '\.(ts|tsx)$' || echo "")
66+
67+
# Test files
68+
TEST_FILES=$(echo "$CHANGED" | grep -E '\.(test|spec)\.(ts|tsx|js|jsx)$' || echo "")
69+
70+
# Count and flags
71+
if [ -n "$FILTERED" ]; then
72+
COUNT=$(echo "$FILTERED" | wc -l)
73+
HAS_CHANGES='true'
74+
else
75+
COUNT=0
76+
HAS_CHANGES='false'
77+
fi
78+
79+
if [ -n "$TS_FILES" ]; then
80+
HAS_TS='true'
81+
else
82+
HAS_TS='false'
83+
fi
84+
85+
if [ -n "$TEST_FILES" ]; then
86+
HAS_TESTS='true'
87+
else
88+
HAS_TESTS='false'
89+
fi
90+
91+
# Set outputs
92+
echo "changed_files<<EOF" >> $GITHUB_OUTPUT
93+
echo "$FILTERED" >> $GITHUB_OUTPUT
94+
echo "EOF" >> $GITHUB_OUTPUT
95+
96+
echo "ts_files<<EOF" >> $GITHUB_OUTPUT
97+
echo "$TS_FILES" >> $GITHUB_OUTPUT
98+
echo "EOF" >> $GITHUB_OUTPUT
99+
100+
echo "test_files<<EOF" >> $GITHUB_OUTPUT
101+
echo "$TEST_FILES" >> $GITHUB_OUTPUT
102+
echo "EOF" >> $GITHUB_OUTPUT
103+
104+
echo "has_changes=$HAS_CHANGES" >> $GITHUB_OUTPUT
105+
echo "file_count=$COUNT" >> $GITHUB_OUTPUT
106+
echo "has_ts_files=$HAS_TS" >> $GITHUB_OUTPUT
107+
echo "has_test_files=$HAS_TESTS" >> $GITHUB_OUTPUT

.github/ci-config.yml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# CI Configuration
2+
# Controls which CI workflows run in this repository
3+
4+
ci:
5+
# Basic CI (always enabled)
6+
basic:
7+
enabled: true
8+
lint: true
9+
typecheck: true
10+
vitest: true
11+
12+
# E2E Testing
13+
e2e:
14+
enabled: true
15+
framework: playwright
16+
17+
# Code Reviews (runs on every commit)
18+
reviews:
19+
enabled: true
20+
requirements: true
21+
rules: true
22+
project_memory: true
23+
agents: true
24+
skills: true
25+
playwright_ui: true
26+
27+
# Deployment CI (PR only)
28+
deployment:
29+
enabled: false
30+
31+
vercel:
32+
enabled: false
33+
34+
supabase:
35+
enabled: false
36+
37+
cloudflare:
38+
enabled: false

.github/workflows/basic-ci.yml

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
name: Basic CI
2+
3+
on:
4+
push:
5+
branches: ['**']
6+
pull_request:
7+
branches: ['**']
8+
merge_group:
9+
10+
concurrency:
11+
group: basic-ci-${{ github.ref }}
12+
cancel-in-progress: true
13+
14+
jobs:
15+
changed-files:
16+
name: Detect Changed Files
17+
runs-on: ubuntu-latest
18+
outputs:
19+
has_ts_files: ${{ steps.filter.outputs.has_ts_files }}
20+
has_test_files: ${{ steps.filter.outputs.has_test_files }}
21+
ts_files: ${{ steps.filter.outputs.ts_files }}
22+
test_files: ${{ steps.filter.outputs.test_files }}
23+
24+
steps:
25+
- uses: actions/checkout@v4
26+
with:
27+
fetch-depth: 0
28+
29+
- name: Get changed files
30+
id: filter
31+
uses: ./.github/actions/changed-files
32+
with:
33+
pattern: '\.(ts|tsx|js|jsx|test\.ts|test\.tsx)$'
34+
35+
lint:
36+
needs: changed-files
37+
if: needs.changed-files.outputs.has_ts_files == 'true'
38+
runs-on: ubuntu-latest
39+
steps:
40+
- uses: actions/checkout@v4
41+
- uses: constellos/.github/actions/lint@main
42+
with:
43+
files: ${{ needs.changed-files.outputs.ts_files }}
44+
45+
typecheck:
46+
needs: changed-files
47+
if: needs.changed-files.outputs.has_ts_files == 'true'
48+
runs-on: ubuntu-latest
49+
steps:
50+
- uses: actions/checkout@v4
51+
- uses: constellos/.github/actions/typecheck@main
52+
with:
53+
files: ${{ needs.changed-files.outputs.ts_files }}
54+
55+
vitest:
56+
needs: changed-files
57+
if: needs.changed-files.outputs.has_test_files == 'true'
58+
runs-on: ubuntu-latest
59+
steps:
60+
- uses: actions/checkout@v4
61+
- uses: constellos/.github/actions/unit-tests@main
62+
with:
63+
files: ${{ needs.changed-files.outputs.test_files }}

0 commit comments

Comments
 (0)