Skip to content

Deployment

This page covers how the main website deploys, how to confirm a deployment, what to do when one fails, and how to roll back. The documentation site deploys separately. See Maintaining These Docs.

What triggers a deployment

Every push or merge to main in Douglasebhoman/douglasebhoman.github.io runs the workflow Build and Deploy to GitHub Pages, defined in .github/workflows/deploy.yml.

What the workflow does

Step What happens
Checkout Checks out the commit that was pushed
Setup Node Installs Node 22 and restores the npm cache
Install dependencies npm ci installs the exact versions in package-lock.json
Drift check bash scripts/drift-check.sh fails the build if any source page contains a retired claim
Build with Eleventy npx @11ty/eleventy builds the site into _site/
Upload Pages artifact Packages _site/ as the deployment artefact
Deploy to GitHub Pages Publishes the artefact to the github-pages environment

The repository is not served as-is. Only the contents of _site/ are published, and _site/ exists only inside the workflow run.

Required repository settings

Under Settings → Pages, the source must be GitHub Actions. If it is set to Deploy from a branch, GitHub ignores the workflow's artefact and serves the raw repository, which shows blog posts without their layout.

What gets deployed

  • Every HTML and Nunjucks page in the repository, processed by Eleventy
  • Every blog post, wrapped in _includes/layouts/post.html
  • sitemap.xml, generated by sitemap.njk
  • assets/, styles.css, CNAME, .nojekyll, robots.txt and 404.html, copied through unchanged
  • Nothing from scripts/, which the Eleventy configuration excludes

Custom domain configuration

  1. A CNAME file in the repository root contains douglasebhoman.com. Eleventy copies it into the build.
  2. A CNAME record in Cloudflare points douglasebhoman.com to douglasebhoman.github.io.
  3. The custom domain is confirmed under Settings → Pages.
  4. GitHub issues and renews the HTTPS certificate through Let's Encrypt.
  5. Cloudflare records are set to DNS only (grey cloud), with no proxy.

Cloudflare proxy must remain disabled

Enabling the proxy (orange cloud) stops GitHub from issuing or renewing the certificate.

Deployment time

The workflow usually finishes in under a minute: the build job, then the deploy job. Allow a few more minutes before the change shows everywhere, because browsers and the CDN cache pages.

Verifying a deployment

  1. Open the Actions tab and find the Build and Deploy to GitHub Pages run for your commit. Both jobs, build and deploy, must show a green tick.
  2. Open the changed page in a private window, so the browser cache does not show you the old version.
  3. For a new blog post, check that it appears on /blog/, in the "Latest writing" strip on /work/, and in https://douglasebhoman.com/sitemap.xml.

Troubleshooting

Symptom Likely cause Fix
build job fails at Install dependencies package-lock.json is missing or does not match package.json Run npm install locally, commit the updated lockfile, and push
build job fails at Drift check A page contains a retired claim Run bash scripts/drift-check.sh locally, correct the page, and push
build job fails at Build with Eleventy Template or front matter error Run npm run build locally. Eleventy names the file and line. Fix it and push
deploy job fails or waits Pages source is not GitHub Actions, or the github-pages environment blocks the branch Check Settings → Pages and Settings → Environments → github-pages
Run is green but the page has not changed Browser or CDN cache Open the page in a private window or hard refresh. Wait two minutes and retry
Blog posts appear unstyled, with no navigation Pages is serving the raw repository instead of the build Set the Pages source to GitHub Actions and re-run the workflow
New post is missing from the blog index and sitemap The post has no part value, or is marked draft: true Fix the front matter. See Content Guide
build job fails at Build with Eleventy, naming isoDate or publishDate A post's publishDate is missing or not in the form September 25, 2026 Correct the date in the post's front matter. See Content Guide
build job fails at Build with Eleventy, naming jsonString A post is missing title, description or canonicalUrl, or one of these, a keyword or a citation contains an HTML entity such as ’ Add the field, or type the character itself. See Content Guide
Whole site returns 404 or shows douglasebhoman.github.io CNAME file deleted, edited, or no longer copied by the build Restore CNAME containing only douglasebhoman.com, and confirm eleventy.config.js still copies it
Browser shows a certificate warning Cloudflare proxy switched on, or certificate not yet issued Set the Cloudflare record to DNS only. Under Settings → Pages, wait for the certificate, then tick Enforce HTTPS
Newsletter form or comments missing Third-party script blocked or offline Check the browser console. MailerLite and Giscus load from external domains

Rolling back

There are two ways to roll back. Use the first when the live site is broken and you need it fixed in minutes. Always finish with the second, so main and the live site agree.

1. Re-run the last good deployment

  1. Open Actions and select Build and Deploy to GitHub Pages.
  2. Open the most recent successful run from before the problem.
  3. Choose Re-run all jobs. The run rebuilds and republishes the commit it originally ran on.

The live site is now restored, but main still contains the bad change. The next push will publish it again.

2. Revert the change on main

  1. Find the commit that caused the problem:

    git switch main
    git pull origin main
    git log --oneline -n 10
    
  2. Revert it. This creates a new commit that reverses the change and keeps the history:

    git revert <commit-sha>
    

    For a merge commit, keep the main line:

    git revert -m 1 <merge-commit-sha>
    
  3. Confirm the site builds, then push:

    npm run build
    git push origin main
    
  4. Verify as described in Verifying a deployment.

  5. Fix the original change on a branch and merge it again when it is ready.