diff --git a/templates/academic-cv/.github/workflows/build.yml b/templates/academic-cv/.github/workflows/build.yml new file mode 100644 index 00000000..f76ec93b --- /dev/null +++ b/templates/academic-cv/.github/workflows/build.yml @@ -0,0 +1,111 @@ +name: Build + +env: + NODE_VERSION: '20' + +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@v4 + 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@v4 + + - name: Get Hugo Version + id: hugo-version + run: | + VERSION=$(grep "hugo_version" hugoblox.yaml | awk '{print $2}' | tr -d "'\""") + echo "HUGO_VERSION=$VERSION" >> $GITHUB_ENV + + - 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: 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@v4 + 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@v4 + with: + path: resources/ + key: ${{ runner.os }}-hugo-resources-${{ hashFiles('assets/**/*', 'config/**/*', + 'hugo.yaml', 'package.json') }} + restore-keys: | + ${{ runner.os }}-hugo-resources- + + - 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 + + - 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 diff --git a/templates/academic-cv/.github/workflows/deploy.yml b/templates/academic-cv/.github/workflows/deploy.yml index fc593765..14d51016 100644 --- a/templates/academic-cv/.github/workflows/deploy.yml +++ b/templates/academic-cv/.github/workflows/deploy.yml @@ -1,8 +1,5 @@ name: Deploy website to GitHub Pages -env: - NODE_VERSION: '20' - on: # Trigger the workflow every time you push to the `main` branch push: @@ -21,95 +18,39 @@ concurrency: cancel-in-progress: false jobs: - # Build website - build: + # Check deployment configuration + config: if: github.repository_owner != 'HugoBlox' runs-on: ubuntu-latest + outputs: + deploy-host: ${{ steps.check.outputs.host }} steps: - name: Checkout uses: actions/checkout@v4 with: - # Fetch history for Hugo's .GitInfo and .Lastmod - fetch-depth: 0 + sparse-checkout: hugoblox.yaml + sparse-checkout-cone-mode: false - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{ env.NODE_VERSION }} - - - name: Setup pnpm - if: hashFiles('package.json') != '' - uses: pnpm/action-setup@v4 - - - name: Get Hugo Version - id: hugo-version + - name: Check deploy host + id: check run: | - VERSION=$(grep "hugo_version" hugoblox.yaml | awk '{print $2}' | tr -d "'\"") - echo "HUGO_VERSION=$VERSION" >> $GITHUB_ENV + # Read deploy.host from hugoblox.yaml, default to github-pages + HOST=$(grep -A5 "^deploy:" hugoblox.yaml 2>/dev/null | grep "host:" | awk '{print $2}' | tr -d "'\""" || echo "github-pages") + HOST=${HOST:-github-pages} + echo "host=$HOST" >> $GITHUB_OUTPUT + echo "Deployment target: $HOST" - - 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: 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@v4 - 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@v4 - 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 - uses: actions/upload-pages-artifact@v4 - with: - path: ./public - - # Deploy website to GitHub Pages hosting - deploy: + # Build website using reusable workflow (always runs for CI) + build: + needs: config if: github.repository_owner != 'HugoBlox' - needs: build + uses: ./.github/workflows/build.yml + secrets: inherit + + # Deploy website to GitHub Pages hosting (only if configured) + deploy: + needs: [config, build] + if: needs.config.outputs.deploy-host == 'github-pages' # Grant GITHUB_TOKEN the permissions required to make a Pages deployment permissions: pages: write # to deploy to Pages diff --git a/templates/academic-cv/.github/workflows/import-publications.yml b/templates/academic-cv/.github/workflows/import-publications.yml index 66266a3d..ec9d16dd 100644 --- a/templates/academic-cv/.github/workflows/import-publications.yml +++ b/templates/academic-cv/.github/workflows/import-publications.yml @@ -28,7 +28,7 @@ jobs: env: ACADEMIC_VERSION: '>=0.10.0' - PYTHON_VERSION: '3.12' + PYTHON_VERSION: '3.13' steps: - name: Checkout the repo uses: actions/checkout@v4 @@ -39,7 +39,7 @@ jobs: - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: '3.12' + python-version: '3.13' - name: Setup pip cache uses: actions/cache@v4 with: @@ -100,7 +100,7 @@ jobs: 📖 [View Documentation](https://github.com/GetRD/academic-file-converter) base: main labels: automated-pr, content, publications - branch: hugoblox-import-publications + branch: hugoblox-import-publications-${{ github.run_id }} delete-branch: true draft: false - name: Check outputs diff --git a/templates/academic-cv/.github/workflows/updater-wip.yml b/templates/academic-cv/.github/workflows/internal-readme-news.yml similarity index 73% rename from templates/academic-cv/.github/workflows/updater-wip.yml rename to templates/academic-cv/.github/workflows/internal-readme-news.yml index 25f5140f..6af51b5e 100644 --- a/templates/academic-cv/.github/workflows/updater-wip.yml +++ b/templates/academic-cv/.github/workflows/internal-readme-news.yml @@ -1,5 +1,6 @@ -# This workflow is only for the Hugo Blox repository. It is safe to delete from your site. -name: Updater (WIP) +# Internal HugoBlox workflow - Updates README news section from RSS feed. +# This file only runs on the HugoBlox org repo and can be safely deleted by end users. +name: Internal - Update README News on: schedule: diff --git a/templates/academic-cv/.github/workflows/upgrade.yml b/templates/academic-cv/.github/workflows/upgrade.yml index 5f845f22..f564f163 100644 --- a/templates/academic-cv/.github/workflows/upgrade.yml +++ b/templates/academic-cv/.github/workflows/upgrade.yml @@ -19,13 +19,17 @@ permissions: contents: write pull-requests: write +# Prevent duplicate upgrade runs +concurrency: + group: upgrade-${{ github.ref }} + cancel-in-progress: true + jobs: upgrade: name: Upgrade if: github.repository_owner != 'HugoBlox' runs-on: ubuntu-latest - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + timeout-minutes: 15 steps: - name: Checkout uses: actions/checkout@v4 @@ -33,20 +37,20 @@ jobs: fetch-depth: 0 - name: Setup Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: - node-version: '20' + node-version: '22' - name: Setup pnpm uses: pnpm/action-setup@v4 with: - package_json_path: templates/academic-cv/package.json + package_json_path: ./package.json run_install: false - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '1.21' + go-version: '1.23' - name: Setup Hugo uses: peaceiris/actions-hugo@v3 @@ -56,6 +60,7 @@ jobs: - name: Run Upgrade CLI env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Use manual input or default to stable for scheduled runs VERSION_TYPE: ${{ inputs.version_type || 'Stable' }} run: | @@ -68,6 +73,7 @@ jobs: echo "Running upgrade with flags: $FLAGS" pnpm dlx hugoblox@latest upgrade $FLAGS + - name: Create Pull Request uses: peter-evans/create-pull-request@v6 with: @@ -84,7 +90,7 @@ jobs: **Verification:** - [ ] Check the Deploy Preview to ensure everything looks correct. - [ ] Merge this PR to apply the updates. - branch: "chore/upgrade-hugoblox" + branch: "chore/upgrade-hugoblox-${{ github.run_id }}" delete-branch: true base: main labels: | diff --git a/templates/academic-cv/hugoblox.yaml b/templates/academic-cv/hugoblox.yaml index f62e4e3c..22238d62 100644 --- a/templates/academic-cv/hugoblox.yaml +++ b/templates/academic-cv/hugoblox.yaml @@ -1,5 +1,8 @@ build: hugo_version: '0.154.5' +deploy: + # Deployment target: github-pages, netlify, vercel, cloudflare, or none + host: 'github-pages' template: id: "academic-cv" name: "Academic CV" diff --git a/templates/data-science-blog/.github/workflows/build.yml b/templates/data-science-blog/.github/workflows/build.yml new file mode 100644 index 00000000..f76ec93b --- /dev/null +++ b/templates/data-science-blog/.github/workflows/build.yml @@ -0,0 +1,111 @@ +name: Build + +env: + NODE_VERSION: '20' + +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@v4 + 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@v4 + + - name: Get Hugo Version + id: hugo-version + run: | + VERSION=$(grep "hugo_version" hugoblox.yaml | awk '{print $2}' | tr -d "'\""") + echo "HUGO_VERSION=$VERSION" >> $GITHUB_ENV + + - 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: 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@v4 + 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@v4 + with: + path: resources/ + key: ${{ runner.os }}-hugo-resources-${{ hashFiles('assets/**/*', 'config/**/*', + 'hugo.yaml', 'package.json') }} + restore-keys: | + ${{ runner.os }}-hugo-resources- + + - 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 + + - 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 diff --git a/templates/data-science-blog/.github/workflows/deploy.yml b/templates/data-science-blog/.github/workflows/deploy.yml index fc593765..14d51016 100644 --- a/templates/data-science-blog/.github/workflows/deploy.yml +++ b/templates/data-science-blog/.github/workflows/deploy.yml @@ -1,8 +1,5 @@ name: Deploy website to GitHub Pages -env: - NODE_VERSION: '20' - on: # Trigger the workflow every time you push to the `main` branch push: @@ -21,95 +18,39 @@ concurrency: cancel-in-progress: false jobs: - # Build website - build: + # Check deployment configuration + config: if: github.repository_owner != 'HugoBlox' runs-on: ubuntu-latest + outputs: + deploy-host: ${{ steps.check.outputs.host }} steps: - name: Checkout uses: actions/checkout@v4 with: - # Fetch history for Hugo's .GitInfo and .Lastmod - fetch-depth: 0 + sparse-checkout: hugoblox.yaml + sparse-checkout-cone-mode: false - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{ env.NODE_VERSION }} - - - name: Setup pnpm - if: hashFiles('package.json') != '' - uses: pnpm/action-setup@v4 - - - name: Get Hugo Version - id: hugo-version + - name: Check deploy host + id: check run: | - VERSION=$(grep "hugo_version" hugoblox.yaml | awk '{print $2}' | tr -d "'\"") - echo "HUGO_VERSION=$VERSION" >> $GITHUB_ENV + # Read deploy.host from hugoblox.yaml, default to github-pages + HOST=$(grep -A5 "^deploy:" hugoblox.yaml 2>/dev/null | grep "host:" | awk '{print $2}' | tr -d "'\""" || echo "github-pages") + HOST=${HOST:-github-pages} + echo "host=$HOST" >> $GITHUB_OUTPUT + echo "Deployment target: $HOST" - - 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: 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@v4 - 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@v4 - 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 - uses: actions/upload-pages-artifact@v4 - with: - path: ./public - - # Deploy website to GitHub Pages hosting - deploy: + # Build website using reusable workflow (always runs for CI) + build: + needs: config if: github.repository_owner != 'HugoBlox' - needs: build + uses: ./.github/workflows/build.yml + secrets: inherit + + # Deploy website to GitHub Pages hosting (only if configured) + deploy: + needs: [config, build] + if: needs.config.outputs.deploy-host == 'github-pages' # Grant GITHUB_TOKEN the permissions required to make a Pages deployment permissions: pages: write # to deploy to Pages diff --git a/templates/data-science-blog/.github/workflows/upgrade.yml b/templates/data-science-blog/.github/workflows/upgrade.yml index 1c52279f..f564f163 100644 --- a/templates/data-science-blog/.github/workflows/upgrade.yml +++ b/templates/data-science-blog/.github/workflows/upgrade.yml @@ -19,13 +19,17 @@ permissions: contents: write pull-requests: write +# Prevent duplicate upgrade runs +concurrency: + group: upgrade-${{ github.ref }} + cancel-in-progress: true + jobs: upgrade: name: Upgrade if: github.repository_owner != 'HugoBlox' runs-on: ubuntu-latest - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + timeout-minutes: 15 steps: - name: Checkout uses: actions/checkout@v4 @@ -33,20 +37,20 @@ jobs: fetch-depth: 0 - name: Setup Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: - node-version: '20' + node-version: '22' - name: Setup pnpm uses: pnpm/action-setup@v4 with: - package_json_path: templates/data-science-blog/package.json + package_json_path: ./package.json run_install: false - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '1.21' + go-version: '1.23' - name: Setup Hugo uses: peaceiris/actions-hugo@v3 @@ -56,6 +60,7 @@ jobs: - name: Run Upgrade CLI env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Use manual input or default to stable for scheduled runs VERSION_TYPE: ${{ inputs.version_type || 'Stable' }} run: | @@ -68,6 +73,7 @@ jobs: echo "Running upgrade with flags: $FLAGS" pnpm dlx hugoblox@latest upgrade $FLAGS + - name: Create Pull Request uses: peter-evans/create-pull-request@v6 with: @@ -84,7 +90,7 @@ jobs: **Verification:** - [ ] Check the Deploy Preview to ensure everything looks correct. - [ ] Merge this PR to apply the updates. - branch: "chore/upgrade-hugoblox" + branch: "chore/upgrade-hugoblox-${{ github.run_id }}" delete-branch: true base: main labels: | diff --git a/templates/data-science-blog/hugoblox.yaml b/templates/data-science-blog/hugoblox.yaml index 0044bd30..f4ae1d28 100644 --- a/templates/data-science-blog/hugoblox.yaml +++ b/templates/data-science-blog/hugoblox.yaml @@ -1,5 +1,8 @@ build: hugo_version: '0.154.5' +deploy: + # Deployment target: github-pages, netlify, vercel, cloudflare, or none + host: 'github-pages' template: id: "blog" name: "Blog" diff --git a/templates/dev-portfolio/.github/workflows/build.yml b/templates/dev-portfolio/.github/workflows/build.yml new file mode 100644 index 00000000..f76ec93b --- /dev/null +++ b/templates/dev-portfolio/.github/workflows/build.yml @@ -0,0 +1,111 @@ +name: Build + +env: + NODE_VERSION: '20' + +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@v4 + 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@v4 + + - name: Get Hugo Version + id: hugo-version + run: | + VERSION=$(grep "hugo_version" hugoblox.yaml | awk '{print $2}' | tr -d "'\""") + echo "HUGO_VERSION=$VERSION" >> $GITHUB_ENV + + - 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: 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@v4 + 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@v4 + with: + path: resources/ + key: ${{ runner.os }}-hugo-resources-${{ hashFiles('assets/**/*', 'config/**/*', + 'hugo.yaml', 'package.json') }} + restore-keys: | + ${{ runner.os }}-hugo-resources- + + - 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 + + - 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 diff --git a/templates/dev-portfolio/.github/workflows/deploy.yml b/templates/dev-portfolio/.github/workflows/deploy.yml index fc593765..14d51016 100644 --- a/templates/dev-portfolio/.github/workflows/deploy.yml +++ b/templates/dev-portfolio/.github/workflows/deploy.yml @@ -1,8 +1,5 @@ name: Deploy website to GitHub Pages -env: - NODE_VERSION: '20' - on: # Trigger the workflow every time you push to the `main` branch push: @@ -21,95 +18,39 @@ concurrency: cancel-in-progress: false jobs: - # Build website - build: + # Check deployment configuration + config: if: github.repository_owner != 'HugoBlox' runs-on: ubuntu-latest + outputs: + deploy-host: ${{ steps.check.outputs.host }} steps: - name: Checkout uses: actions/checkout@v4 with: - # Fetch history for Hugo's .GitInfo and .Lastmod - fetch-depth: 0 + sparse-checkout: hugoblox.yaml + sparse-checkout-cone-mode: false - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{ env.NODE_VERSION }} - - - name: Setup pnpm - if: hashFiles('package.json') != '' - uses: pnpm/action-setup@v4 - - - name: Get Hugo Version - id: hugo-version + - name: Check deploy host + id: check run: | - VERSION=$(grep "hugo_version" hugoblox.yaml | awk '{print $2}' | tr -d "'\"") - echo "HUGO_VERSION=$VERSION" >> $GITHUB_ENV + # Read deploy.host from hugoblox.yaml, default to github-pages + HOST=$(grep -A5 "^deploy:" hugoblox.yaml 2>/dev/null | grep "host:" | awk '{print $2}' | tr -d "'\""" || echo "github-pages") + HOST=${HOST:-github-pages} + echo "host=$HOST" >> $GITHUB_OUTPUT + echo "Deployment target: $HOST" - - 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: 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@v4 - 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@v4 - 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 - uses: actions/upload-pages-artifact@v4 - with: - path: ./public - - # Deploy website to GitHub Pages hosting - deploy: + # Build website using reusable workflow (always runs for CI) + build: + needs: config if: github.repository_owner != 'HugoBlox' - needs: build + uses: ./.github/workflows/build.yml + secrets: inherit + + # Deploy website to GitHub Pages hosting (only if configured) + deploy: + needs: [config, build] + if: needs.config.outputs.deploy-host == 'github-pages' # Grant GITHUB_TOKEN the permissions required to make a Pages deployment permissions: pages: write # to deploy to Pages diff --git a/templates/dev-portfolio/.github/workflows/upgrade.yml b/templates/dev-portfolio/.github/workflows/upgrade.yml index bb8df56b..f564f163 100644 --- a/templates/dev-portfolio/.github/workflows/upgrade.yml +++ b/templates/dev-portfolio/.github/workflows/upgrade.yml @@ -19,13 +19,17 @@ permissions: contents: write pull-requests: write +# Prevent duplicate upgrade runs +concurrency: + group: upgrade-${{ github.ref }} + cancel-in-progress: true + jobs: upgrade: name: Upgrade if: github.repository_owner != 'HugoBlox' runs-on: ubuntu-latest - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + timeout-minutes: 15 steps: - name: Checkout uses: actions/checkout@v4 @@ -33,20 +37,20 @@ jobs: fetch-depth: 0 - name: Setup Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: - node-version: '20' + node-version: '22' - name: Setup pnpm uses: pnpm/action-setup@v4 with: - package_json_path: templates/dev-portfolio/package.json + package_json_path: ./package.json run_install: false - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '1.21' + go-version: '1.23' - name: Setup Hugo uses: peaceiris/actions-hugo@v3 @@ -56,6 +60,7 @@ jobs: - name: Run Upgrade CLI env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Use manual input or default to stable for scheduled runs VERSION_TYPE: ${{ inputs.version_type || 'Stable' }} run: | @@ -68,6 +73,7 @@ jobs: echo "Running upgrade with flags: $FLAGS" pnpm dlx hugoblox@latest upgrade $FLAGS + - name: Create Pull Request uses: peter-evans/create-pull-request@v6 with: @@ -84,7 +90,7 @@ jobs: **Verification:** - [ ] Check the Deploy Preview to ensure everything looks correct. - [ ] Merge this PR to apply the updates. - branch: "chore/upgrade-hugoblox" + branch: "chore/upgrade-hugoblox-${{ github.run_id }}" delete-branch: true base: main labels: | diff --git a/templates/dev-portfolio/hugoblox.yaml b/templates/dev-portfolio/hugoblox.yaml index 346184c0..31b6423f 100644 --- a/templates/dev-portfolio/hugoblox.yaml +++ b/templates/dev-portfolio/hugoblox.yaml @@ -1,5 +1,8 @@ build: hugo_version: '0.154.5' +deploy: + # Deployment target: github-pages, netlify, vercel, cloudflare, or none + host: 'github-pages' template: id: "dev-portfolio" name: "Developer Portfolio" diff --git a/templates/documentation/.github/workflows/build.yml b/templates/documentation/.github/workflows/build.yml new file mode 100644 index 00000000..f76ec93b --- /dev/null +++ b/templates/documentation/.github/workflows/build.yml @@ -0,0 +1,111 @@ +name: Build + +env: + NODE_VERSION: '20' + +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@v4 + 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@v4 + + - name: Get Hugo Version + id: hugo-version + run: | + VERSION=$(grep "hugo_version" hugoblox.yaml | awk '{print $2}' | tr -d "'\""") + echo "HUGO_VERSION=$VERSION" >> $GITHUB_ENV + + - 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: 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@v4 + 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@v4 + with: + path: resources/ + key: ${{ runner.os }}-hugo-resources-${{ hashFiles('assets/**/*', 'config/**/*', + 'hugo.yaml', 'package.json') }} + restore-keys: | + ${{ runner.os }}-hugo-resources- + + - 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 + + - 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 diff --git a/templates/documentation/.github/workflows/deploy.yml b/templates/documentation/.github/workflows/deploy.yml index fc593765..14d51016 100644 --- a/templates/documentation/.github/workflows/deploy.yml +++ b/templates/documentation/.github/workflows/deploy.yml @@ -1,8 +1,5 @@ name: Deploy website to GitHub Pages -env: - NODE_VERSION: '20' - on: # Trigger the workflow every time you push to the `main` branch push: @@ -21,95 +18,39 @@ concurrency: cancel-in-progress: false jobs: - # Build website - build: + # Check deployment configuration + config: if: github.repository_owner != 'HugoBlox' runs-on: ubuntu-latest + outputs: + deploy-host: ${{ steps.check.outputs.host }} steps: - name: Checkout uses: actions/checkout@v4 with: - # Fetch history for Hugo's .GitInfo and .Lastmod - fetch-depth: 0 + sparse-checkout: hugoblox.yaml + sparse-checkout-cone-mode: false - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{ env.NODE_VERSION }} - - - name: Setup pnpm - if: hashFiles('package.json') != '' - uses: pnpm/action-setup@v4 - - - name: Get Hugo Version - id: hugo-version + - name: Check deploy host + id: check run: | - VERSION=$(grep "hugo_version" hugoblox.yaml | awk '{print $2}' | tr -d "'\"") - echo "HUGO_VERSION=$VERSION" >> $GITHUB_ENV + # Read deploy.host from hugoblox.yaml, default to github-pages + HOST=$(grep -A5 "^deploy:" hugoblox.yaml 2>/dev/null | grep "host:" | awk '{print $2}' | tr -d "'\""" || echo "github-pages") + HOST=${HOST:-github-pages} + echo "host=$HOST" >> $GITHUB_OUTPUT + echo "Deployment target: $HOST" - - 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: 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@v4 - 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@v4 - 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 - uses: actions/upload-pages-artifact@v4 - with: - path: ./public - - # Deploy website to GitHub Pages hosting - deploy: + # Build website using reusable workflow (always runs for CI) + build: + needs: config if: github.repository_owner != 'HugoBlox' - needs: build + uses: ./.github/workflows/build.yml + secrets: inherit + + # Deploy website to GitHub Pages hosting (only if configured) + deploy: + needs: [config, build] + if: needs.config.outputs.deploy-host == 'github-pages' # Grant GITHUB_TOKEN the permissions required to make a Pages deployment permissions: pages: write # to deploy to Pages diff --git a/templates/documentation/.github/workflows/upgrade.yml b/templates/documentation/.github/workflows/upgrade.yml index f62e4a42..f564f163 100644 --- a/templates/documentation/.github/workflows/upgrade.yml +++ b/templates/documentation/.github/workflows/upgrade.yml @@ -19,13 +19,17 @@ permissions: contents: write pull-requests: write +# Prevent duplicate upgrade runs +concurrency: + group: upgrade-${{ github.ref }} + cancel-in-progress: true + jobs: upgrade: name: Upgrade if: github.repository_owner != 'HugoBlox' runs-on: ubuntu-latest - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + timeout-minutes: 15 steps: - name: Checkout uses: actions/checkout@v4 @@ -33,20 +37,20 @@ jobs: fetch-depth: 0 - name: Setup Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: - node-version: '20' + node-version: '22' - name: Setup pnpm uses: pnpm/action-setup@v4 with: - package_json_path: templates/documentation/package.json + package_json_path: ./package.json run_install: false - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '1.21' + go-version: '1.23' - name: Setup Hugo uses: peaceiris/actions-hugo@v3 @@ -56,6 +60,7 @@ jobs: - name: Run Upgrade CLI env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Use manual input or default to stable for scheduled runs VERSION_TYPE: ${{ inputs.version_type || 'Stable' }} run: | @@ -68,6 +73,7 @@ jobs: echo "Running upgrade with flags: $FLAGS" pnpm dlx hugoblox@latest upgrade $FLAGS + - name: Create Pull Request uses: peter-evans/create-pull-request@v6 with: @@ -84,7 +90,7 @@ jobs: **Verification:** - [ ] Check the Deploy Preview to ensure everything looks correct. - [ ] Merge this PR to apply the updates. - branch: "chore/upgrade-hugoblox" + branch: "chore/upgrade-hugoblox-${{ github.run_id }}" delete-branch: true base: main labels: | diff --git a/templates/documentation/hugoblox.yaml b/templates/documentation/hugoblox.yaml index 1f93c3f9..6bc253c3 100644 --- a/templates/documentation/hugoblox.yaml +++ b/templates/documentation/hugoblox.yaml @@ -1,5 +1,8 @@ build: hugo_version: '0.154.5' +deploy: + # Deployment target: github-pages, netlify, vercel, cloudflare, or none + host: 'github-pages' template: id: "documentation" name: "Documentation" diff --git a/templates/link-in-bio/.github/workflows/build.yml b/templates/link-in-bio/.github/workflows/build.yml new file mode 100644 index 00000000..f76ec93b --- /dev/null +++ b/templates/link-in-bio/.github/workflows/build.yml @@ -0,0 +1,111 @@ +name: Build + +env: + NODE_VERSION: '20' + +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@v4 + 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@v4 + + - name: Get Hugo Version + id: hugo-version + run: | + VERSION=$(grep "hugo_version" hugoblox.yaml | awk '{print $2}' | tr -d "'\""") + echo "HUGO_VERSION=$VERSION" >> $GITHUB_ENV + + - 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: 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@v4 + 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@v4 + with: + path: resources/ + key: ${{ runner.os }}-hugo-resources-${{ hashFiles('assets/**/*', 'config/**/*', + 'hugo.yaml', 'package.json') }} + restore-keys: | + ${{ runner.os }}-hugo-resources- + + - 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 + + - 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 diff --git a/templates/link-in-bio/.github/workflows/deploy.yml b/templates/link-in-bio/.github/workflows/deploy.yml index fc593765..14d51016 100644 --- a/templates/link-in-bio/.github/workflows/deploy.yml +++ b/templates/link-in-bio/.github/workflows/deploy.yml @@ -1,8 +1,5 @@ name: Deploy website to GitHub Pages -env: - NODE_VERSION: '20' - on: # Trigger the workflow every time you push to the `main` branch push: @@ -21,95 +18,39 @@ concurrency: cancel-in-progress: false jobs: - # Build website - build: + # Check deployment configuration + config: if: github.repository_owner != 'HugoBlox' runs-on: ubuntu-latest + outputs: + deploy-host: ${{ steps.check.outputs.host }} steps: - name: Checkout uses: actions/checkout@v4 with: - # Fetch history for Hugo's .GitInfo and .Lastmod - fetch-depth: 0 + sparse-checkout: hugoblox.yaml + sparse-checkout-cone-mode: false - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{ env.NODE_VERSION }} - - - name: Setup pnpm - if: hashFiles('package.json') != '' - uses: pnpm/action-setup@v4 - - - name: Get Hugo Version - id: hugo-version + - name: Check deploy host + id: check run: | - VERSION=$(grep "hugo_version" hugoblox.yaml | awk '{print $2}' | tr -d "'\"") - echo "HUGO_VERSION=$VERSION" >> $GITHUB_ENV + # Read deploy.host from hugoblox.yaml, default to github-pages + HOST=$(grep -A5 "^deploy:" hugoblox.yaml 2>/dev/null | grep "host:" | awk '{print $2}' | tr -d "'\""" || echo "github-pages") + HOST=${HOST:-github-pages} + echo "host=$HOST" >> $GITHUB_OUTPUT + echo "Deployment target: $HOST" - - 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: 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@v4 - 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@v4 - 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 - uses: actions/upload-pages-artifact@v4 - with: - path: ./public - - # Deploy website to GitHub Pages hosting - deploy: + # Build website using reusable workflow (always runs for CI) + build: + needs: config if: github.repository_owner != 'HugoBlox' - needs: build + uses: ./.github/workflows/build.yml + secrets: inherit + + # Deploy website to GitHub Pages hosting (only if configured) + deploy: + needs: [config, build] + if: needs.config.outputs.deploy-host == 'github-pages' # Grant GITHUB_TOKEN the permissions required to make a Pages deployment permissions: pages: write # to deploy to Pages diff --git a/templates/link-in-bio/.github/workflows/upgrade.yml b/templates/link-in-bio/.github/workflows/upgrade.yml index 9a231155..f564f163 100644 --- a/templates/link-in-bio/.github/workflows/upgrade.yml +++ b/templates/link-in-bio/.github/workflows/upgrade.yml @@ -19,13 +19,17 @@ permissions: contents: write pull-requests: write +# Prevent duplicate upgrade runs +concurrency: + group: upgrade-${{ github.ref }} + cancel-in-progress: true + jobs: upgrade: name: Upgrade if: github.repository_owner != 'HugoBlox' runs-on: ubuntu-latest - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + timeout-minutes: 15 steps: - name: Checkout uses: actions/checkout@v4 @@ -33,20 +37,20 @@ jobs: fetch-depth: 0 - name: Setup Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: - node-version: '20' + node-version: '22' - name: Setup pnpm uses: pnpm/action-setup@v4 with: - package_json_path: templates/link-in-bio/package.json + package_json_path: ./package.json run_install: false - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '1.21' + go-version: '1.23' - name: Setup Hugo uses: peaceiris/actions-hugo@v3 @@ -56,6 +60,7 @@ jobs: - name: Run Upgrade CLI env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Use manual input or default to stable for scheduled runs VERSION_TYPE: ${{ inputs.version_type || 'Stable' }} run: | @@ -68,6 +73,7 @@ jobs: echo "Running upgrade with flags: $FLAGS" pnpm dlx hugoblox@latest upgrade $FLAGS + - name: Create Pull Request uses: peter-evans/create-pull-request@v6 with: @@ -84,7 +90,7 @@ jobs: **Verification:** - [ ] Check the Deploy Preview to ensure everything looks correct. - [ ] Merge this PR to apply the updates. - branch: "chore/upgrade-hugoblox" + branch: "chore/upgrade-hugoblox-${{ github.run_id }}" delete-branch: true base: main labels: | diff --git a/templates/link-in-bio/hugoblox.yaml b/templates/link-in-bio/hugoblox.yaml index 601ae0d7..27b4d00f 100644 --- a/templates/link-in-bio/hugoblox.yaml +++ b/templates/link-in-bio/hugoblox.yaml @@ -1,5 +1,8 @@ build: hugo_version: '0.154.5' +deploy: + # Deployment target: github-pages, netlify, vercel, cloudflare, or none + host: 'github-pages' template: id: "link-in-bio" name: "Link in Bio" diff --git a/templates/markdown-slides/.github/workflows/build.yml b/templates/markdown-slides/.github/workflows/build.yml new file mode 100644 index 00000000..f76ec93b --- /dev/null +++ b/templates/markdown-slides/.github/workflows/build.yml @@ -0,0 +1,111 @@ +name: Build + +env: + NODE_VERSION: '20' + +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@v4 + 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@v4 + + - name: Get Hugo Version + id: hugo-version + run: | + VERSION=$(grep "hugo_version" hugoblox.yaml | awk '{print $2}' | tr -d "'\""") + echo "HUGO_VERSION=$VERSION" >> $GITHUB_ENV + + - 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: 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@v4 + 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@v4 + with: + path: resources/ + key: ${{ runner.os }}-hugo-resources-${{ hashFiles('assets/**/*', 'config/**/*', + 'hugo.yaml', 'package.json') }} + restore-keys: | + ${{ runner.os }}-hugo-resources- + + - 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 + + - 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 diff --git a/templates/markdown-slides/.github/workflows/deploy.yml b/templates/markdown-slides/.github/workflows/deploy.yml index fc593765..14d51016 100644 --- a/templates/markdown-slides/.github/workflows/deploy.yml +++ b/templates/markdown-slides/.github/workflows/deploy.yml @@ -1,8 +1,5 @@ name: Deploy website to GitHub Pages -env: - NODE_VERSION: '20' - on: # Trigger the workflow every time you push to the `main` branch push: @@ -21,95 +18,39 @@ concurrency: cancel-in-progress: false jobs: - # Build website - build: + # Check deployment configuration + config: if: github.repository_owner != 'HugoBlox' runs-on: ubuntu-latest + outputs: + deploy-host: ${{ steps.check.outputs.host }} steps: - name: Checkout uses: actions/checkout@v4 with: - # Fetch history for Hugo's .GitInfo and .Lastmod - fetch-depth: 0 + sparse-checkout: hugoblox.yaml + sparse-checkout-cone-mode: false - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{ env.NODE_VERSION }} - - - name: Setup pnpm - if: hashFiles('package.json') != '' - uses: pnpm/action-setup@v4 - - - name: Get Hugo Version - id: hugo-version + - name: Check deploy host + id: check run: | - VERSION=$(grep "hugo_version" hugoblox.yaml | awk '{print $2}' | tr -d "'\"") - echo "HUGO_VERSION=$VERSION" >> $GITHUB_ENV + # Read deploy.host from hugoblox.yaml, default to github-pages + HOST=$(grep -A5 "^deploy:" hugoblox.yaml 2>/dev/null | grep "host:" | awk '{print $2}' | tr -d "'\""" || echo "github-pages") + HOST=${HOST:-github-pages} + echo "host=$HOST" >> $GITHUB_OUTPUT + echo "Deployment target: $HOST" - - 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: 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@v4 - 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@v4 - 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 - uses: actions/upload-pages-artifact@v4 - with: - path: ./public - - # Deploy website to GitHub Pages hosting - deploy: + # Build website using reusable workflow (always runs for CI) + build: + needs: config if: github.repository_owner != 'HugoBlox' - needs: build + uses: ./.github/workflows/build.yml + secrets: inherit + + # Deploy website to GitHub Pages hosting (only if configured) + deploy: + needs: [config, build] + if: needs.config.outputs.deploy-host == 'github-pages' # Grant GITHUB_TOKEN the permissions required to make a Pages deployment permissions: pages: write # to deploy to Pages diff --git a/templates/markdown-slides/.github/workflows/upgrade.yml b/templates/markdown-slides/.github/workflows/upgrade.yml index e320b7e6..f564f163 100644 --- a/templates/markdown-slides/.github/workflows/upgrade.yml +++ b/templates/markdown-slides/.github/workflows/upgrade.yml @@ -19,13 +19,17 @@ permissions: contents: write pull-requests: write +# Prevent duplicate upgrade runs +concurrency: + group: upgrade-${{ github.ref }} + cancel-in-progress: true + jobs: upgrade: name: Upgrade if: github.repository_owner != 'HugoBlox' runs-on: ubuntu-latest - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + timeout-minutes: 15 steps: - name: Checkout uses: actions/checkout@v4 @@ -33,20 +37,20 @@ jobs: fetch-depth: 0 - name: Setup Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: - node-version: '20' + node-version: '22' - name: Setup pnpm uses: pnpm/action-setup@v4 with: - package_json_path: templates/markdown-slides/package.json + package_json_path: ./package.json run_install: false - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '1.21' + go-version: '1.23' - name: Setup Hugo uses: peaceiris/actions-hugo@v3 @@ -56,6 +60,7 @@ jobs: - name: Run Upgrade CLI env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Use manual input or default to stable for scheduled runs VERSION_TYPE: ${{ inputs.version_type || 'Stable' }} run: | @@ -68,6 +73,7 @@ jobs: echo "Running upgrade with flags: $FLAGS" pnpm dlx hugoblox@latest upgrade $FLAGS + - name: Create Pull Request uses: peter-evans/create-pull-request@v6 with: @@ -84,7 +90,7 @@ jobs: **Verification:** - [ ] Check the Deploy Preview to ensure everything looks correct. - [ ] Merge this PR to apply the updates. - branch: "chore/upgrade-hugoblox" + branch: "chore/upgrade-hugoblox-${{ github.run_id }}" delete-branch: true base: main labels: | diff --git a/templates/markdown-slides/hugoblox.yaml b/templates/markdown-slides/hugoblox.yaml index 8ee3c89d..83ff2c20 100644 --- a/templates/markdown-slides/hugoblox.yaml +++ b/templates/markdown-slides/hugoblox.yaml @@ -1,5 +1,8 @@ build: hugo_version: '0.154.5' +deploy: + # Deployment target: github-pages, netlify, vercel, cloudflare, or none + host: 'github-pages' template: id: "markdown-slides" name: "Markdown Slides" diff --git a/templates/resume/.github/workflows/build.yml b/templates/resume/.github/workflows/build.yml new file mode 100644 index 00000000..f76ec93b --- /dev/null +++ b/templates/resume/.github/workflows/build.yml @@ -0,0 +1,111 @@ +name: Build + +env: + NODE_VERSION: '20' + +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@v4 + 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@v4 + + - name: Get Hugo Version + id: hugo-version + run: | + VERSION=$(grep "hugo_version" hugoblox.yaml | awk '{print $2}' | tr -d "'\""") + echo "HUGO_VERSION=$VERSION" >> $GITHUB_ENV + + - 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: 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@v4 + 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@v4 + with: + path: resources/ + key: ${{ runner.os }}-hugo-resources-${{ hashFiles('assets/**/*', 'config/**/*', + 'hugo.yaml', 'package.json') }} + restore-keys: | + ${{ runner.os }}-hugo-resources- + + - 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 + + - 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 diff --git a/templates/resume/.github/workflows/deploy.yml b/templates/resume/.github/workflows/deploy.yml index fc593765..14d51016 100644 --- a/templates/resume/.github/workflows/deploy.yml +++ b/templates/resume/.github/workflows/deploy.yml @@ -1,8 +1,5 @@ name: Deploy website to GitHub Pages -env: - NODE_VERSION: '20' - on: # Trigger the workflow every time you push to the `main` branch push: @@ -21,95 +18,39 @@ concurrency: cancel-in-progress: false jobs: - # Build website - build: + # Check deployment configuration + config: if: github.repository_owner != 'HugoBlox' runs-on: ubuntu-latest + outputs: + deploy-host: ${{ steps.check.outputs.host }} steps: - name: Checkout uses: actions/checkout@v4 with: - # Fetch history for Hugo's .GitInfo and .Lastmod - fetch-depth: 0 + sparse-checkout: hugoblox.yaml + sparse-checkout-cone-mode: false - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{ env.NODE_VERSION }} - - - name: Setup pnpm - if: hashFiles('package.json') != '' - uses: pnpm/action-setup@v4 - - - name: Get Hugo Version - id: hugo-version + - name: Check deploy host + id: check run: | - VERSION=$(grep "hugo_version" hugoblox.yaml | awk '{print $2}' | tr -d "'\"") - echo "HUGO_VERSION=$VERSION" >> $GITHUB_ENV + # Read deploy.host from hugoblox.yaml, default to github-pages + HOST=$(grep -A5 "^deploy:" hugoblox.yaml 2>/dev/null | grep "host:" | awk '{print $2}' | tr -d "'\""" || echo "github-pages") + HOST=${HOST:-github-pages} + echo "host=$HOST" >> $GITHUB_OUTPUT + echo "Deployment target: $HOST" - - 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: 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@v4 - 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@v4 - 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 - uses: actions/upload-pages-artifact@v4 - with: - path: ./public - - # Deploy website to GitHub Pages hosting - deploy: + # Build website using reusable workflow (always runs for CI) + build: + needs: config if: github.repository_owner != 'HugoBlox' - needs: build + uses: ./.github/workflows/build.yml + secrets: inherit + + # Deploy website to GitHub Pages hosting (only if configured) + deploy: + needs: [config, build] + if: needs.config.outputs.deploy-host == 'github-pages' # Grant GITHUB_TOKEN the permissions required to make a Pages deployment permissions: pages: write # to deploy to Pages diff --git a/templates/resume/.github/workflows/upgrade.yml b/templates/resume/.github/workflows/upgrade.yml index 8ea0325b..f564f163 100644 --- a/templates/resume/.github/workflows/upgrade.yml +++ b/templates/resume/.github/workflows/upgrade.yml @@ -19,13 +19,17 @@ permissions: contents: write pull-requests: write +# Prevent duplicate upgrade runs +concurrency: + group: upgrade-${{ github.ref }} + cancel-in-progress: true + jobs: upgrade: name: Upgrade if: github.repository_owner != 'HugoBlox' runs-on: ubuntu-latest - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + timeout-minutes: 15 steps: - name: Checkout uses: actions/checkout@v4 @@ -33,20 +37,20 @@ jobs: fetch-depth: 0 - name: Setup Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: - node-version: '20' + node-version: '22' - name: Setup pnpm uses: pnpm/action-setup@v4 with: - package_json_path: templates/resume/package.json + package_json_path: ./package.json run_install: false - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '1.21' + go-version: '1.23' - name: Setup Hugo uses: peaceiris/actions-hugo@v3 @@ -56,6 +60,7 @@ jobs: - name: Run Upgrade CLI env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Use manual input or default to stable for scheduled runs VERSION_TYPE: ${{ inputs.version_type || 'Stable' }} run: | @@ -68,6 +73,7 @@ jobs: echo "Running upgrade with flags: $FLAGS" pnpm dlx hugoblox@latest upgrade $FLAGS + - name: Create Pull Request uses: peter-evans/create-pull-request@v6 with: @@ -84,7 +90,7 @@ jobs: **Verification:** - [ ] Check the Deploy Preview to ensure everything looks correct. - [ ] Merge this PR to apply the updates. - branch: "chore/upgrade-hugoblox" + branch: "chore/upgrade-hugoblox-${{ github.run_id }}" delete-branch: true base: main labels: | diff --git a/templates/resume/hugoblox.yaml b/templates/resume/hugoblox.yaml index 06330faa..ddcff1a1 100644 --- a/templates/resume/hugoblox.yaml +++ b/templates/resume/hugoblox.yaml @@ -1,5 +1,8 @@ build: hugo_version: '0.154.5' +deploy: + # Deployment target: github-pages, netlify, vercel, cloudflare, or none + host: 'github-pages' template: id: "resume" name: "Resume" diff --git a/templates/startup-landing-page/.github/workflows/build.yml b/templates/startup-landing-page/.github/workflows/build.yml new file mode 100644 index 00000000..f76ec93b --- /dev/null +++ b/templates/startup-landing-page/.github/workflows/build.yml @@ -0,0 +1,111 @@ +name: Build + +env: + NODE_VERSION: '20' + +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@v4 + 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@v4 + + - name: Get Hugo Version + id: hugo-version + run: | + VERSION=$(grep "hugo_version" hugoblox.yaml | awk '{print $2}' | tr -d "'\""") + echo "HUGO_VERSION=$VERSION" >> $GITHUB_ENV + + - 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: 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@v4 + 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@v4 + with: + path: resources/ + key: ${{ runner.os }}-hugo-resources-${{ hashFiles('assets/**/*', 'config/**/*', + 'hugo.yaml', 'package.json') }} + restore-keys: | + ${{ runner.os }}-hugo-resources- + + - 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 + + - 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 diff --git a/templates/startup-landing-page/.github/workflows/deploy.yml b/templates/startup-landing-page/.github/workflows/deploy.yml index fc593765..14d51016 100644 --- a/templates/startup-landing-page/.github/workflows/deploy.yml +++ b/templates/startup-landing-page/.github/workflows/deploy.yml @@ -1,8 +1,5 @@ name: Deploy website to GitHub Pages -env: - NODE_VERSION: '20' - on: # Trigger the workflow every time you push to the `main` branch push: @@ -21,95 +18,39 @@ concurrency: cancel-in-progress: false jobs: - # Build website - build: + # Check deployment configuration + config: if: github.repository_owner != 'HugoBlox' runs-on: ubuntu-latest + outputs: + deploy-host: ${{ steps.check.outputs.host }} steps: - name: Checkout uses: actions/checkout@v4 with: - # Fetch history for Hugo's .GitInfo and .Lastmod - fetch-depth: 0 + sparse-checkout: hugoblox.yaml + sparse-checkout-cone-mode: false - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{ env.NODE_VERSION }} - - - name: Setup pnpm - if: hashFiles('package.json') != '' - uses: pnpm/action-setup@v4 - - - name: Get Hugo Version - id: hugo-version + - name: Check deploy host + id: check run: | - VERSION=$(grep "hugo_version" hugoblox.yaml | awk '{print $2}' | tr -d "'\"") - echo "HUGO_VERSION=$VERSION" >> $GITHUB_ENV + # Read deploy.host from hugoblox.yaml, default to github-pages + HOST=$(grep -A5 "^deploy:" hugoblox.yaml 2>/dev/null | grep "host:" | awk '{print $2}' | tr -d "'\""" || echo "github-pages") + HOST=${HOST:-github-pages} + echo "host=$HOST" >> $GITHUB_OUTPUT + echo "Deployment target: $HOST" - - 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: 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@v4 - 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@v4 - 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 - uses: actions/upload-pages-artifact@v4 - with: - path: ./public - - # Deploy website to GitHub Pages hosting - deploy: + # Build website using reusable workflow (always runs for CI) + build: + needs: config if: github.repository_owner != 'HugoBlox' - needs: build + uses: ./.github/workflows/build.yml + secrets: inherit + + # Deploy website to GitHub Pages hosting (only if configured) + deploy: + needs: [config, build] + if: needs.config.outputs.deploy-host == 'github-pages' # Grant GITHUB_TOKEN the permissions required to make a Pages deployment permissions: pages: write # to deploy to Pages diff --git a/templates/startup-landing-page/.github/workflows/upgrade.yml b/templates/startup-landing-page/.github/workflows/upgrade.yml index 272da76e..f564f163 100644 --- a/templates/startup-landing-page/.github/workflows/upgrade.yml +++ b/templates/startup-landing-page/.github/workflows/upgrade.yml @@ -19,13 +19,17 @@ permissions: contents: write pull-requests: write +# Prevent duplicate upgrade runs +concurrency: + group: upgrade-${{ github.ref }} + cancel-in-progress: true + jobs: upgrade: name: Upgrade if: github.repository_owner != 'HugoBlox' runs-on: ubuntu-latest - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + timeout-minutes: 15 steps: - name: Checkout uses: actions/checkout@v4 @@ -33,20 +37,20 @@ jobs: fetch-depth: 0 - name: Setup Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: - node-version: '20' + node-version: '22' - name: Setup pnpm uses: pnpm/action-setup@v4 with: - package_json_path: templates/startup-landing-page/package.json + package_json_path: ./package.json run_install: false - name: Setup Go uses: actions/setup-go@v5 with: - go-version: '1.21' + go-version: '1.23' - name: Setup Hugo uses: peaceiris/actions-hugo@v3 @@ -56,6 +60,7 @@ jobs: - name: Run Upgrade CLI env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Use manual input or default to stable for scheduled runs VERSION_TYPE: ${{ inputs.version_type || 'Stable' }} run: | @@ -68,6 +73,7 @@ jobs: echo "Running upgrade with flags: $FLAGS" pnpm dlx hugoblox@latest upgrade $FLAGS + - name: Create Pull Request uses: peter-evans/create-pull-request@v6 with: @@ -84,7 +90,7 @@ jobs: **Verification:** - [ ] Check the Deploy Preview to ensure everything looks correct. - [ ] Merge this PR to apply the updates. - branch: "chore/upgrade-hugoblox" + branch: "chore/upgrade-hugoblox-${{ github.run_id }}" delete-branch: true base: main labels: | diff --git a/templates/startup-landing-page/hugoblox.yaml b/templates/startup-landing-page/hugoblox.yaml index 9cefb8a3..56fc9d1a 100644 --- a/templates/startup-landing-page/hugoblox.yaml +++ b/templates/startup-landing-page/hugoblox.yaml @@ -1,5 +1,8 @@ build: hugo_version: '0.154.5' +deploy: + # Deployment target: github-pages, netlify, vercel, cloudflare, or none + host: 'github-pages' template: id: "landing-page" name: "Landing Page"