Skip to content

GitHub Pages Setup

Set up a GitHub Pages site for an OpsDev.nz module with a custom domain.

Goal

Publish Zensical documentation for an OpsDev.nz module through GitHub Pages with a custom domain (e.g., op.opsdev.nz, octodns-metaname.opsdev.nz).

Prerequisites

  • GitHub access with administrator access to the repository.
  • gh installed and authenticated.
  • uv available in the OpsDev.nz repository.
  • OctoDNS and the Metaname test credentials available through the normal environment and 1Password workflow.
  • A GitHub Actions workflow for Zensical docs deployment (see Step 3).

All commands assume the OpsDev.nz repository root and use uv run to execute within the project venv. If the venv doesn't exist, uv run creates it automatically.

Do not put API tokens or secret values in the repository, workflow, or DNS zone. The DNS record and GitHub Pages configuration are not substitutes for access control.

1Password prerequisite

Before running OctoDNS validation, plans, or applies:

  1. Unlock/sign in to 1Password using the normal local CLI workflow.
  2. Load the Metaname test account credentials through the existing env/metaname-test.env configuration.
  3. Select the OpsDev.nz resolver hook:
export OCTODNS_METANAME_SECRET_RESOLVER="octodns_metaname.op_opsdevnz_hooks:resolve"
  1. Confirm that the resolver can access the test account without printing the secret values.

Use the test credentials only for the test zone configuration. Do not load production credentials while testing this change.

❯ eval $(op signin)
Enter the password for john.opsdevnz@gmail.com at my.1password.com:

❯ source env/metaname-test.env

1. Test the DNS change

Add a clearly temporary test name to the test zone rather than the production record. For example, after confirming the target with GitHub:

'module-pages-test':
  - ttl: 3600
    type: CNAME
    value: startmeup-nz.github.io.

Review the entire zone diff before running OctoDNS.

Run the validation and dry-run from the repository root:

uv run octodns-validate --config-file octodns/configs/metaname.test.yaml
uv run octodns-sync --config-file octodns/configs/metaname.test.yaml

Without --doit, octodns-sync prints the proposed changes and does not apply them. Review the plan and confirm that only the intended test CNAME is added.

When the plan is correct, apply the test change through the existing manual test deployment process. Do not add --doit until the plan has been reviewed.

Verify propagation using a resolver that is not relying only on local cache:

dig +short CNAME module-pages-test.opstest.nz

The result should match the GitHub Pages target. Remove the temporary test record after the test has served its purpose, and run another OctoDNS plan to confirm the cleanup.

2. Research the custom-domain requirements

Read the relevant GitHub documentation:

For a subdomain, GitHub requires a CNAME record pointing at the repository owner's Pages hostname. For the startmeup-nz organization, that is:

startmeup-nz.github.io.

If the repository lives under a different owner (e.g., a personal account or another organization), confirm the target in the GitHub Pages settings before applying DNS changes.

3. Confirm the GitHub Pages workflow

Ensure the module has a GitHub Actions workflow for docs deployment. A typical workflow:

  1. Triggers on pushes to main;
  2. Checks out the repository;
  3. Installs Python and Zensical;
  4. Builds the docs/ site;
  5. Uploads the site/ directory as a Pages artifact; and
  6. Deploys it with the GitHub Pages deployment action.

Verify the workflow exists at:

modules/<module>/.github/workflows/docs.yml

Verify the build works locally from the module directory:

cd modules/<module>
uv sync --extra dev
uv run zensical build --clean

The build must complete without errors. Do not start zensical serve from an automated runbook session; the human operator controls long-running servers.

4. Configure GitHub Pages for the repository

In the GitHub repository:

  1. Open Settings → Pages.
  2. Set the publishing source to GitHub Actions.
  3. Confirm the workflow has the required pages: write and id-token: write permissions.
  4. Confirm the github-pages environment is available to the repository.
  5. Merge the workflow to main and wait for the Documentation workflow to complete.
  6. Open the default project Pages URL shown by GitHub and confirm the Zensical site renders.

Do not configure the production custom domain until the test DNS process below has been completed successfully.

5. Configure the production custom domain

After the test passes:

  1. In GitHub Settings → Pages, enter the custom domain (e.g., octodns-metaname.opsdev.nz).
  2. Confirm the Pages UI accepts the domain and reports the expected DNS target.
  3. Add the production CNAME to the zone file.

The expected shape (using octodns-metaname as an example):

'octodns-metaname':
  - ttl: 3600
    type: CNAME
    value: startmeup-nz.github.io.
  1. Run uv run octodns-validate and a dry-run uv run octodns-sync against the production configuration.
  2. Review the production plan carefully before applying it.
  3. Apply the production DNS change through the guarded manual process.

GitHub may create or require a CNAME file as part of custom-domain configuration. Follow the Pages settings and workflow guidance rather than creating a conflicting file by hand.

6. Verify the published site

After the DNS record propagates and GitHub verifies the domain, Let's Encrypt provisions an SSL certificate. This can take a few minutes to an hour.

Once the certificate is active:

  1. Enable Enforce HTTPS in GitHub Settings → Pages.
  2. Verify the site loads at https://<custom-domain>/.

Verify all of the following:

dig +short CNAME <custom-domain>
curl --head --location https://<custom-domain>/

Then check manually:

  • the certificate is valid for the custom domain;
  • the home page renders;
  • navigation links do not point at local-only paths; and
  • a new documentation change merged to main triggers a successful Pages deployment.

7. Rollback

If the DNS change is wrong:

  1. Stop applying further changes.
  2. Restore the previous zone entry in the relevant YAML file.
  3. Run uv run octodns-validate and a dry-run plan.
  4. Apply the rollback through the same guarded process.
  5. Check the GitHub Pages custom-domain setting and deployment status.

Do not delete the GitHub repository or Pages environment as a first response; DNS rollback is the smaller and more reversible action.