CI/CD: GitHub Actions → Cloudflare Pages
Kode Anda tinggal di repo GitHub privat (harryosmar/pangaea.id), dan setiap perubahan mengalir
lewat Pull Request. Inilah bagian yang mengubah "PR ter-merge" jadi "situs live ter-update" —
rangkaian CI/CD-nya, ujung ke ujung, lengkap dengan tiap perintah yang benar-benar Anda jalankan.
Satu fitur = satu Pull Request
Tak ada yang dirilis langsung ke main. Perubahan dimulai di branch, membuka PR, dan baru ter-merge
setelah cek-nya hijau. Merge hijau itulah yang menerbitkan situs.
Dua cara menyambungkan Pages
Ada dua cara mendapatkan deploy Cloudflare Pages. Keduanya jalan; kami pakai yang kedua, dan alasannya penting.
Cara mudah — integrasi Git native
Cara yang kami pakai — GitHub Actions
Repo sudah berisi .github/workflows/deploy.yml: ia menjalankan build + typecheck di tiap PR,
dan men-deploy ke Pages hanya setelah Anda menambahkan dua secret repository. Sampai itu ada, ia
tetap hijau tapi dorman — jadi Anda bisa pakai integrasi native sekarang dan beralih nanti.
File workflow-nya, dijelaskan
Seluruh pipeline ada di satu file yang sudah dibawa repo —
.github/workflows/deploy.yml.
Ini dia, sedikit dipangkas:
name: Deploy
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read # least-privilege: the job only reads the repo
jobs:
build-deploy:
runs-on: ubuntu-latest
env:
CF_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: 20
cache: npm
- run: npm ci
- run: npm run typecheck
- name: Build
run: npm run build # prerender → dist/ + csp-hash.mjs (its last step)
env:
VITE_GA_ID: ${{ vars.VITE_GA_ID }}
# Deploy ONLY on a push to main, and only once the token secret exists.
- name: Deploy to Cloudflare Pages
if: ${{ github.event_name == 'push' && env.CF_API_TOKEN != '' }}
uses: cloudflare/wrangler-action@v4
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: pages deploy apps/labs/dist --project-name=pangaea-id --branch=main
# After a real deploy, ping IndexNow so Bing/Yandex recrawl within minutes.
- name: Notify IndexNow (Bing/Yandex)
if: ${{ github.event_name == 'push' && env.CF_API_TOKEN != '' }}
continue-on-error: true
run: npm run indexnow -w @pangaea/labs
Langkah demi langkah:
on:— job berjalan di tiap push kemaindan tiap pull request kemain.permissions: contents: read— token GitHub job ini cuma bisa membaca repo; tak lebih.env: CF_API_TOKEN— memunculkan secret sekali agar langkah deploy bisa menguji apakah ia terisi.checkout+setup-node— clone repo dan pasang Node 20 dengan cache npm.npm ci— install bersih sesuai lockfile (reproducible, beda darinpm install).npm run typecheck— gate pertama. Error tipe menggagalkan job dan memblok PR.Build→npm run build— mem-prerender tiap halaman kedist/dan menjalankancsp-hash.mjsdi langkah terakhir (alasan kami build di sini, bukan di container Cloudflare).VITE_GA_IDdatang dari GitHub Actions Variable (publik by design; kalau kosong = GA4 tetap no-op).Deploy …— gate yang menentukan:if: github.event_name == 'push' && env.CF_API_TOKEN != ''. Jadi PR mem-build + typecheck tapi tak pernah men-deploy, dan sebelum secret-nya ada langkah ini cuma dilewati (job tetap hijau). Saat ia jalan,wrangler-actionmengunggahdist/ke project Pagespangaea-id.Notify IndexNow— gate yang sama, pluscontinue-on-error: true. Setelah deploy nyata ia menekan Bing/Yandex agar halaman baru/berubah di-crawl ulang dalam menit; kegagalan sesaat tak pernah merah-X deploy yang baik.
Rangkai deploy-nya: token → secret → Actions → Pages → domain
Ini jalur yang benar-benar dipakai situs. GitHub Actions mem-build (jadi csp-hash.mjs selalu jalan)
dan mengunggah ke Pages dengan wrangler. Satu push ke main = satu deploy live.
Langkah 1 — Buat project Pages (sekali)
wrangler pages deploy tidak membuat project otomatis — ia error Project not found [8000007].
Buat sekali dulu. Bisa lewat dashboard (Workers & Pages → Create → Pages → Use direct upload,
bukan "Connect to Git" → beri nama persis pangaea-id, yang harus cocok dengan --project-name di
workflow → Create), atau dari CLI:
npx wrangler login # membuka OAuth di browser, sekali saja
npx wrangler pages project create pangaea-id --production-branch=main
Langkah 2 — Buat token API hak-minimal
Profile → API Tokens → Create Token → Create Custom Token, persis:
- Token name —
github-actions-pages-deploy - Permission —
Account·Cloudflare Pages·Edit(yang ini saja, tak ada lagi) - Account Resources —
Include· akun Anda
Lalu Continue → Create, dan salin token sekarang — Cloudflare menampilkannya sekali saja.
Do
- Buat Custom Token dengan satu permission
Cloudflare Pages · Editsaja - Batasi ke satu akun Anda, dan salin nilainya segera
Don't
- Memberi
DNS/Zone/Workers/SSL—pages deploytak membutuhkannya, dan token sempit membatasi kerusakan kalau ia bocor - Memakai template jadi (mis. "Edit Cloudflare Workers" itu yang salah, terlalu luas)
Langkah 3 — Ambil Account ID Anda
Workers & Pages → sidebar kanan → Account ID (string hex 32 karakter).
Langkah 4 — Tambah dua secret GitHub
Repo → Settings → Secrets and variables → Actions → tab Secrets (bukan Variables) → New repository secret. Nama harus cocok persis:
CLOUDFLARE_API_TOKEN— token dari Langkah 2CLOUDFLARE_ACCOUNT_ID— ID dari Langkah 3
Langkah 5 — Deploy
Push atau merge ke main. Pantau GitHub → Actions → Deploy: langkah "Deploy … to Cloudflare
Pages" berubah dari skipped ke success, dan pangaea-id.pages.dev jadi live. Langkah terakhir
"Notify IndexNow" lalu menekan Bing/Yandex agar halaman baru/berubah di-crawl ulang dalam menit —
best-effort (continue-on-error), dan ia jalan hanya setelah deploy nyata.
Langkah 6 — Arahkan domain ke sana
Di Pages project → Custom domains → Set up a domain, tambahkan www.pangaea.id dan pangaea.id
(ini menukar record parkir dengan yang proxied yang benar). Lalu tambahkan redirect apex → www
301 — lihat Bagian 3 · Root → www.
Contekan
Seluruh pipeline dalam satu baris:
merge PR → Actions build (npm run build → csp-hash) → wrangler pages deploy → npm run indexnow → live di www.pangaea.id dalam ~30d
Roll back kapan pun di Pages → Deployments → Rollback (instan, tanpa build ulang). Verifikasi rangkaiannya, read-only:
gh run list --branch main --limit 1 # run "Deploy" terbaru harusnya: success
curl -sI https://pangaea-id.pages.dev/ # 200 begitu project punya satu deployment
Troubleshooting: deploy pertama bilang "project not found"
npx wrangler login # kalau belum login
npx wrangler pages project create pangaea-id --production-branch=main
npx wrangler pages deploy apps/labs/dist --project-name=pangaea-id
Tak yakin ia sudah ada? Daftar project Anda dulu — kalau pangaea-id ada, lewati langkah create dan
langsung deploy (atau push ke main):
npx wrangler pages project list
Jangan
- Terus mengulang deploy berharap berhasil. "Not found" berarti project-nya memang belum ada — buat sekali, lalu deploy.
Berikutnya
Pipeline ini merilis situs statis yang domainnya diarahkan Bagian 1. Cerita bahasa-sederhana kenapa Cloudflare Pages alih-alih VPS sewaan ada di catatan build kami, Rilis — Git → CI/CD → Pages; serah-terima DNS yang lebih dulu ada di Arahkan domain ke Cloudflare (DNS).
Sources