Deployment berbasis tag untuk Cloudflare Pages menggunakan GitHub Actions

Tue, December 17, 2024 — 17 min read

Sebagai front-end developer zaman sekarang, saya cukup dimanjakan oleh kemudahan integrasi Git dari Platform-as-a-Service (PaaS) seperti Vercel, Netlify, dan Cloudflare Pages untuk melakukan deployment. Hanya butuh klik-klik-klik untuk pengaturan awal dan push perubahan menggunakan Git untuk melakukan deployment secara terus-menerus. Rasanya, hidup tidak pernah semudah ini.

Di balik semua kemudahan tersebut, adakalanya kebutuhan kita sebagai developer tidak bisa dipenuhi oleh PaaS yang ada sehingga memerlukan langkah tambahan untuk memenuhi kebutuhan tersebut. Contohnya adalah ketika ingin melakukan deployment hanya pada saat ada tag terbaru di remote repository proyek kita—atau strategi deployment lain.

Pada artikel ini, saya ingin menulis langkah deployment yang saya lakukan untuk proyek saya yaitu: KaGet (Kawan Budget). Artikel ini akan menggunakan template proyek blog dari Astro. Sederhananya, alur deployment yang dilakukan akan seperti berikut:

  1. Setiap ada push ke branch main akan dianggap sebagai preview/staging deployment dengan URL-nya sendiri.
  2. Ketika ada tag baru yang di-push ke branch main, maka akan dianggap sebagai production deployment dengan https://kaget.mupin.dev/ sebagai URL-nya.

Saya menggunakan Cloudflare Pages sebagai hosting, GitHub Actions untuk CI/CD, dan GitHub Releases untuk mengatur tag dan catatan rilis.

Permasalahan

Hanya mendukung push-to-deploy

Secara default, Cloudflare Pages, Vercel, dan Netlify tidak mendukung pengaturan deployment berbasis tag. Oleh karena itu, peran GitHub Actions di sini sangat penting—juga dengan dukungan alat CLI dari masing-masing platform. Cloudflare memiliki Wrangler sebagai alat CLI mereka agar developer bisa berinteraksi dengan layanan Cloudflare melalui CLI (command-line interface).

Wrangler yang menghilangkan segala kemudahan dari Cloudflare Pages

Dengan Wrangler, kita mendapatkan mendapatkan fleksibilitas untuk mengatur bagaimana proyek kita akan di-deploy, namun kemudahan bawaan Cloudflare Pages akan sirna.

Asalnya, di Cloudflare Pages, kita bisa memilih branch mana yang akan dijadikan production deployment melalui dashboard dengan mudah dan semua branch lain akan dianggap sebagai preview deployment. Secara otomatis, Cloudflare Pages akan melakukan build dan deploy pada setiap push; ini memungkinkan kita memiliki deployment URL yang unik dari tiap commit atau branch.

Hal-hal tersebut harus sirna atau bisa kita buat secara manual demi fleksibilitas yang kita inginkan.

Apa itu GitHub Actions?

GitHub Actions adalah salah satu fitur dari GitHub untuk melakukan proses CI/CD—mengotomatiskan proses pengembangan aplikasi, seperti build, test, dan deployment.

Saya menggunakan GitHub Actions tentu karena saya meletakkan repositori proyek saya di GitHub, jadi segala prosesnya lebih seamless—dan tentunya, gratis!

Apa itu Cloudflare Pages?

Cloudflare Pages adalah salah satu layanan dari Cloudflare untuk hosting aplikasi web. Fitur dari Cloudflare Pages sangat lengkap:

  1. Build dan deploy secara otomatis
  2. Kolaborasi tanpa batas. Bebas menambahkan anggota tim tanpa batas, tanpa biaya
  3. Integrasi dengan Cloudflare Workers untuk aplikasi dinamis; server-side rendering hingga server functions
  4. Terintegrasi dengan analitik bawaan yang gratis dan mengutamakan privasi pengguna
  5. Bandwidth tak terbatas
  6. Static requests tak terbatas

