Docs Deploy
Reusable workflow for building and deploying VitePress sites to Cloudflare Pages. Includes content hash gating to skip unnecessary deploys when documentation sources have not changed.
Publication policy
Use this workflow only for content approved for publication. When the site contains sensitive operational guides, Cloudflare Pages publication must be protected by an authentication layer before exposure.
Trigger
yaml
on:
workflow_call:Called via uses: from the repository's documentation deploy workflow.
Inputs
| Input | Type | Default | Required | Description |
|---|---|---|---|---|
docs-path | string | -- | Yes | Path to the VitePress docs directory (e.g. docs-site/, docs/) |
project-name | string | -- | Yes | Cloudflare Pages project name (e.g. my-project-docs) |
deploy-url | string | -- | Yes | URL to check the current deployed hash against (e.g. https://my-project-docs.pages.dev) |
node-version | string | '22' | No | Node.js version |
build-command | string | 'npm run docs:build' | No | Build command to run inside docs-path |
force | boolean | false | No | Force deploy ignoring content hash |
Secrets
| Secret | Description |
|---|---|
CLOUDFLARE_API_TOKEN | Cloudflare API token with Pages deploy scope |
CLOUDFLARE_ACCOUNT_ID | Cloudflare account ID |
Permissions
yaml
permissions:
contents: read
deployments: writeJob: deploy
Runs on ubuntu-latest:
- Checkout the code.
- Compute content hash — calculates SHA-256 of all
.md,.ts, and.jsonfiles in the docs directory (excludingnode_modules,dist, andcache). - Compare with deployed hash — requests
<deploy-url>/.content-hashand compares:- If
force: true: deploys regardless. - If hashes differ: deploys.
- If hashes match: skips deploy.
- If
- Setup Node.js with npm cache.
- Install and build —
npm ci+ configured build command. - Write content hash — saves the hash to
.vitepress/dist/.content-hashfor future comparisons. - Deploy to Cloudflare Pages — via
cloudflare/wrangler-action@v3.
Content Hash Gating
The content hash mechanism prevents redundant deploys:
Calculate SHA-256 of sources (.md, .ts, .json)
│
▼
Fetch deployed hash from <url>/.content-hash
│
┌──────┴──────┐
│ │
Different Same
│ │
▼ ▼
Deploy Skip deployThe .content-hash file is saved at the deploy root and serves as a reference for the next run.
Usage example
yaml
# .github/workflows/docs.yml
name: Deploy Docs
on:
push:
branches: [main]
paths:
- 'docs-site/**'
jobs:
deploy:
uses: middag-io/.github-private/.github/workflows/docs-deploy.yml@workflows-v1
with:
docs-path: docs-site/
project-name: my-project-docs
deploy-url: https://my-project-docs.pages.dev
secrets: inheritForce deploy
yaml
jobs:
deploy:
uses: middag-io/.github-private/.github/workflows/docs-deploy.yml@workflows-v1
with:
docs-path: docs-site/
project-name: my-project-docs
deploy-url: https://my-project-docs.pages.dev
force: true
secrets: inherit