Automate Cloudflare and SpinupWP Cache Purges with Git Hooks
The Core Insight: A local Git pre-push hook that calls the Cloudflare and SpinupWP APIs automatically clears your cache on every push, with nothing to configure on the production server.
There’s a version of this conversation I’ve had more times than I care to count. I push a change, send the client an email saying it’s live, and they write back: “I don’t see it on my end.” And I already know what happened before I even log in to check. The cache hasn’t cleared.
So now I have to send the follow-up explaining what a cache is, why it holds onto the old version, and that I’m going to go clear it. Then another “okay, try now.” Sometimes they see it. Sometimes their browser is also caching things and I have to explain that too. The whole exchange makes it look like the deployment didn’t work, even though it went fine. It’s one of those things that’s easy to brush off as “just part of the job,” but it doesn’t have to be.
The fix is a Git hook that hits the Cloudflare and SpinupWP APIs automatically every time you push. The cache gets cleared as part of the push. No extra step, no follow-up email.
Understanding Git Pre-Push Hooks for Automation
Git has hooks built in. They’re shell scripts that fire automatically at different points in the Git workflow. The one we want is pre-push, which runs on your local machine right before Git sends the push to the remote. That timing is perfect because it means the cache is already cleared by the time the code lands on the server.
The hook file lives at .git/hooks/pre-push inside your project. It’s just a shell script, and Git runs it automatically. If it exits with an error, the push gets cancelled. If it exits clean, the push goes through and the caches are already gone.
How to Create the Automated Cache Purge Script
You’ll need a few things before writing the script. From Cloudflare: your Zone ID (on the Overview page of your domain) and an API token with the “Cache Purge” permission, created under Profile > API Tokens. From SpinupWP: an API token from your account settings and the site ID for the site you’re working on.
Create the hook file:
nano .git/hooks/pre-push
Add this:
#!/bin/bash
CLOUDFLARE_ZONE_ID="your_zone_id_here"
CLOUDFLARE_API_TOKEN="your_cloudflare_token_here"
SPINUPWP_API_TOKEN="your_spinupwp_token_here"
SPINUPWP_SITE_ID="your_site_id_here"
# Purge Cloudflare cache
curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$CLOUDFLARE_ZONE_ID/purge_cache" \
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{"purge_everything":true}'
echo "Cloudflare cache purged."
# Purge SpinupWP page cache
curl -s -X POST "https://api.spinupwp.app/v1/sites/$SPINUPWP_SITE_ID/page-cache/purge" \
-H "Authorization: Bearer $SPINUPWP_API_TOKEN" \
-H "Accept: application/json"
echo "SpinupWP cache purged."
Make it executable:
chmod +x .git/hooks/pre-push
That’s it. The next time you git push, both caches clear automatically before the push completes. SpinupWP also has a separate object cache purge endpoint at /v1/sites/{id}/object-cache/purge if you need that too. Same format, just a second curl call.
Pro-Tip: For better security, consider using environment variables for your
API_TOKENSinstead of hardcoding them into the script.
Benefits of Local vs. Server-Side Cache Automation
The thing I like about using a local pre-push hook instead of a server-side hook is that there’s nothing to configure on the production server. No SSH access needed, no hook file to manage remotely. Everything lives on your local machine and talks to the APIs directly. You set it up once per project and forget about it.
It’s a small automation, but the payoff is that you stop looking like something went wrong when nothing did. That’s worth the fifteen minutes it takes to set up.
FAQs: Scaling Your Git Hook Workflow
Not necessarily. Sites that don’t use Cloudflare or SpinupWP don’t need it. But if those are part of your standard stack for client sites, this is worth adding to each project.
The push will still go through since the hook exits clean regardless. If you want stricter behavior, you can add error checking to exit with a non-zero code on failure, which will cancel the push. For most setups, though, a failed purge is just a manually-clear-it-this-one-time situation.
The easiest way is to open the site in your SpinupWP dashboard and grab the ID from the URL. You can also hit the /v1/sites endpoint with your API token to get a list of all your sites and their IDs.
Local Git hooks fire regardless of where you’re pushing to, so yes. The pre-push hook runs on your machine before the push goes out, whether the remote is GitHub, GitLab, a VPS, or anything else.