Karena saya menggunakan layanan Cloudflare DNS juga, ini memudahkan saya ketika saya butuh custom domain. Selain itu, ada banyak kasus developer yang tiba-tiba proyek hobinya mendapatkan banyak traffic sehingga mencapai/melebihi batasan bandwidth/static request yang ditetapkan provider lain—karena itu sedia Cloudflare Pages sebelum tagihan datang—eh?

Analitik web yang disediakan juga menjadi alasan saya mencoba Cloudflare Pages. Saat ini, saya menggunakan self-hosted Umami dengan Supabase untuk menyimpan datanya. Kombinasi ini bekerja dengan sangat baik selama kurang lebih 6 bulan; namun, satu hal yang merepotkan adalah saya perlu memastikan Supabase saya tidak masuk ke dalam mode pause. Supabase melakukan hal tersebut pada free tier setelah tidak ada aktifitas sama sekali selama seminggu.

Persiapan

Berikut beberapa hal yang perlu kalian siapkan sebelum membaca lebih lanjut:

Membuat proyek dengan Astro

Kita akan menggunakan blog starter template dari Astro dengan menjalankan perintah berikut di terminal:

pnpm create astro --template blog

Ikuti prompt-nya dan pastikan kalian memilih “Ya” untuk instalasi dependensi dan menginisialisasi repositori Git.

Tampilan terminal pada saat membuat proyek blog dengan template dari Astro

Pastikan proyek tersebut berjalan dengan lancar di development dengan menjalankan pnpm dev dan juga dapat di-build dengan pnpm build.

Menyiapkan repositori di GitHub

Setelah berhasil membuat proyek dengan Astro dan memastikan semuanya bekerja dengan baik, langkah selanjutnya adalah membuat remote repositori di GitHub dan membawa proyek blog kita ke sana.

  1. Kunjungi https://github.com/new
  2. Isi nama repositori saja dan biarkan kolom lain, lalu klik “Create repository”
  3. Setelah remote repositori terbuat, akan muncul dua panduan untuk melakukan push repositori lokal kita ke remote repositori yang baru kita buat. Ikuti langkah pada kotak merah di bawah ini:
Tampilan repositori GitHub dalam keadaan kosong berisi panduan untuk melakukan push ke repositori tersebut
  1. Muat ulang halaman dan pastikan remote repositori kalian kurang lebih terlihat seperti ini:
Tampilan repositori GitHub setelah melakukan push

Mendapatkan Cloudflare API Token

Sebelum menggunakan Wrangler CLI, kita membutuhkan dua kredensial dari Cloudflare; yaitu API Token dan Account ID.

  1. Masuk ke dashboard Cloudflare
  2. Pergi ke menu “My Profile” yang berada di pojok kanan atas dengan mengeklik ikon pengguna
  3. Pergi ke menu “API Tokens”, lalu klik “Create Token”
  4. Pilih “Custom Token”, lalu klik “Get started”
  5. Beri nama apa pun untuk API Token yang akan dibuat pada kolom “Token name”
  6. Lalu, di bagian “Permissions” pilih Account, Cloudflare Pages, dan Edit (kolom pilih opsi secara berurut dari kiri ke kanan)
  7. Klik “Continue to summary”, lalu klik “Create token”
  8. Salin dan simpan token tersebut untuk kemudian kita gunakan di Github Actions dan API
Halaman pengguna Cloudflare ketika membuat API Token

Mendapatkan Cloudflare Project Account ID

  1. Masuk ke dashboard Cloudflare
  2. Pergi ke menu “Workers & Pages”
  3. Terdapat bagian “Account details” di sisi sebelah kanan, ada kolom “Account ID”. Klik untuk menyalin isinya
  4. Simpan Account ID tersebut untuk kemudian kita gunakan di Github Actions dan API
Halaman Workers & Pages untuk mengakses Account ID

Membuat Github Actions workflows

Workflows adalah proses otomatis yang dapat dikonfigurasi yang akan menjalankan satu atau lebih pekerjaan (berikutnya akan disebut sebagai jobs). Workflows didefinisikan oleh berkas YAML yang dapat dijalankan berdasarkan sebuah event, dijalankan secara manual, atau bahkan terjadwal.

Berkas workflows disimpan di folder .github/workflows pada sebuah repositori. Oleh karena itu, langkah pertama kita adalah membuat folder .github/workflows pada proyek blog kita.

