Deploy to GitHub Pages workflow (Modernizr/Modernizr)
The Deploy to GitHub Pages workflow from Modernizr/Modernizr, explained and optimized by Latchkey.
CI health: C - fair
Point runs-on at Latchkey and get run de-duplication, job timeouts, self-healing for flaky steps, and up to 58% lower cost, applied automatically.
What it does
This is the Deploy to GitHub Pages workflow from the Modernizr/Modernizr repository, a real project running GitHub Actions. It is shown here with attribution under its MIT license.
Below, Latchkey shows a faster, safer version produced by its optimization engine.
The workflow
name: Deploy to GitHub Pages
on:
push:
tags:
- 'v*' # Run only for tags that start with 'v' (e.g., v1.0, v2.1.3)
jobs:
# Build job
build:
# Specify runner + build & upload the static files as an artifact
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Installing Node
uses: actions/setup-node@v6
with:
node-version: 24
cache: npm
- name: Installing dependencies
run: npm ci
- name: Installing gulp command line interface
run: npm install gulp-cli
- name: Build static files
id: build
run: |
gulp gh-pages
- name: Upload static files as artifact
id: deployment
uses: actions/upload-pages-artifact@v3
with:
path: gh-pages/
# Deployment job
deploy:
# Add a dependency to the build job
needs: build
# Grant GITHUB_TOKEN the permissions required to make a Pages deployment
permissions:
pages: write # to deploy to Pages
id-token: write # to verify the deployment originates from an appropriate source
# Deploy to the github-pages environment
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
# Specify runner + deployment step
runs-on: ubuntu-latest
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
The same workflow, on Latchkey
Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.
name: Deploy to GitHub Pages on: push: tags: - 'v*' # Run only for tags that start with 'v' (e.g., v1.0, v2.1.3) concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: # Build job build: timeout-minutes: 30 # Specify runner + build & upload the static files as an artifact runs-on: latchkey-small steps: - name: Checkout code uses: actions/checkout@v6 - name: Installing Node uses: actions/setup-node@v6 with: node-version: 24 cache: npm - name: Installing dependencies run: npm ci - name: Installing gulp command line interface run: npm install gulp-cli - name: Build static files id: build run: | gulp gh-pages - name: Upload static files as artifact id: deployment uses: actions/upload-pages-artifact@v3 with: path: gh-pages/ # Deployment job deploy: timeout-minutes: 30 # Add a dependency to the build job needs: build # Grant GITHUB_TOKEN the permissions required to make a Pages deployment permissions: pages: write # to deploy to Pages id-token: write # to verify the deployment originates from an appropriate source # Deploy to the github-pages environment environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} # Specify runner + deployment step runs-on: latchkey-small steps: - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v4
What changed
- Run on Latchkey managed runners with one line (
runs-on), which apply the fixes below automatically and self-heal transient failures. This example useslatchkey-small; pick the runner size that fits the job. - Cancel superseded runs when a branch or PR gets a newer push.
- Add a job timeout so a hung step cannot burn hours of runner time.
What Latchkey heals here
This workflow has steps that commonly fail on transient issues (network, registries, flaky browsers). On Latchkey managed runners they are detected, retried, and self-healed instead of failing your build:
- Dependency installs
This workflow runs 2 jobs per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.