@@ -10,39 +10,177 @@ permissions:
1010 contents : read
1111
1212jobs :
13- check :
13+ # ── Stage 1: Install & cache ──────────────────────────────────────────
14+ install :
1415 runs-on : ubuntu-latest
1516 steps :
1617 - uses : actions/checkout@v4
1718 - uses : actions/setup-node@v4
1819 with :
1920 node-version : 22
20- cache : npm
21- cache-dependency-path : |
22- apps/desktop/package-lock.json
23- apps/mcp-server/package-lock.json
24- apps/web/package-lock.json
2521
26- - name : Install MCP server dependencies
27- run : cd apps/mcp-server && npm ci
22+ - name : Restore node_modules cache
23+ id : cache
24+ uses : actions/cache@v4
25+ with :
26+ path : |
27+ apps/desktop/node_modules
28+ apps/mcp-server/node_modules
29+ apps/web/node_modules
30+ key : nm-${{ hashFiles('apps/desktop/package-lock.json','apps/mcp-server/package-lock.json','apps/web/package-lock.json') }}
2831
29- - name : Install desktop dependencies
30- run : cd apps/desktop && npm ci
32+ - name : Install all dependencies (parallel)
33+ if : steps.cache.outputs.cache-hit != 'true'
34+ run : |
35+ cd apps/desktop && npm ci &
36+ cd apps/mcp-server && npm ci &
37+ cd apps/web && npm ci &
38+ wait
3139
32- - name : Install web dependencies
33- run : cd apps/web && npm ci
40+ # ── Stage 2: Parallel checks ──────────────────────────────────────────
41+ typecheck-desktop :
42+ needs : install
43+ runs-on : ubuntu-latest
44+ steps :
45+ - uses : actions/checkout@v4
46+ - uses : actions/setup-node@v4
47+ with :
48+ node-version : 22
49+ - uses : actions/cache/restore@v4
50+ with :
51+ path : |
52+ apps/desktop/node_modules
53+ apps/mcp-server/node_modules
54+ apps/web/node_modules
55+ key : nm-${{ hashFiles('apps/desktop/package-lock.json','apps/mcp-server/package-lock.json','apps/web/package-lock.json') }}
56+ - run : cd apps/desktop && npm run typecheck
3457
35- - name : Typecheck
36- run : cd apps/desktop && npm run typecheck
58+ typecheck-mcp :
59+ needs : install
60+ runs-on : ubuntu-latest
61+ steps :
62+ - uses : actions/checkout@v4
63+ - uses : actions/setup-node@v4
64+ with :
65+ node-version : 22
66+ - uses : actions/cache/restore@v4
67+ with :
68+ path : |
69+ apps/desktop/node_modules
70+ apps/mcp-server/node_modules
71+ apps/web/node_modules
72+ key : nm-${{ hashFiles('apps/desktop/package-lock.json','apps/mcp-server/package-lock.json','apps/web/package-lock.json') }}
73+ - run : cd apps/mcp-server && npm run typecheck
74+
75+ lint-desktop :
76+ needs : install
77+ runs-on : ubuntu-latest
78+ steps :
79+ - uses : actions/checkout@v4
80+ - uses : actions/setup-node@v4
81+ with :
82+ node-version : 22
83+ - uses : actions/cache/restore@v4
84+ with :
85+ path : |
86+ apps/desktop/node_modules
87+ apps/mcp-server/node_modules
88+ apps/web/node_modules
89+ key : nm-${{ hashFiles('apps/desktop/package-lock.json','apps/mcp-server/package-lock.json','apps/web/package-lock.json') }}
90+ - run : cd apps/desktop && npm run lint
91+
92+ test-desktop :
93+ needs : install
94+ runs-on : ubuntu-latest
95+ strategy :
96+ fail-fast : false
97+ matrix :
98+ shard : [1, 2, 3]
99+ steps :
100+ - uses : actions/checkout@v4
101+ - uses : actions/setup-node@v4
102+ with :
103+ node-version : 22
104+ - uses : actions/cache/restore@v4
105+ with :
106+ path : |
107+ apps/desktop/node_modules
108+ apps/mcp-server/node_modules
109+ apps/web/node_modules
110+ key : nm-${{ hashFiles('apps/desktop/package-lock.json','apps/mcp-server/package-lock.json','apps/web/package-lock.json') }}
111+ - run : cd apps/desktop && npx vitest run --shard=${{ matrix.shard }}/3
37112
38- - name : Test desktop
39- run : cd apps/desktop && npm test
113+ test-mcp :
114+ needs : install
115+ runs-on : ubuntu-latest
116+ steps :
117+ - uses : actions/checkout@v4
118+ - uses : actions/setup-node@v4
119+ with :
120+ node-version : 22
121+ - uses : actions/cache/restore@v4
122+ with :
123+ path : |
124+ apps/desktop/node_modules
125+ apps/mcp-server/node_modules
126+ apps/web/node_modules
127+ key : nm-${{ hashFiles('apps/desktop/package-lock.json','apps/mcp-server/package-lock.json','apps/web/package-lock.json') }}
128+ - run : cd apps/mcp-server && npm test
40129
41- - name : Test MCP server
42- run : cd apps/mcp-server && npm test
130+ build :
131+ needs : install
132+ runs-on : ubuntu-latest
133+ steps :
134+ - uses : actions/checkout@v4
135+ - uses : actions/setup-node@v4
136+ with :
137+ node-version : 22
138+ - uses : actions/cache/restore@v4
139+ with :
140+ path : |
141+ apps/desktop/node_modules
142+ apps/mcp-server/node_modules
143+ apps/web/node_modules
144+ key : nm-${{ hashFiles('apps/desktop/package-lock.json','apps/mcp-server/package-lock.json','apps/web/package-lock.json') }}
145+ - run : cd apps/desktop && npm run build
146+ - run : cd apps/mcp-server && npm run build
147+ - run : cd apps/web && npm run build
43148
44- - name : Build web
45- run : cd apps/web && npm run build
149+ validate-docs :
150+ needs : install
151+ runs-on : ubuntu-latest
152+ steps :
153+ - uses : actions/checkout@v4
154+ - uses : actions/setup-node@v4
155+ with :
156+ node-version : 22
157+ - uses : actions/cache/restore@v4
158+ with :
159+ path : |
160+ apps/desktop/node_modules
161+ apps/mcp-server/node_modules
162+ apps/web/node_modules
163+ key : nm-${{ hashFiles('apps/desktop/package-lock.json','apps/mcp-server/package-lock.json','apps/web/package-lock.json') }}
164+ - run : node scripts/validate-docs.mjs
46165
47- - name : Validate docs
48- run : node scripts/validate-docs.mjs
166+ # ── Gate: all jobs must pass ──────────────────────────────────────────
167+ ci-pass :
168+ if : always()
169+ needs :
170+ - typecheck-desktop
171+ - typecheck-mcp
172+ - lint-desktop
173+ - test-desktop
174+ - test-mcp
175+ - build
176+ - validate-docs
177+ runs-on : ubuntu-latest
178+ steps :
179+ - name : Check all jobs passed
180+ run : |
181+ if [[ "${{ contains(needs.*.result, 'failure') }}" == "true" ]] ||
182+ [[ "${{ contains(needs.*.result, 'cancelled') }}" == "true" ]]; then
183+ echo "::error::One or more required jobs failed or were cancelled"
184+ exit 1
185+ fi
186+ echo "All CI jobs passed"
0 commit comments