Tampilan direktori proyek setelah membuat folder .github/workflows

Lalu, buat berkas deploy.yml di dalam folder .github/workflows

Tampilan direktori .github/workflows yang berisi berkas deploy.yml

Mendefinisikan trigger, permissions, serta environment variables

Pada dasarnya, ada tiga komponen penting dalam sebuah workflow: event, job, dan step. Event adalah penentu pada saat apa sebuah workflow akan dijalankan. Job adalah sebuah tugas yang berjalan pada mesin virtual masing-masing yang secara default dijalankan secara paralel. Tiap job dapat memiliki beberapa step yang bisa menjalankan sebuah skrip yang kita buat atau sebuah paket/action yang tersedia di marketplace.

Gambaran besar dari sebuah Workflow pada GitHub Actions

Pada proyek ini, saya menginginkan workflow dijalankan pada:

  1. Setiap kali ada push ke branch main
  2. Setiap ada rilis baru dari Github Releases
  3. Dapat dijalankan secara manual dengan memilih environment tujuan dari deployment sesuai keinginan. Opsinya ada staging dan production
name: Deploy to Cloduflare Pages
 
on:
  workflow_dispatch:
    inputs:
      environment:
        description: "Choose an environment to deploy to:"
        required: true
        default: "staging"
        type: choice
        options:
          - staging
          - production
  push:
    branches:
      - main
  release:
    types: [released]

Pertama, nama. Layaknya sebuah do’a, beri nama workflow kalian dengan sebaik-baiknya nama. Pada key name kalian bisa memberi nama untuk workflow yang akan dibuat.

name: Deploy to Cloudflare Pages

Kedua, event. Event didefinisikan di dalam key on.

on:
  event_name:
  event_name_2:
  event_name_n:

Untuk menjalankan workflow secara manual, kita dapat menggunakan event workflow_dispatch. Event ini menerima maksimal 10 inputs. Inputs berfungsi sebagai kolom opsi yang bisa kita pilih untuk memengaruhi jalannya sebuah workflow. Ada berbagai tipe data untuk mendefinisikan sebuah input, yaitu: boolean, choice, number, environment, dan string. Penjelasan lebih lanjut dapat dibaca di Workflow syntax for GitHub Actions

Sebagai contoh:

on:
  workflow_dispatch:
    inputs:
      logLevel:
        description: "Log level"
        required: true
        default: "warning"
        type: choice
        options:
          - info
          - warning
          - debug
      tags:
        description: "Test scenario tags"
        required: false
        type: boolean
      environment:
        description: "Environment to run tests against"
        type: environment
        required: true

Konfigurasi di atas akan menghasilkan inputs seperti di bawah ini

Contoh tampilan hasil inputs dari sebuah workflow

Oke, kembali ke topik utama. Dengan konfigurasi yang sudah kita buat di atas tadi, maka inputs yang dihasilkan akan seperti ini

Hasil tampilan inputs dari workflow yang kita buat
on:
  workflow_dispatch:
    inputs:
      environment:
        description: "Choose an environment to deploy to:"
        required: true
        default: "staging"
        type: choice
        options:
          - staging
          - production

Selanjutnya, kita perlu mendefinisikan event push agar workflow ini dapat dijalankan ketika ada push ke branch main.

on:
  workflow_dispatch:
    inputs:
      environment:
        description: "Choose an environment to deploy to:"
        required: true
        default: "staging"
        type: choice
        options:
          - staging
          - production
  push:
    branches:
      - main

Selain branches, ada juga tags dan paths. Loh, kenapa kita tidak menggunakan tags juga di sini? Karena event pada Github Actions itu sifatnya seperti logical OR. Jika kita mendefinisikan event seperti berikut:

on:
	push:
		branches:
			- main
		tags:
			- 'v**'

Maka, workflow tersebut akan dijalankan ketika ada push ke branch main ATAU ada push tag dengan awalan “v”. Perlu sedikit akrobat jika ingin sebuah workflow dijalankan pada saat ada push tag ke branch main. Oleh karena itu, kita hanya akan memanfaatkan event release yang berikutnya akan saya jelaskan.

