1+ name : Nx Smart Deploy
2+
3+ on :
4+ push :
5+ branches : [main]
6+ pull_request :
7+ branches : [main]
8+ workflow_dispatch :
9+ inputs :
10+ force_build_all :
11+ description : ' Force build all projects'
12+ required : false
13+ default : ' false'
14+ type : boolean
15+ run_e2e :
16+ description : ' Run e2e tests'
17+ required : false
18+ default : ' false'
19+ type : boolean
20+
21+ env :
22+ NX_CLOUD_DISTRIBUTED_EXECUTION : true
23+ NX_CLOUD_DISTRIBUTED_EXECUTION_AGENT_COUNT : 3
24+ NX_BRANCH : ${{ github.event.number || github.ref_name }}
25+ NX_RUN_GROUP : ${{ github.run_id }}
26+ HUSKY : 0
27+ NODE_OPTIONS : --max-old-space-size=4096
28+
29+ permissions :
30+ contents : read
31+ pages : write
32+ id-token : write
33+
34+ concurrency :
35+ group : ${{ github.workflow }}-${{ github.ref }}
36+ cancel-in-progress : true
37+
38+ jobs :
39+ setup :
40+ name : Setup and Analysis
41+ runs-on : ubuntu-latest
42+ outputs :
43+ has-affected-projects : ${{ steps.affected.outputs.has-affected-projects }}
44+ affected-projects : ${{ steps.affected.outputs.affected-projects }}
45+ should-deploy : ${{ steps.should-deploy.outputs.should-deploy }}
46+ should-run-e2e : ${{ steps.should-deploy.outputs.should-run-e2e }}
47+ steps :
48+ - name : Checkout
49+ uses : actions/checkout@v4
50+ with :
51+ fetch-depth : 0
52+ token : ${{ secrets.GITHUB_TOKEN }}
53+
54+ - name : Derive appropriate SHAs for base and head for `nx affected` commands
55+ uses : nrwl/nx-set-shas@v4
56+
57+ - name : Setup pnpm
58+ uses : pnpm/action-setup@v4
59+
60+ - name : Setup Node.js
61+ uses : actions/setup-node@v4
62+ with :
63+ node-version : ' 22'
64+ cache : ' pnpm'
65+
66+ - name : Install dependencies
67+ run : pnpm install --no-frozen-lockfile
68+
69+ - name : Check affected projects
70+ id : affected
71+ run : |
72+ # Get affected projects for build target
73+ affected=$(npx nx print-affected --select=projects --type=app 2>/dev/null || echo "")
74+
75+ if [ -n "$affected" ] && [ "$affected" != "" ]; then
76+ echo "has-affected-projects=true" >> $GITHUB_OUTPUT
77+ echo "affected-projects=$affected" >> $GITHUB_OUTPUT
78+ echo "📦 Affected projects: $affected"
79+ else
80+ echo "has-affected-projects=false" >> $GITHUB_OUTPUT
81+ echo "affected-projects=" >> $GITHUB_OUTPUT
82+ echo "📦 No affected projects found"
83+ fi
84+
85+ - name : Determine deployment and testing strategy
86+ id : should-deploy
87+ run : |
88+ should_deploy="false"
89+ should_run_e2e="false"
90+
91+ # Deploy on main branch pushes or manual trigger
92+ if [[ "${{ github.ref }}" == "refs/heads/main" ]] || [[ "${{ github.event.inputs.force_build_all }}" == "true" ]]; then
93+ should_deploy="true"
94+ fi
95+
96+ # Run E2E on main, manual trigger, or if explicitly requested
97+ if [[ "${{ github.ref }}" == "refs/heads/main" ]] || [[ "${{ github.event.inputs.run_e2e }}" == "true" ]]; then
98+ should_run_e2e="true"
99+ fi
100+
101+ echo "should-deploy=$should_deploy" >> $GITHUB_OUTPUT
102+ echo "should-run-e2e=$should_run_e2e" >> $GITHUB_OUTPUT
103+ echo "🚀 Should deploy: $should_deploy"
104+ echo "🧪 Should run e2e: $should_run_e2e"
105+
106+ ci :
107+ name : Nx Cloud - Main Job
108+ runs-on : ubuntu-latest
109+ needs : [setup]
110+ if : needs.setup.outputs.has-affected-projects == 'true' || github.event.inputs.force_build_all == 'true'
111+ steps :
112+ - name : Checkout
113+ uses : actions/checkout@v4
114+ with :
115+ fetch-depth : 0
116+ token : ${{ secrets.GITHUB_TOKEN }}
117+
118+ - name : Derive appropriate SHAs for base and head for `nx affected` commands
119+ uses : nrwl/nx-set-shas@v4
120+
121+ - name : Setup pnpm
122+ uses : pnpm/action-setup@v4
123+
124+ - name : Setup Node.js
125+ uses : actions/setup-node@v4
126+ with :
127+ node-version : ' 22'
128+ cache : ' pnpm'
129+
130+ - name : Install dependencies
131+ run : pnpm install --no-frozen-lockfile
132+
133+ - name : Start CI run
134+ run : ' npx nx-cloud start-ci-run --stop-agents-after="build" --agent-count=3'
135+
136+ - name : Run commands in parallel
137+ run : |
138+ pids=()
139+
140+ if [ "${{ github.event.inputs.force_build_all }}" == "true" ]; then
141+ # Force build all projects
142+ echo "🔄 Force building all projects"
143+ npx nx run-many --target=typecheck --all --parallel=3 --ci --verbose & pids+=($!)
144+ npx nx run-many --target=lint --all --parallel=3 --ci --verbose & pids+=($!)
145+ npx nx run-many --target=test --all --parallel=3 --ci --verbose & pids+=($!)
146+ npx nx run-many --target=build --all --parallel=3 --ci --verbose & pids+=($!)
147+ else
148+ # Run only affected
149+ echo "🎯 Running affected projects only"
150+ npx nx affected --target=typecheck --parallel=3 --ci --verbose & pids+=($!)
151+ npx nx affected --target=lint --parallel=3 --ci --verbose & pids+=($!)
152+ npx nx affected --target=test --parallel=3 --ci --verbose & pids+=($!)
153+ npx nx affected --target=build --parallel=3 --ci --verbose & pids+=($!)
154+ fi
155+
156+ # Wait for all jobs to complete
157+ for pid in "${pids[@]}"; do
158+ wait $pid
159+ done
160+
161+ - name : Upload build artifacts
162+ if : needs.setup.outputs.should-deploy == 'true'
163+ uses : actions/upload-artifact@v4
164+ with :
165+ name : build-artifacts
166+ path : |
167+ portal/build/
168+ standards/*/build/
169+ retention-days : 1
170+
171+ - name : Stop all running agents for this CI run
172+ if : always()
173+ run : npx nx-cloud stop-all-agents
174+
175+ agents :
176+ name : Nx Cloud - Agent ${{ matrix.agent }}
177+ runs-on : ubuntu-latest
178+ needs : [setup]
179+ if : needs.setup.outputs.has-affected-projects == 'true' || github.event.inputs.force_build_all == 'true'
180+ timeout-minutes : 60
181+ strategy :
182+ matrix :
183+ agent : [1, 2, 3]
184+ steps :
185+ - name : Checkout
186+ uses : actions/checkout@v4
187+
188+ - name : Setup pnpm
189+ uses : pnpm/action-setup@v4
190+
191+ - name : Setup Node.js
192+ uses : actions/setup-node@v4
193+ with :
194+ node-version : ' 22'
195+ cache : ' pnpm'
196+
197+ - name : Install dependencies
198+ run : pnpm install --no-frozen-lockfile
199+
200+ - name : Start Nx Agent ${{ matrix.agent }}
201+ run : npx nx-cloud start-agent
202+ env :
203+ NX_AGENT_NAME : ${{ matrix.agent }}
204+
205+ e2e :
206+ name : E2E Tests
207+ runs-on : ubuntu-latest
208+ needs : [setup, ci]
209+ if : needs.setup.outputs.should-run-e2e == 'true' && (success() || failure())
210+ timeout-minutes : 30
211+ steps :
212+ - name : Checkout
213+ uses : actions/checkout@v4
214+
215+ - name : Setup pnpm
216+ uses : pnpm/action-setup@v4
217+
218+ - name : Setup Node.js
219+ uses : actions/setup-node@v4
220+ with :
221+ node-version : ' 22'
222+ cache : ' pnpm'
223+
224+ - name : Install dependencies
225+ run : pnpm install --no-frozen-lockfile
226+
227+ - name : Install Playwright Browsers
228+ run : npx playwright install --with-deps
229+
230+ - name : Download build artifacts
231+ uses : actions/download-artifact@v4
232+ with :
233+ name : build-artifacts
234+ path : ./
235+ continue-on-error : true
236+
237+ - name : Run Playwright tests
238+ run : npx playwright test
239+ env :
240+ CI : true
241+
242+ - name : Upload test results
243+ uses : actions/upload-artifact@v4
244+ if : always()
245+ with :
246+ name : e2e-test-results
247+ path : |
248+ test-results/
249+ playwright-report/
250+ retention-days : 7
251+
252+ deploy :
253+ name : Deploy to GitHub Pages
254+ runs-on : ubuntu-latest
255+ needs : [setup, ci, e2e]
256+ if : always() && needs.setup.outputs.should-deploy == 'true' && (needs.ci.result == 'success' || needs.ci.result == 'skipped')
257+ environment :
258+ name : github-pages
259+ url : ${{ steps.deployment.outputs.page_url }}
260+ steps :
261+ - name : Download build artifacts
262+ uses : actions/download-artifact@v4
263+ with :
264+ name : build-artifacts
265+ path : deployment/
266+ continue-on-error : true
267+
268+ - name : Create deployment structure
269+ run : |
270+ # Ensure we have a deployment directory
271+ mkdir -p deployment
272+
273+ # Create standards index page
274+ cat > deployment/standards.html << 'EOF'
275+ <!DOCTYPE html>
276+ <html>
277+ <head>
278+ <title>IFLA Standards</title>
279+ <meta charset="utf-8">
280+ <meta name="viewport" content="width=device-width, initial-scale=1">
281+ <style>
282+ body {
283+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
284+ max-width: 800px;
285+ margin: 0 auto;
286+ padding: 2rem;
287+ background: #f5f5f5;
288+ }
289+ .container {
290+ background: white;
291+ padding: 2rem;
292+ border-radius: 8px;
293+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
294+ }
295+ h1 { color: #333; margin-bottom: 0.5rem; }
296+ .subtitle { color: #666; margin-bottom: 2rem; }
297+ ul { list-style: none; padding: 0; }
298+ li { margin: 1rem 0; }
299+ a {
300+ display: block;
301+ padding: 1rem;
302+ background: #f8f9fa;
303+ color: #0066cc;
304+ text-decoration: none;
305+ border-radius: 4px;
306+ border: 1px solid #e9ecef;
307+ transition: all 0.2s;
308+ }
309+ a:hover {
310+ background: #e9ecef;
311+ border-color: #dee2e6;
312+ transform: translateX(4px);
313+ }
314+ .standard-name {
315+ font-weight: 600;
316+ display: block;
317+ margin-bottom: 0.25rem;
318+ }
319+ .standard-desc {
320+ font-size: 0.875rem;
321+ color: #666;
322+ }
323+ </style>
324+ </head>
325+ <body>
326+ <div class="container">
327+ <h1>IFLA Standards Documentation</h1>
328+ <p class="subtitle">International Federation of Library Associations and Institutions</p>
329+ <ul>
330+ <li><a href="./ISBDM/"><span class="standard-name">ISBDM</span><span class="standard-desc">International Standard Bibliographic Description for Manifestations</span></a></li>
331+ <li><a href="./LRM/"><span class="standard-name">LRM</span><span class="standard-desc">Library Reference Model</span></a></li>
332+ <li><a href="./FRBR/"><span class="standard-name">FRBR</span><span class="standard-desc">Functional Requirements for Bibliographic Records</span></a></li>
333+ <li><a href="./isbd/"><span class="standard-name">ISBD</span><span class="standard-desc">International Standard Bibliographic Description</span></a></li>
334+ <li><a href="./muldicat/"><span class="standard-name">MulDiCat</span><span class="standard-desc">Multilingual Dictionary of Cataloguing Terms</span></a></li>
335+ <li><a href="./unimarc/"><span class="standard-name">UNIMARC</span><span class="standard-desc">Universal Machine-Readable Cataloguing</span></a></li>
336+ </ul>
337+ </div>
338+ </body>
339+ </html>
340+ EOF
341+
342+ - name : Setup Pages
343+ uses : actions/configure-pages@v5
344+
345+ - name : Upload to GitHub Pages
346+ uses : actions/upload-pages-artifact@v3
347+ with :
348+ path : deployment
349+
350+ - name : Deploy to GitHub Pages
351+ id : deployment
352+ uses : actions/deploy-pages@v4
0 commit comments