name: Build env: NODE_VERSION: '22' on: # Standalone trigger for PR validation pull_request: branches: ['main'] # Reusable workflow trigger - called by deploy.yml workflow_call: outputs: artifact-id: description: 'The ID of the uploaded artifact' value: ${{ jobs.build.outputs.artifact-id }} # Allow manual trigger for testing workflow_dispatch: # Read-only permissions for security permissions: contents: read # Prevent duplicate builds for the same PR concurrency: group: build-${{ github.head_ref || github.run_id }} cancel-in-progress: true jobs: build: if: github.repository_owner != 'HugoBlox' runs-on: ubuntu-latest timeout-minutes: 10 outputs: artifact-id: ${{ steps.upload.outputs.artifact-id }} steps: - name: Checkout uses: actions/checkout@v6 with: # Fetch history for Hugo's .GitInfo and .Lastmod fetch-depth: 0 - name: Setup Node.js uses: actions/setup-node@v6 with: node-version: ${{ env.NODE_VERSION }} - name: Setup pnpm if: hashFiles('package.json') != '' uses: pnpm/action-setup@v6 - name: Get Hugo Version id: hugo-version run: | # Install pinned yq version for robust YAML parsing YQ_VERSION="v4.44.1" if ! wget -q --tries=3 --waitretry=1 -O /tmp/yq \ "https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/yq_linux_amd64"; then echo "::error::Failed to download yq" exit 1 fi sudo mv /tmp/yq /usr/local/bin/yq sudo chmod +x /usr/local/bin/yq # Read hugo_version from hugoblox.yaml VERSION=$(yq '.build.hugo_version // ""' hugoblox.yaml 2>/dev/null | grep -v '^null$' || true) # Fallback to a known stable version if not specified DEFAULT_VERSION="0.161.1" VERSION=${VERSION:-$DEFAULT_VERSION} # Validate version format (basic check) if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then echo "::warning::Invalid hugo_version format '$VERSION', using default $DEFAULT_VERSION" VERSION="$DEFAULT_VERSION" fi echo "HUGO_VERSION=$VERSION" >> $GITHUB_ENV echo "Using Hugo version: $VERSION" - name: Install dependencies run: | # Install Tailwind CLI if package.json exists if [ -f "package.json" ]; then echo "Installing Tailwind dependencies..." pnpm install --no-frozen-lockfile || npm install fi - name: Verify Tailwind CSS dependency if: hashFiles('package.json') != '' run: | if ! node -e "require.resolve('@tailwindcss/cli/package.json')" 2>/dev/null; then echo "::error title=Missing dependency '@tailwindcss/cli'::Hugo >= 0.161.0 requires the npm @tailwindcss/cli package. Add it to package.json:" echo "::error:: pnpm add @tailwindcss/cli tailwindcss" echo "::error::See https://github.com/HugoBlox/kit for upgrade instructions." exit 1 fi - name: Setup Hugo uses: peaceiris/actions-hugo@v3 with: hugo-version: ${{ env.HUGO_VERSION }} extended: true # Cache dependencies (Go modules, node_modules) - stable, rarely changes - uses: actions/cache@v5 with: path: | /tmp/hugo_cache_runner/ node_modules/ modules/*/node_modules/ key: ${{ runner.os }}-hugo-deps-${{ hashFiles('**/go.mod', '**/package-lock.json', '**/pnpm-lock.yaml') }} restore-keys: | ${{ runner.os }}-hugo-deps- # Cache Hugo resources (processed images, CSS) - invalidates only when assets/config change - uses: actions/cache@v5 with: path: resources/ key: ${{ runner.os }}-hugo-resources-${{ hashFiles('assets/**/*', 'config/**/*', 'hugo.yaml', 'package.json') }} restore-keys: | ${{ runner.os }}-hugo-resources- - name: Setup Pages id: pages uses: actions/configure-pages@v5 - name: Build with Hugo env: HUGO_ENVIRONMENT: production HUGO_BLOX_LICENSE: ${{ secrets.HUGO_BLOX_LICENSE }} run: | echo "Hugo Cache Dir: $(hugo config | grep cachedir)" hugo --minify --baseURL "${{ steps.pages.outputs.base_url }}/" - name: Generate Pagefind search index (if applicable) run: | # Check if site uses Pagefind search if [ -f "package.json" ] && grep -q "pagefind" package.json; then pnpm run pagefind || npx pagefind --site "public" fi - name: Upload artifact id: upload uses: actions/upload-pages-artifact@v4 with: path: ./public