Selanjutnya, untuk menjalankan workflow ketika ada rilis baru dengan tag yang dibuat dari GitHub Releases. Event rilis memiliki setidaknya tujuh tipe, yaitu:

Masing-masing memiliki kegunaannya tersendiri dan yang akan kita gunakan hanyalah released. Kita belum membutuhkan draft dan pre-release, sehingga tidak memerlukan tipe published. Penjelasan lebih lanjut dapat dibaca di Events that trigger workflows

Tampilan dari GitHub Releases ketika ingin membuat rilisan baru
name: Deploy to Cloudflare Pages
 
on:
  workflow_dispatch:
    inputs:
      environment:
        description: "Choose an environment to deploy to:"
        required: true
        default: "staging"
        type: choice
        options:
          - staging
          - production
  push:
    branches:
      - main
  release:
    types: [released]

Setelah event beres, kita perlu mendefinisikan permission agar workflow kita dapat berjalan dengan lancar dan dapat menggunakan apa yang kita butuhkan. Pada workflow ini, kita hanya perlu dua permission: contents dan deployments. Kalian bisa melihat permission apa saja yang tersedia di Workflow permissions

permissions:
  contents: read
  deployments: write

Selanjutnya, kita memerlukan sebuah environment variables untuk menentukan apakah workflow kali ini dijalankan untuk production atau staging. Environment variables tersebut akan kita gunakan pada langkah terakhir, yaitu deployment ke Cloudflare Pages.

env:
  IS_PRODUCTION: ${{ github.event.inputs.environment == 'production' || github.event_name == 'release' }}

IS_PRODUCTION akan bernilai true jika workflow dijalankan secara manual dengan opsi production atau workflow djalankan karena terpicu oleh event release. Sesuai tujuan utama kita, pembeda antara staging dan production ada pada tag atau rilis.

Sejauh ini, file deploy.yml kita akan seperti ini:

name: Deploy to Cloudflare Pages
 
on:
  workflow_dispatch:
    inputs:
      environment:
        description: "Choose an environment to deploy to:"
        required: true
        default: "staging"
        type: choice
        options:
          - staging
          - production
  push:
    branches:
      - main
  release:
    types: [released]
 
permissions:
  contents: read
  deployments: write
 
env:
  IS_PRODUCTION: ${{ github.event.inputs.environment == 'production' || github.event_name == 'release' }}

Kencangkan sabuk pengaman, karena kita akan menyelami lautan jobs!

Mendefinisikan Jobs

Jobs di Github Actions secara default berjalan secara paralel. Namun, kita dapat mendefinisikannya agar berjalan secara sekuensial dengan key jobs.<job_id>.needs. Pada workflow ini, kita akan mendefinisikan dua jobs: build dan deploy.

jobs:
	build:
		runs-on: ubuntu-latest
		steps:
		 - . . .
 
	deploy:
		needs: build
		runs-on: ubuntu-latest
		steps:
			- . . .

Key runs-on diperlukan untuk mendefinisikan di mana job yang kita buat akan dijalankan. ubuntu-latest berarti job tersebut akan dijalankan di sebuah mesin virtual dengan OS Linux Ubuntu versi terbaru. Ada banyak opsi runner lain yang dapat kalian lihat di Workflow runners.

Lalu, ada key needs yang berarti job tersebut perlu menunggu job build selesai sebelum dijalankan. Sebetulnya, kita dapat membuat satu job saja—tetapi cara tersebut tidak direkomendasikan terlebih lagi kita memerlukan instalasi dependensi dan build sebelum melakukan deployment; apabila deployment gagal, kita perlu mengulang keseluruhan job dari awal. Berbeda dengan memisahkan job build dan deploy, ketika deploy gagal, maka kita bisa menjalankan ulang job deploy saja.

