Skip to main content

Cloudflare API token fast fail

So I've been making a lot of changes on my blog recently and I ran into the issue a few times where the post would not get generated by Docusaurus after pushing the commit to GitHub.
This is mostly because I've configured Docusaurus to fail upon finding invalid tags or missing images or the like (For which I created other solutions that I'll document later), but in one case it was because the Cloudflare API token had expired and it got me to thinking about how I could fast-fail the GitHub action that rebuilds the site upon the push of a new post if the API key had expired.
This is partly because I rotate all my API keys frequently, typically every 30 days, even if they are just for a personal blog like this. It's simply good security practice and if you do it everywhere you quickly end up automating these little pain points.

So I utilized the simple curl command that Cloudflare provide for testing their API keys and adapted it for use in a GitHub workflow, you can see it below at the step: Validate Cloudflare Pages API token
This step will now fail in about 7 seconds of run time versus the 130 seconds that it typically took to get to the Publish to Cloudflare Pages and then only fail if the Cloudflare API key has expired...

name: Publish to Cloudflare Pages

on:
workflow_dispatch:
push:
branches:
- main
paths-ignore:
- ".github/workflows/**"
- "drafts/**"
- "tags.yaml"
- ".gitignore"
- "README.md"
- "LICENSE"
- "new_post.sh"
- "update_tags.sh"

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
CLOUDFLARE_API_TOKEN: ${{secrets.CLOUDFLARE_PAGES_API_TOKEN}}
CLOUDFLARE_ACCOUNT_ID: ${{secrets.CLOUDFLARE_ACCOUNT_ID}}
CLOUDFLARE_PAGES_PROJECT: "futureops2024"
gitHubToken: ${{ secrets.GITHUB_TOKEN }}

jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
deployments: write
steps:
- name: Verify Cloudflare Pages API token
run: |
set -euo pipefail
if [[ -z "${CLOUDFLARE_API_TOKEN:-}" ]]; then
printf "Error: CLOUDFLARE_API_TOKEN secret is not configured.\n"
exit 1
fi
STATUS=$(curl \
--fail \
--silent \
--show-error \
--header "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" \
https://api.cloudflare.com/client/v4/accounts/"${CLOUDFLARE_ACCOUNT_ID}"/tokens/verify | jq -r '.result.status // empty')
if [[ -z "${STATUS}" ]]; then
printf "Error: Failed to parse Cloudflare token verification response.\n"
exit 1
fi
if [[ "${STATUS}" != "active" ]]; then
printf "Error: Cloudflare Pages API token verification failed (status: ${STATUS})\n"
exit 1
fi
printf "✅ Cloudflare API token is active.\n"

- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Install Node
uses: actions/setup-node@v6
with:
node-version: 25

- name: Install dependencies
run: |
npm install

- name: Build the website
run: |
npm run clear
npm run build

- name: Publish to Cloudflare Pages
run: |
npx wrangler pages deploy build \
--project-name "${CLOUDFLARE_PAGES_PROJECT}" \
--branch main \
--commit-dirty=true