-
Notifications
You must be signed in to change notification settings - Fork 0
163 lines (142 loc) · 8.31 KB
/
Copy pathdeploy.yml
File metadata and controls
163 lines (142 loc) · 8.31 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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
name: Deploy to Cloudflare
on:
push:
branches: ['main']
workflow_dispatch:
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Terraform
uses: hashicorp/setup-terraform@v2.0.3
with:
terraform_version: 1.6.4
- name: Use Node.js 22.x
uses: actions/setup-node@v3
with:
node-version: 22.x
cache: 'npm'
# Automatically get an account id via the API Token
# if secrets.CLOUDFLARE_ACCOUNT_ID is not set.
- name: Fetch Account ID
id: fetch_account_id
run: |
if [[ -n "${{ secrets.CLOUDFLARE_ACCOUNT_ID }}" ]]; then
ACCOUNT_ID="${{ secrets.CLOUDFLARE_ACCOUNT_ID }}"
echo "Using provided CLOUDFLARE_ACCOUNT_ID from secrets."
else
ACCOUNT_ID=$(curl -X GET "https://api.cloudflare.com/client/v4/accounts" -H "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" -H "Content-Type:application/json" | jq ".result[0].id" -r)
if [[ "$ACCOUNT_ID" == "null" ]]; then
echo "Failed to get an account id, please make sure you have set up CLOUDFLARE_API_TOKEN correctly!"
exit 1
fi
fi
echo 'account_id='$ACCOUNT_ID >> $GITHUB_OUTPUT
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
# This is a temporary workaround to fix issue #13
# On a new Cloudflare account, the terraform apply will fail with `workers.api.error.subdomain_required`
# This may be due to the account not having a worker subdomain yet, so we create a dummy worker and then delete it.
# Cloudflare should allocate a worker subdomain after this.
# https://github.com/cloudflare/terraform-provider-cloudflare/issues/3304
- name: Create worker subdomain (temporary workaround)
id: create_dummy_worker
run: |
curl --request PUT --fail-with-body \
--url https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/workers/scripts/dummy-ib4db6ntj5csdef3 \
--header 'Authorization: Bearer '$CLOUDFLARE_API_TOKEN \
--header 'Content-Type: application/javascript' \
--data 'addEventListener('\''fetch'\'', (event) => event.respondWith(new Response('\''OK'\'')))'\
curl --request DELETE --fail-with-body \
--url https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/workers/scripts/dummy-ib4db6ntj5csdef3 \
--header 'Authorization: Bearer '$CLOUDFLARE_API_TOKEN \
--header 'Content-Type: application/json'
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ steps.fetch_account_id.outputs.account_id }}
- name: Install packages
run: |
npm install
cd worker
npm install
- name: Build worker
run: |
cd worker
npx wrangler deploy src/index.ts --outdir dist --dry-run
- name: Build page
run: |
npx @cloudflare/next-on-pages
- name: Remove durable objects bindings (temporary workaround)
continue-on-error: true
# This is a workaround to fix Cloudflare provider 4.x import crash when there's a durable object binding.
run: |
# Get bindings without durable objects
NEW_BINDINGS=$(curl --request GET --fail-with-body \
--url https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/workers/scripts/uptimeflare_worker/settings \
--header 'Authorization: Bearer '$CLOUDFLARE_API_TOKEN \
--header 'Content-Type: application/json' | jq '.result.bindings | map(select(.type != "durable_object_namespace"))' -jc)
echo "New bindings: $NEW_BINDINGS"
# Remove durable objects bindings
curl --request PATCH --fail-with-body \
--url https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/workers/scripts/uptimeflare_worker/settings \
--header 'Authorization: Bearer '$CLOUDFLARE_API_TOKEN \
-F 'settings={"bindings":'$NEW_BINDINGS'}'
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ steps.fetch_account_id.outputs.account_id }}
- name: Deploy using Terraform
# As we don't save terraform state somewhere, we need to import the existing resources
run: |
terraform init
KV_ID=$(curl https://api.cloudflare.com/client/v4/accounts/$TF_VAR_CLOUDFLARE_ACCOUNT_ID/storage/kv/namespaces\?per_page\=100 --header 'Authorization: Bearer '$CLOUDFLARE_API_TOKEN | jq -r '.result[] | select(.title == "uptimeflare_kv") | .id')
if [ -n "$KV_ID" ]; then
echo "Importing existing resources..."
terraform import cloudflare_workers_kv_namespace.uptimeflare_kv "$TF_VAR_CLOUDFLARE_ACCOUNT_ID/$KV_ID"
terraform import cloudflare_worker_script.uptimeflare "$TF_VAR_CLOUDFLARE_ACCOUNT_ID/uptimeflare_worker"
terraform import cloudflare_worker_cron_trigger.uptimeflare_worker_cron "$TF_VAR_CLOUDFLARE_ACCOUNT_ID/uptimeflare_worker"
terraform import cloudflare_pages_project.uptimeflare "$TF_VAR_CLOUDFLARE_ACCOUNT_ID/uptimeflare"
else
echo "KV namespace not found, first-time setup."
fi
terraform apply -auto-approve -input=false
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
TF_VAR_CLOUDFLARE_ACCOUNT_ID: ${{ steps.fetch_account_id.outputs.account_id }}
# Terraform Cloudflare provider 4.x doesn't support durable objects, provider 5.x has unresolved issues blocking the deployment. (cloudflare/terraform-provider-cloudflare#5412)
# So I have to manually add durable objects bindings here.
- name: Add durable objects bindings
run: |
# Get current bindings
CURRENT_BINDINGS=$(curl --request GET --fail-with-body \
--url https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/workers/scripts/uptimeflare_worker/settings \
--header 'Authorization: Bearer '$CLOUDFLARE_API_TOKEN \
--header 'Content-Type: application/json' | jq '.result.bindings' -jc)
CURRENT_BINDINGS="${CURRENT_BINDINGS:1:-1}"
echo "Current bindings: $CURRENT_BINDINGS"
# Try migration first (required for the new durable object class, ignore failures)
curl --request PATCH \
--url https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/workers/scripts/uptimeflare_worker/settings \
--header 'Authorization: Bearer '$CLOUDFLARE_API_TOKEN \
-F 'settings={"bindings":[{"type":"durable_object_namespace","name":"REMOTE_CHECKER_DO","class_name":"RemoteChecker"},'$CURRENT_BINDINGS'],"migrations":{"new_sqlite_classes":["RemoteChecker"],"new_tag":"v1"}}'
# Actually add the binding
curl --request PATCH --fail-with-body \
--url https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/workers/scripts/uptimeflare_worker/settings \
--header 'Authorization: Bearer '$CLOUDFLARE_API_TOKEN \
-F 'settings={"bindings":[{"type":"durable_object_namespace","name":"REMOTE_CHECKER_DO","class_name":"RemoteChecker"},'$CURRENT_BINDINGS']}'
# By the ways enable logs
curl --request PATCH \
--url https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/workers/scripts/uptimeflare_worker/script-settings \
--header 'Authorization: Bearer '$CLOUDFLARE_API_TOKEN \
--header 'Content-Type: application/json' \
-d '{"observability":{"enabled":true}}'
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ steps.fetch_account_id.outputs.account_id }}
# Currently Terraform Cloudflare provider doesn't support direct upload, use wrangler to upload instead.
- name: Upload pages
run: |
npx wrangler pages deploy .vercel/output/static --project-name uptimeflare
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ steps.fetch_account_id.outputs.account_id }}