Untuk job build, kita memerlukan beberapa step:

  1. Menggunakan action actions/checkout@v4 untuk melakukan checkout di repositori kita agar workflow kita bisa mengakses kodenya
  2. Karena saya menggunakan pnpm, maka saya perlu menggunakan action pnpm/action-setup@v4 untuk menginstal pnpm
  3. Untuk menggunakan fitur cache pada pnpm, kita perlu mengikut langkah berikut dokumentasi pnpm/action-setup
  4. Langkah berikutnya adalah menjalankan build dengan run: pnpm build
  5. Setelah build selesai, kita perlu mengunggah berkas build tersebut ke artifacts agar berkas tersebut dapat digunakan oleh job berikutnya atau bahkan workflow lain. Untuk hal ini, kita gunakan actions/upload-artifact@v4
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
 
      - uses: pnpm/action-setup@v4
        with:
          version: 8
          run_install: false
 
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: "pnpm"
 
      - name: Install dependencies
        run: pnpm install
 
      - name: Build
        run: pnpm build
 
      - name: Upload artifacts
        uses: actions/upload-artifact@v4
        with:
          name: build-files
          path: ./dist

Untuk pengguna npm, kalian tidak memerlukan pnpm/action-setup@v4 dan mengganti beberapa perintah.

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
 
      - uses: actions/setup-node@v4
        with:
          node-version: 20
 
      - name: Install dependencies
        run: npm install
 
      - name: Build
        run: npm run build
 
      - name: Upload artifacts
        uses: actions/upload-artifact@v4
        with:
          name: build-files
          path: ./dist

Untuk pengguna yarn, kalian bisa coba menyesuaikan dengan action berikut GitHub Action for Yarn

Berikutnya, untuk job deploy! Langkah yang kita perlukan adalah:

  1. Mengunduh artifacts yang kita unggah di job sebelumnya menggunakan action actions/download-artifact@v4
  2. Karena tiap job jalan di mesin independen, maka kita perlu menginstal pnpm lagi menggunakan action pnpm/action-setup@v4
  3. Terakhir, kita akan menggunakan action cloudflare/wrangler-action@v3 untuk melakukan deployment ke Cloudflare Pages.
deploy:
  needs: build
  runs-on: ubuntu-latest
  steps:
    - name: Download artifacts
      uses: actions/download-artifact@v4
      with:
        name: build-files
        path: ./dist
 
    - uses: pnpm/action-setup@v4
      with:
        version: 8
 
    - name: Deploy to Cloudflare Pages
      uses: cloudflare/wrangler-action@v3
      with:
        apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
        accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
        gitHubToken: ${{ secrets.GITHUB_TOKEN }}
        packageManager: pnpm
        command: |
          pages deploy dist --project-name=kaget --branch=${{ env.IS_PRODUCTION == 'true' && 'production' || 'main' }}

Masih ingat API Token dan Account ID yang sudah kita siapkan di awal artikel ini? Nah, dua hal tersebut diperlukan di langkah ini untuk menggunakan Wrangler CLI via action cloudflare/wrangler-action@v3.

Kita akan menambahkan API Token dan Account ID ke dalam GitHub Secrets.

  1. Buka halaman repositori yang sudah kita buat
  2. Klik “Settings” > “Secrets and variables” > “Actions”
  3. Klik “New repository secret”
  4. Isi kolom nama dengan CLOUDFLARE_API_TOKEN
  5. Isi kolom value dengan API Token yang sudah kita buat, lalu klik “Add secret”
  6. Ulangi dari langkah ketiga dengan nama dan value untuk CLOUDFLARE_ACCOUNT_ID
Tampilan untuk konfigurasi secrets di GitHub Actions

Secrets yang sudah kita buat dapat diakses dari workflow dengan secrets.<name>. Untuk secrets.GITHUB_TOKEN, secara otomatis disediakan oleh GitHub dengan menggunakan permission tertentu.

Berikutnya, perhatikan argumen command pada step “Deploy to Cloudflare Pages”. Action cloudflare/wrangler-action@v3 memungkinkan kita untuk menimpa command bawaan sesuai kebutuhan.

Ada beberapa argumen opsi yang saya gunakan di sini agar deployment ini sesuai keinginan:

command: |
	pages deploy dist --project-name=kaget --branch=${{ env.IS_PRODUCTION == 'true' && 'production' || 'main' }}

Workflow kita sudah selesai. Saatnya pembuktian!

Deployment pertama

