CI - Build Starters Matrix - main #529
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI - Build Starters Matrix | |
| run-name: ${{ github.workflow }} - ${{ github.ref_name }} | |
| on: | |
| schedule: | |
| - cron: "0 2 * * *" | |
| workflow_dispatch: | |
| push: | |
| branches: [main] | |
| paths: | |
| - "modules/**" | |
| - "templates/**" | |
| - "test/**" | |
| - "scripts/**" | |
| - "package.json" | |
| - "pnpm-lock.yaml" | |
| - "biome.json" | |
| - "vite.config.js" | |
| pull_request: | |
| types: | |
| - opened | |
| - reopened | |
| - synchronize | |
| - ready_for_review | |
| paths: | |
| - "modules/**" | |
| - "templates/**" | |
| - "test/**" | |
| - "scripts/**" | |
| - "package.json" | |
| - "pnpm-lock.yaml" | |
| - "biome.json" | |
| - "vite.config.js" | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: templates-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| NODE_VERSION: "22" | |
| jobs: | |
| audit-template-deps: | |
| name: Audit template Tailwind dependencies | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: "${{ env.NODE_VERSION }}" | |
| - name: Verify every template declares @tailwindcss/cli + tailwindcss | |
| # Hugo >= 0.161.0 requires the npm @tailwindcss/cli package; the | |
| # standalone tailwindcss binary is no longer accepted. | |
| run: node scripts/check-template-deps.mjs | |
| build-templates: | |
| needs: audit-template-deps | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| starter: | |
| - name: academic-cv | |
| path: templates/academic-cv | |
| - name: saas-landing-page | |
| path: templates/saas-landing-page | |
| - name: dev-portfolio | |
| path: templates/dev-portfolio | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| submodules: true | |
| fetch-depth: 0 | |
| - name: Compute resources cache key | |
| id: reskey | |
| run: | | |
| set -euo pipefail | |
| P=${{ matrix.starter.path }} | |
| # Hash tracked files under assets/config and key files for invalidation | |
| HASH=$(git ls-files -s "$P/assets" "$P/config" "$P/hugoblox.yaml" "$P/package.json" 2>/dev/null | sha256sum | cut -d' ' -f1 || true) | |
| if [ -z "$HASH" ]; then HASH="nohash"; fi | |
| echo "key=${{ runner.os }}-hugo-resources-${{ matrix.starter.name }}-$HASH" >> $GITHUB_OUTPUT | |
| - name: Cache Hugo resources (starter) | |
| uses: actions/cache@v5 | |
| with: | |
| path: ${{ matrix.starter.path }}/resources/ | |
| key: ${{ steps.reskey.outputs.key }} | |
| restore-keys: | | |
| ${{ runner.os }}-hugo-resources-${{ matrix.starter.name }}- | |
| - name: Enable Corepack (for pnpm cache) | |
| run: corepack enable | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: "${{ env.NODE_VERSION }}" | |
| cache: "pnpm" | |
| - name: Activate pnpm from root package.json | |
| run: pnpm --version | |
| - name: Install template dependencies | |
| working-directory: ${{ matrix.starter.path }} | |
| # Don't use --frozen-lockfile as starters have auto-generated package.json with simple deps (Tailwind CLI) | |
| # and may not have lock files checked into the repo | |
| run: pnpm install --no-frozen-lockfile | |
| - name: Verify @tailwindcss/cli resolves via node_modules | |
| # Hugo >= 0.161.0 invokes node @tailwindcss/cli/dist/index.mjs directly. | |
| # If require.resolve fails here, Hugo will fall back to PATH and emit | |
| # "binary tailwindcss is not a Node.js script" at build time. | |
| working-directory: ${{ matrix.starter.path }} | |
| run: node -e "require.resolve('@tailwindcss/cli/package.json')" | |
| - name: Read Hugo version from template | |
| id: hugo | |
| run: | | |
| set -euo pipefail | |
| P=${{ matrix.starter.path }} | |
| VERSION=$(grep -E "^\s*hugo_version:\s*['\"]?" "$P/hugoblox.yaml" | sed -E "s/.*hugo_version:\s*['\"]?([^'\"]+)['\"]?.*/\1/") | |
| if [ -z "$VERSION" ]; then | |
| echo "::error::Could not read hugo_version from $P/hugoblox.yaml" | |
| exit 1 | |
| fi | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| - name: Setup Hugo | |
| uses: peaceiris/actions-hugo@v3 | |
| with: | |
| hugo-version: "${{ steps.hugo.outputs.version }}" | |
| extended: true | |
| - name: Build ${{ matrix.starter.name }} | |
| working-directory: ${{ matrix.starter.path }} | |
| run: hugo --minify --panicOnWarning | |
| smoke-test-latest: | |
| name: Test site on latest Hugo (allowed to fail) | |
| needs: audit-template-deps | |
| runs-on: ubuntu-latest | |
| continue-on-error: true | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| submodules: true | |
| fetch-depth: 0 | |
| - name: Enable Corepack (for pnpm cache) | |
| run: corepack enable | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: "${{ env.NODE_VERSION }}" | |
| cache: "pnpm" | |
| - name: Install root dependencies | |
| run: pnpm install --no-frozen-lockfile | |
| - name: Install test dependencies | |
| working-directory: test | |
| run: pnpm install --no-frozen-lockfile | |
| - name: Verify @tailwindcss/cli resolves via node_modules | |
| working-directory: test | |
| run: node -e "require.resolve('@tailwindcss/cli/package.json')" | |
| - name: Cache Hugo resources (test) | |
| uses: actions/cache@v5 | |
| with: | |
| path: test/resources/ | |
| key: ${{ runner.os }}-hugo-resources-test-${{ hashFiles('test/assets/**/*', 'test/config.yaml', 'test/package.json') }} | |
| restore-keys: | | |
| ${{ runner.os }}-hugo-resources-test- | |
| - name: Setup Hugo (latest) | |
| uses: peaceiris/actions-hugo@v3 | |
| with: | |
| hugo-version: latest | |
| extended: true | |
| - name: Build test site (latest) | |
| working-directory: test | |
| run: hugo --minify --panicOnWarning --templateMetrics --templateMetricsHints | |
| canary-academic-latest: | |
| name: academic-cv on latest Hugo (allowed to fail) | |
| needs: audit-template-deps | |
| runs-on: ubuntu-latest | |
| continue-on-error: true | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| submodules: true | |
| fetch-depth: 0 | |
| - name: Enable Corepack (for pnpm cache) | |
| run: corepack enable | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: "${{ env.NODE_VERSION }}" | |
| cache: "pnpm" | |
| - name: Install template dependencies | |
| working-directory: templates/academic-cv | |
| run: pnpm install --no-frozen-lockfile | |
| - name: Verify @tailwindcss/cli resolves via node_modules | |
| working-directory: templates/academic-cv | |
| run: node -e "require.resolve('@tailwindcss/cli/package.json')" | |
| - name: Cache Hugo resources (template) | |
| uses: actions/cache@v5 | |
| with: | |
| path: templates/academic-cv/resources/ | |
| key: ${{ runner.os }}-hugo-resources-academic-latest-${{ hashFiles('templates/academic-cv/assets/**/*', 'templates/academic-cv/config/**/*', 'templates/academic-cv/hugoblox.yaml', 'templates/academic-cv/package.json') }} | |
| restore-keys: | | |
| ${{ runner.os }}-hugo-resources-academic-latest- | |
| - name: Setup Hugo (latest) | |
| uses: peaceiris/actions-hugo@v3 | |
| with: | |
| hugo-version: latest | |
| extended: true | |
| - name: Build academic-cv (latest) | |
| working-directory: templates/academic-cv | |
| run: hugo --minify --panicOnWarning | |
| smoke-test-min: | |
| name: Test site on minimum supported Hugo | |
| needs: audit-template-deps | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| submodules: true | |
| fetch-depth: 0 | |
| - name: Enable Corepack (for pnpm cache) | |
| run: corepack enable | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: "${{ env.NODE_VERSION }}" | |
| cache: "pnpm" | |
| - name: Install root dependencies | |
| run: pnpm install --no-frozen-lockfile | |
| - name: Install test dependencies | |
| working-directory: test | |
| run: pnpm install --no-frozen-lockfile | |
| - name: Verify @tailwindcss/cli resolves via node_modules | |
| working-directory: test | |
| run: node -e "require.resolve('@tailwindcss/cli/package.json')" | |
| - name: Read minimum Hugo version from framework | |
| id: min | |
| run: | | |
| set -euo pipefail | |
| VERSION=$(grep -E "^[[:space:]]*min:[[:space:]]*['\"]?" modules/blox/hugo.yaml | head -n1 | sed -E "s/.*min:[[:space:]]*['\"]?([^'\"#]+).*/\\1/") | |
| if [ -z "$VERSION" ]; then | |
| echo "::error::Could not read module.hugoVersion.min from modules/blox/hugo.yaml" | |
| exit 1 | |
| fi | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| - name: Cache Hugo resources (test - min) | |
| uses: actions/cache@v5 | |
| with: | |
| path: test/resources/ | |
| key: ${{ runner.os }}-hugo-resources-test-min-${{ steps.min.outputs.version }}-${{ hashFiles('test/assets/**/*', 'test/config.yaml', 'test/package.json') }} | |
| restore-keys: | | |
| ${{ runner.os }}-hugo-resources-test-min- | |
| - name: Setup Hugo (min) | |
| uses: peaceiris/actions-hugo@v3 | |
| with: | |
| hugo-version: "${{ steps.min.outputs.version }}" | |
| extended: true | |
| - name: Build test site (min) | |
| working-directory: test | |
| run: hugo --minify --panicOnWarning --templateMetrics --templateMetricsHints |