Skip to content

feat: implement comprehensive environment configuration system #1

feat: implement comprehensive environment configuration system

feat: implement comprehensive environment configuration system #1

name: Nx Smart Deploy
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
inputs:
force_build_all:
description: 'Force build all projects'
required: false
default: 'false'
type: boolean
run_e2e:
description: 'Run e2e tests'
required: false
default: 'false'
type: boolean
env:

Check failure on line 21 in .github/workflows/nx-smart-deploy.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/nx-smart-deploy.yml

Invalid workflow file

You have an error in your yaml syntax on line 21
NX_CLOUD_DISTRIBUTED_EXECUTION: true
NX_CLOUD_DISTRIBUTED_EXECUTION_AGENT_COUNT: 3
NX_BRANCH: ${{ github.event.number || github.ref_name }}
NX_RUN_GROUP: ${{ github.run_id }}
HUSKY: 0
NODE_OPTIONS: --max-old-space-size=4096
# Set DOCS_ENV for proper environment detection (main branch = production)
DOCS_ENV: ${{
github.event_name == 'pull_request' && 'preview' ||
'production'
}}
# Fallback environment variables for sites that need them
SITE_TITLE: IFLA Standards Portal
SITE_TAGLINE: International Federation of Library Associations and Institutions
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
setup:
name: Setup and Analysis
runs-on: ubuntu-latest
outputs:
has-affected-projects: ${{ steps.affected.outputs.has-affected-projects }}
affected-projects: ${{ steps.affected.outputs.affected-projects }}
should-deploy: ${{ steps.should-deploy.outputs.should-deploy }}
should-run-e2e: ${{ steps.should-deploy.outputs.should-run-e2e }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Derive appropriate SHAs for base and head for `nx affected` commands
uses: nrwl/nx-set-shas@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --no-frozen-lockfile
- name: Check affected projects
id: affected
run: |
# Get affected projects for build target
affected=$(npx nx print-affected --select=projects --type=app 2>/dev/null || echo "")
if [ -n "$affected" ] && [ "$affected" != "" ]; then
echo "has-affected-projects=true" >> $GITHUB_OUTPUT
echo "affected-projects=$affected" >> $GITHUB_OUTPUT
echo "📦 Affected projects: $affected"
else
echo "has-affected-projects=false" >> $GITHUB_OUTPUT
echo "affected-projects=" >> $GITHUB_OUTPUT
echo "📦 No affected projects found"
fi
- name: Determine deployment and testing strategy
id: should-deploy
run: |
should_deploy="false"
should_run_e2e="false"
# Deploy on main branch pushes or manual trigger
if [[ "${{ github.ref }}" == "refs/heads/main" ]] || [[ "${{ github.event.inputs.force_build_all }}" == "true" ]]; then
should_deploy="true"
fi
# Run E2E on main, manual trigger, or if explicitly requested
if [[ "${{ github.ref }}" == "refs/heads/main" ]] || [[ "${{ github.event.inputs.run_e2e }}" == "true" ]]; then
should_run_e2e="true"
fi
echo "should-deploy=$should_deploy" >> $GITHUB_OUTPUT
echo "should-run-e2e=$should_run_e2e" >> $GITHUB_OUTPUT
echo "🚀 Should deploy: $should_deploy"
echo "🧪 Should run e2e: $should_run_e2e"
ci:
name: Nx Cloud - Main Job
runs-on: ubuntu-latest
needs: [setup]
if: needs.setup.outputs.has-affected-projects == 'true' || github.event.inputs.force_build_all == 'true'
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Derive appropriate SHAs for base and head for `nx affected` commands
uses: nrwl/nx-set-shas@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --no-frozen-lockfile
- name: Start CI run
run: 'npx nx-cloud start-ci-run --stop-agents-after="build" --agent-count=3'
- name: Run commands in parallel
run: |
pids=()
if [ "${{ github.event.inputs.force_build_all }}" == "true" ]; then
# Force build all projects
echo "🔄 Force building all projects"
npx nx run-many --target=typecheck --all --parallel=3 --ci --verbose & pids+=($!)
npx nx run-many --target=lint --all --parallel=3 --ci --verbose & pids+=($!)
npx nx run-many --target=test --all --parallel=3 --ci --verbose & pids+=($!)
npx nx run-many --target=build --all --parallel=3 --ci --verbose & pids+=($!)
else
# Run only affected
echo "🎯 Running affected projects only"
npx nx affected --target=typecheck --parallel=3 --ci --verbose & pids+=($!)
npx nx affected --target=lint --parallel=3 --ci --verbose & pids+=($!)
npx nx affected --target=test --parallel=3 --ci --verbose & pids+=($!)
npx nx affected --target=build --parallel=3 --ci --verbose & pids+=($!)
fi
# Wait for all jobs to complete
for pid in "${pids[@]}"; do
wait $pid
done
- name: Upload build artifacts
if: needs.setup.outputs.should-deploy == 'true'
uses: actions/upload-artifact@v4
with:
name: build-artifacts
path: |
portal/build/
standards/*/build/
retention-days: 1
- name: Stop all running agents for this CI run
if: always()
run: npx nx-cloud stop-all-agents
agents:
name: Nx Cloud - Agent ${{ matrix.agent }}
runs-on: ubuntu-latest
needs: [setup]
if: needs.setup.outputs.has-affected-projects == 'true' || github.event.inputs.force_build_all == 'true'
timeout-minutes: 60
strategy:
matrix:
agent: [1, 2, 3]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --no-frozen-lockfile
- name: Start Nx Agent ${{ matrix.agent }}
run: npx nx-cloud start-agent
env:
NX_AGENT_NAME: ${{ matrix.agent }}
e2e:
name: E2E Tests
runs-on: ubuntu-latest
needs: [setup, ci]
if: needs.setup.outputs.should-run-e2e == 'true' && (success() || failure())
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --no-frozen-lockfile
- name: Install Playwright Browsers
run: npx playwright install --with-deps
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: build-artifacts
path: ./
continue-on-error: true
- name: Run Playwright tests
run: npx playwright test
env:
CI: true
- name: Upload test results
uses: actions/upload-artifact@v4
if: always()
with:
name: e2e-test-results
path: |
test-results/
playwright-report/
retention-days: 7
deploy:
name: Deploy to GitHub Pages
runs-on: ubuntu-latest
needs: [setup, ci, e2e]
if: always() && needs.setup.outputs.should-deploy == 'true' && (needs.ci.result == 'success' || needs.ci.result == 'skipped')
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: build-artifacts
path: deployment/
continue-on-error: true
- name: Create deployment structure
run: |
# Ensure we have a deployment directory
mkdir -p deployment
# Create standards index page
cat > deployment/standards.html << 'EOF'
<!DOCTYPE html>
<html>
<head>
<title>IFLA Standards</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 2rem;
background: #f5f5f5;
}
.container {
background: white;
padding: 2rem;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
h1 { color: #333; margin-bottom: 0.5rem; }
.subtitle { color: #666; margin-bottom: 2rem; }
ul { list-style: none; padding: 0; }
li { margin: 1rem 0; }
a {
display: block;
padding: 1rem;
background: #f8f9fa;
color: #0066cc;
text-decoration: none;
border-radius: 4px;
border: 1px solid #e9ecef;
transition: all 0.2s;
}
a:hover {
background: #e9ecef;
border-color: #dee2e6;
transform: translateX(4px);
}
.standard-name {
font-weight: 600;
display: block;
margin-bottom: 0.25rem;
}
.standard-desc {
font-size: 0.875rem;
color: #666;
}
</style>
</head>
<body>
<div class="container">
<h1>IFLA Standards Documentation</h1>
<p class="subtitle">International Federation of Library Associations and Institutions</p>
<ul>
<li><a href="./ISBDM/"><span class="standard-name">ISBDM</span><span class="standard-desc">International Standard Bibliographic Description for Manifestations</span></a></li>
<li><a href="./LRM/"><span class="standard-name">LRM</span><span class="standard-desc">Library Reference Model</span></a></li>
<li><a href="./FRBR/"><span class="standard-name">FRBR</span><span class="standard-desc">Functional Requirements for Bibliographic Records</span></a></li>
<li><a href="./isbd/"><span class="standard-name">ISBD</span><span class="standard-desc">International Standard Bibliographic Description</span></a></li>
<li><a href="./muldicat/"><span class="standard-name">MulDiCat</span><span class="standard-desc">Multilingual Dictionary of Cataloguing Terms</span></a></li>
<li><a href="./unimarc/"><span class="standard-name">UNIMARC</span><span class="standard-desc">Universal Machine-Readable Cataloguing</span></a></li>
</ul>
</div>
</body>
</html>
EOF
- name: Setup Pages
uses: actions/configure-pages@v5
- name: Upload to GitHub Pages
uses: actions/upload-pages-artifact@v3
with:
path: deployment
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4