Pre-commit hooks menjaga kualitas di mesin masing-masing — selama hook terpasang dan tidak dilewati. Continuous Integration (CI) memindahkan penjagaan itu ke server: setiap push dan pull request memicu mesin bersih yang menginstal dependensi dari nol, menjalankan test, lalu melaporkan lulus atau gagal. Tidak ada lagi ruang “di komputer saya jalannya normal”, karena komputer CI selalu sama dan selalu mulai dari keadaan murni. Pada Chapter ini kita menulis workflow GitHub Actions, menguji beberapa versi Python lewat matrix, lalu menutup Section dengan disiplin kerja yang menjadikan CI berguna.

Workflow GitHub Actions #

GitHub Actions membaca konfigurasi dari file YAML di folder .github/workflows/. Simpan sebagai .github/workflows/tests.yml:

yaml
name: Tests

on:
  push:
    branches: [main]
  pull_request:

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ["3.11", "3.12", "3.13"]
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}
      - name: Instal dependensi
        run: python -m pip install -r requirements.txt
      - name: Jalankan test
        run: python -m pytest -q

Mari kita bedah komponen-komponennya:

  1. name: Tests: nama workflow yang tampil di tab Actions dan status check.
  2. on: push / pull_request: pemicu eksekusi — push ke branch main dan setiap pull request. Stage paling awal: branch main terjaga, pull request terverifikasi sebelum merge.
  3. jobs.test.runs-on: ubuntu-latest: mesin virtual yang disediakan GitHub untuk menjalankan pekerjaan ini.
  4. strategy.matrix.python-version: pekerjaan diduplikasi menjadi tiga — sekali per versi Python. Perubahan kode yang hanya gagal di Python 3.11 tertangkap sebelum menyatu.
  5. steps dengan uses:: action siap pakai — checkout mengambil source code, setup-python menginstal versi Python dari matrix.
  6. run:: perintah shell biasa; di sini instalasi dependensi dan menjalankan pytest. Langkah terakhir inilah inti CI: test berjalan di mesin yang bersih dari sisa-sisa lokal.

pytest sebagai Sinyal Lulus atau Gagal #

CI menentukan keberhasilan langkah dari exit code perintah. pytest menerapkan konvensi Unix: lulus berarti 0, ada test gagal berarti 1:

bash
python3 -m pytest -q
echo "kode keluar: $?"

Output yang Dihasilkan:

text
kode keluar: 0

Bila ada test yang gagal, nilai yang tercetak adalah 1 dan GitHub Actions menandai langkah tersebut gagal — pull request otomatis diberi label merah tanpa perlu membaca log panjang.

Badge Status #

Status terkini workflow bisa ditampilkan di README.md sebagai badge — cuplikan markdown yang GitHub render menjadi gambar passing atau failing:

markdown
![Tests](https://github.com/USER/REPO/actions/workflows/tests.yml/badge.svg)

Ganti USER/REPO dengan nama pemilik dan repository sesungguhnya. Badge hijau di halaman depan proyek memberi sinyal cepat kepada pengunjung bahwa test saat ini sehat.

Disiplin Kerja dengan CI #

Peralatan sudah lengkap; sisanya kebiasaan:

  • Test sebelum merge. Pull request tidak digabung selama status check masih merah — satu klik “Re-run” tidak menggantikan perbaikan.
  • Jangan menonaktifkan test yang gagal. Test gagal adalah informasi; menghapusnya demi badge hijau menanam bug yang sudah ketahuan.
  • CI cepat menjaga kebiasaan. Test suite yang memakan puluhan menit mendorong orang menunda push. Jaga unit test tetap ringan, pisahkan test lambat ke workflow terjadwal bila perlu.

Platform CI Lainnya #

GitHub Actions bukan satu-satunya pilihan; konsepnya identik di mana pun, yang berbeda hanyalah nama file dan sintaksnya:

PlatformFile konfigurasiCiri khas
GitHub Actions.github/workflows/*.ymlaction siap pakai dari marketplace, matrix bawaan
GitLab CI.gitlab-ci.ymlimage: Docker dan script: per stage
CircleCI.circleci/config.ymlberbasis job dan orbs
Azure Pipelinesazure-pipelines.ymlvmImage dan integrasi ekosistem Azure

Seluruh perjalanan Section ini kini menutup lingkaran: dari test pertama dengan assert, fixtures dan parametrize agar test ringkas, mocking untuk isolasi dependensi, coverage sebagai kompas, ruff sebagai penjaga gaya, pre-commit sebagai gerbang lokal, hingga CI sebagai penjaga terakhir di server. Kode yang melewati rantai ini layak dipercaya untuk berubah kapan pun dibutuhkan.