Sebelum kita commit dan push worklfow yang sudah dibuat, ada satu hal yang perlu kita pastikan—yaitu membuat proyek baru di dashboard Cloudflare Pages.

  1. Buka dashboard Cloudflare
  2. Di pojok kanan atas, temukan dan klik “+ Add” lalu klik “Pages”. Nanti akan muncul menu “Workers & Pages” di menu sidebar sebelah kiri
Tampilan halaman Workers & Pages di dashboard Cloudflare pada saat membuat proyek baru
  1. Klik “Create” > Pilih tab “Pages” > Pilih opsi direct upload
  2. Isi kolom nama proyek sesuai dengan nama repositori atau sesuai dengan yang kita kirim di argumen opsi --project-name dari Wrangler CLI sebelumnya
  3. Lalu klik “Create project”
Tampilan sesudah membuat proyek di halaman Workers & Pages
  1. Kembali ke halaman “Workers & Pages”. Tidak perlu mengunggah aset apa pun karena kita akan mengunggahnya melalui Github Actions.

Setelah semua pengaturan beres, saatnya commit dan push berkas workflow kita.

$ git add .
$ git commit -m "chore: setup workflows"
$ git push

Buka halaman repositori kita, klik “Actions” dan kalian akan melihat ada satu workflow yang sedang berjalan. Kalian bisa klik untuk melihat detailnya, bahkan hingga detail masing-masing job dan step yang sedang berjalan.

Tampilan Actions pada repositori yang menampilkan workflow yang sedang atau sudah berjalan
Detail tampilan dari sebuah workflow. Terlihat jobs yang saling terhubung
Detail tampilan dari tiap job dalam sebuah workflow. Terlihat steps yang dijalankan di job tersebut

Lihat gambar terakhir dan perhatikan deployment URL-nya—betul sekali, ada semacam hash unik di sana. Coba kita lihat dari dashboard “Workers & Pages” dan lihat detail proyeknya.

Halaman Workers & Pages yang menampilkan daftar proyek di Cloudflare Pages
Halaman detail dari proyek Cloudflare Pages

Kita mendapatkan dua URL! Satu URL utama https://blog-poc-cf-pages-tag-based-deployment.pages.dev/ dan yang kedua dengan hash unik untuk tiap commitnya https://e0c3013f.blog-poc-cf-pages-tag-based-deployment.pages.dev/. Jika ada deployment baru, maka deployment tersebut dapat diakses melalui URL utama dan URL dengan hash terbaru. Lalu, apakah deployment sebelumnya masih bisa kita akses? Tentu saja! Dengan catatan, hanya bisa diakses melalui URL yang berkaitan.

Perlu dicatat, URL utama akan di-assign oleh Cloudflare Pages ke branch utama (main/master) dan dianggap sebagai production deployment.

Deployment ke production

Kita akan menggunakan Github Releases untuk membuat tag dan mencatat perubahan apa saja yang terjadi pada rilis ke production ini.

Pertama, buka halaman repositori kita dan lihat di sisi sebelah kanan terdapat bagian “Releases”. Klik “Create a new release”.

Halaman utama dari repositori GitHub. Terdapat kotak merah yang menunjukkan lokasi bagian Releases

Lalu, buat tag baru pada kolom “Choose a tag”. Kita akan membuat tag v1.0.0 sebagai versi awal.

Tampilan membuat tag pada halaman GitHub Releases

Kemudian, klik “Generate release notes”. Ini akan membuat catatan rilis secara otomatis berdasarkan commit history dari pull request yang berhasil di-merge. Untuk saat ini, karena memang belum ada pull request yang di-merge, maka catatan rilis tampak kosong.

Selanjutnya, klik “Publish release” dan lihat akan ada workflow yang berjalan!

Halaman GitHub Releases setelah diisi secara otomatis
Halaman Actions yang menampilkan sebuah workflow yang berjalan karena dipicu oleh rilis baru

Perhatikan job deploy pada step “Deploy to Cloudflare Pages”. Kita sudah berhasil mengatur deployment berdasarkan tag dari Github Releases, sehingga argumen opsi --branch seharusnya berisi production.

Detail dari step 'Deploy to Cloudflare Pages' yang terdapat kotak merah untuk menunjukkan argumen --branch berisi production

