-
Notifications
You must be signed in to change notification settings - Fork 0
94 lines (89 loc) · 4.15 KB
/
Copy pathpurge-cache.yml
File metadata and controls
94 lines (89 loc) · 4.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
name: Purge Cloudflare cache after deploy
# Every push to main triggers a Cloudflare Pages deploy. Once the deploy
# finishes, this workflow purges the ontargetnotes.com zone cache so the
# custom domain (website.ontargetnotes.com) catches up to the latest
# build immediately instead of waiting on Cloudflare's CDN TTL.
on:
push:
branches: [main]
workflow_dispatch:
concurrency:
group: purge-cf-cache
cancel-in-progress: false
jobs:
wait-and-purge:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Wait for matching Cloudflare Pages deployment
env:
CF_API_TOKEN: ${{ secrets.CF_API_TOKEN }}
CF_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }}
CF_PAGES_PROJECT: ${{ secrets.CF_PAGES_PROJECT }}
COMMIT_SHA: ${{ github.sha }}
run: |
python3 <<'PY'
import json, os, sys, time, urllib.request, urllib.error
tok = os.environ.get('CF_API_TOKEN', '')
acct = os.environ.get('CF_ACCOUNT_ID', '')
proj = os.environ.get('CF_PAGES_PROJECT', '')
sha = os.environ.get('COMMIT_SHA', '')
# Fail fast and loud when secrets are missing. The earlier
# behavior built a URL with empty placeholders and looped
# against it for 12 minutes producing useless 7003 errors.
missing = [n for n, v in
(('CF_API_TOKEN', tok), ('CF_ACCOUNT_ID', acct),
('CF_PAGES_PROJECT', proj))
if not v]
if missing:
print(f"::error::Missing required GitHub Actions secret(s): {', '.join(missing)}. "
"Set them at /settings/secrets/actions on this repo.", file=sys.stderr)
sys.exit(2)
h = {'Authorization': f'Bearer {tok}', 'Accept': 'application/json'}
base = f'https://api.cloudflare.com/client/v4/accounts/{acct}/pages/projects/{proj}/deployments'
deadline = time.time() + 12 * 60
last_status = ''
while time.time() < deadline:
req = urllib.request.Request(f'{base}?per_page=20', headers=h)
try:
d = json.loads(urllib.request.urlopen(req, timeout=20).read())
except urllib.error.HTTPError as e:
print(f'CF API HTTPError {e.code}: {e.read().decode()[:300]}', file=sys.stderr)
time.sleep(8); continue
match = None
for r in d.get('result', []):
meta = ((r.get('deployment_trigger') or {}).get('metadata') or {})
if meta.get('commit_hash', '')[:8] == sha[:8]:
match = r; break
if not match:
print(f'no deployment yet for commit {sha[:8]}, waiting...')
time.sleep(10); continue
stages = match.get('stages') or []
last = stages[-1] if stages else {}
status_line = f"deploy {match['id'][:8]} stage={last.get('name')} status={last.get('status')}"
if status_line != last_status:
print(status_line)
last_status = status_line
if last.get('status') == 'success':
print('deploy succeeded — proceeding to purge.')
sys.exit(0)
if last.get('status') in ('failure', 'canceled'):
print(f"deploy ended with status={last.get('status')} — skipping purge.")
sys.exit(1)
time.sleep(8)
print('Timed out waiting for the CF Pages deploy.', file=sys.stderr)
sys.exit(1)
PY
- name: Purge ontargetnotes.com zone cache
env:
CF_API_TOKEN: ${{ secrets.CF_API_TOKEN }}
CF_ZONE_ID: ${{ secrets.CF_ZONE_ID }}
run: |
set -e
resp=$(curl -sS -X POST \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"purge_everything":true}' \
"https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/purge_cache")
echo "$resp"
echo "$resp" | python3 -c 'import json,sys; d=json.load(sys.stdin); sys.exit(0 if d.get("success") else 1)'