Untuk memastikan apakah deployment tadi benar-benar dianggap sebagai production oleh Cloudflare Pages, kita perlu melihatnya di dashboard “Workers & Pages” proyek kita.

Bisa kita lihat gambar di bawah ini. Sebetulnya, kita tidak memiliki branch production, tetapi argumen opsi --branch memungkinkan kita untuk membedakan sebuah deployment dengan hanya memiliki satu branch.

Hal janggal lainnya adalah branch production kita masih dianggap preview deployment oleh Cloudflare Pages; artinya, URL utama kita (https://blog-poc-cf-pages-tag-based-deployment.pages.dev/) masih memiliki konten yang lama, karena masih mengarah ke deployment sebelumnya. Tentu ini belum sesuai dengan tujuan kita. Kita ingin deployment ke production hanya pada saat ada tag baru. Perubahan apa pun yang di-push ke branch main, jika belum siap untuk dirilis maka tidak akan tersedia di URL utama—melainkan hanya di preview URL.

Halaman detail dari proyek Cloudflare Pages yang ada di dashboard Cloudflare

Mengatur branch production sebagai production environment

Sayang seribu sayang—jika kita menggunakan metode direct upload untuk men-deploy proyek kita ke Cloudflare Pages, tidak ada cara untuk mengatur branch yang digunakan untuk production environment lewat dashboard. Kita harus melakukannya melalui API endpoint yang disediakan oleh Cloudflare.

Jalankan perintah berikut di terminal kalian. Jangan lupa siapkan API Token, Account ID, dan nama proyek kalian.

curl --request PATCH \
"https://api.cloudflare.com/client/v4/accounts/{account_id}/pages/projects/{project_name}" \
--header "Authorization: Bearer <API_TOKEN>" \
--header "Content-Type: application/json" \
--data "{\"production_branch\": \"production\"}"

Setelah sukses, kita perlu melakukan deployment lagi untuk menerapkan perubahan. Jalankan workflow secara manual dengan memilih opsi production sebagai environment tujuan.

Tampilan dari terminal setelah melakukan perintah untuk mengganti production branch yang hasilnya sukses
Halaman Actions yang menampilkan inputs untuk menjalankan workflow secara manual

Lalu, cek dashboard “Workers & Pages” kalian dan production environment kita sudah berada di jalan yang benar. Mungkin, rasanya tidak ada perbedaan antara production dan preview untuk saat ini. Kalian bisa coba buat perubahan pada proyek kalian. Pada percobaan yang saya lakukan, saya mengganti judul pada halaman home di berkas src/pages/index.astro lalu push perubahan tersebut ke branch main. Di sinilah perbedaan akan muncul. URL utama (https://blog-poc-cf-pages-tag-based-deployment.pages.dev/) saya tidak ada perubahan apa pun, sedangkan jika mengakses preview deployment dari branch main, maka terlihat ada perbedaan pada judul (https://main.blog-poc-cf-pages-tag-based-deployment.pages.dev/).

💡 Selain hash unik, preview deployment juga bisa diakses melalui nama branch seperti <branch>.<project>.pages.dev. URL tersebut merupakan alias untuk deployment terakhir pada branch terkait.

Kesimpulan

Cloudflare Pages dan ekosistemnya bisa dibilang alternatif yang sangat menjanjikan. Kapan lagi bisa dapat unlimited bandwidth untuk situs yang kita buat? Selain itu, integrasi dengan provider Git juga sangat memudahkan dan bisa dibilang cukup bersaing dengan platform sejenis.

Mungkin sebagian dari kalian akan beranggapan “Ngapain sih front-end developer ngoprek-ngoprek CI/CD? Kan itu tugasnya DevOps”—percayalah, CI/CD ini konsep umum yang perlu dipahami oleh setiap developer; setidaknya mengetahui apa saja yang diperlukan untuk membuat sebuah proyek siap ke production—mulai dari lint, test, build, serta berkas mana saja yang digunakan.

Memahami CI/CD juga bermanfaat untuk proyek hobi karena kita bekerja seorang diri—seperti apa yang saya lakukan saat ini.

Terima kasih!

Referensi