Bagian 1 : Menyiapkan pipeline CI/CD sederhana untuk Python dan PyPI
Diterbitkan 17 July 2025
Pengenalan
Otomatisasi proses pengembangan telah menjadi tidak terelakkan dalam proyek-proyek modern. Sebuah pipeline CI/CD yang dirancang dengan baik tidak hanya memungkinkan deteksi regresi lebih awal dalam siklus pengembangan, tetapi juga mengotomatisasi seluruh proses penyebaran.
Dalam artikel ini, kita akan menjelajahi cara menyiapkan pipeline lengkap dengan GitHub Actions untuk aplikasi Python, dari integrasi berkelanjutan (CI) hingga deploy berkelanjutan (CD) ke PyPI.
Arsitektur Pipeline
Pipeline kami terdiri dari dua alur kerja yang berbeda:
-
Alur CI: Dieksekusi pada setiap push dan pull request
-
Pipeline CDDemicu hanya selama rilis GitHub
@startuml
!theme plain
package "GitHub Repositori" {
[Source Code] as source
[GitHub Actions] as actions
}
package "Alur CI" {
[Checkout] as checkout_ci
[Setup Python] as python_ci
[Install Dependencies] as deps_ci
[Linting (Ruff)] as lint
[Unit Tests] as tests
}
package "CD Pipeline" {
[Checkout] as checkout_cd
[Setup Python] as python_cd
[Build Package] as build
[Publish to PyPI] as pypi
}
source --> actions : Push/PR
actions --> checkout_ci
checkout_ci --> python_ci
python_ci --> deps_ci
deps_ci --> lint
lint --> tests
source --> actions : Release
actions --> checkout_cd : On Release
checkout_cd --> python_cd
python_cd --> build
build --> pypi
@enduml
Konfigurasi Pipeline Integrasi Berkelanjutan (CI)
Struktur alur kerja CI
Alur kerja CI dirancang untuk memvalidasi setiap kontribusi ke kode. Berikut konfigurasi lengkapnya :
name: CI/CD Pipeline
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install ruff pytest pytest-mock
- name: Run Linting (Ruff)
run: ruff check .
- name: Run Tests (Pytest)
run: pytest
Analisis Langkah CI
1. Pemicu (on)
----
----
on:
push:
branches:
- main
pull_request:
branches:
- main
----
Pipeline dipicu pada : - Setiap push ke cabang`main` - Setiap pull request menuju`main`
Pendekatan ini memastikan bahwa kode utama tetap stabil dan bahwa semua kontribusi divalidasi sebelum integrasi.
==== 2. Lingkungan Eksekusi
----
runs-on: ubuntu-latest
Ubuntu Latest menawarkan kompromi yang baik antara performa, biaya, dan kompatibilitas untuk sebagian besar proyek Python.
==== 3. Checkout Kode
```yaml
----
----
- name: Checkout code
uses: actions/checkout@v4
----
tindakan
</think>
tindakan`checkout@v4`Mengambil kode sumber dari repositori. Versi v4 memberikan peningkatan performa dan keamanan.
==== 4. Konfigurasi Python
----
- name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.x'
penggunaan`'3.x'`memungkinkan penggunaan otomatis versi stabil terbaru dari Python 3, memudahkan pemeliharaan.
==== 5. Instalasi Dependensi
```yaml
----
----
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install ruff pytest pytest-mock
----
Tahap ini : - Memperbarui pip ke versi terbaru - Instal dependensi proyek - Tambahkan alat pengembangan (linting dan ujian)
==== 6. Linting dengan Ruff
----
- name: Run Linting (Ruff) run: ruff check .
**Ruff**adalah linter Python yang sangat cepat yang ditulis dalam Rust. Dia menggabungkan fitur dari beberapa alat (Flake8, Black, isort) menjadi satu alat yang kuat.
==== 7. Pelaksanaan Tes
```yaml
----
----
- name: Run Tests (Pytest)
run: pytest
----
Pytest menjalankan seluruh suite tes, memastikan bahwa perubahan tidak memperkenalkan regresi.
== Konfigurasi Pipeline Penerapan (CD)
=== Struktur Workflow CD
Workflow CD hanya terpicu selama rilis GitHub dan mengotomatiskan publikasi ke PyPI :
[source,yaml]
----
name: Publish to PyPI
on:
release:
types:
- published
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install setuptools wheel twine
- name: Build and publish
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
run: |
python setup.py sdist bdist_wheel
twine upload dist/*
----
=== Analisis Tahap CD
==== 1. Pemicu Pelepasan
----
on: release: types: - published
Pipeline CD hanya dipicu saat mempublikasikan rilis GitHub. Pendekatan ini memastikan kontrol yang tepat atas penerapan.
==== 2. Instalasi Alat Pembangunan
```yaml
----
----
pip install setuptools wheel twine
----
- **setuptools**: Alat packaging Python - **roda**: Format distribusi Python modern - **benang**: Alat aman untuk mengunggah ke PyPI
==== 3. Konfigurasi Otentikasi
----
env: TWINE_USERNAME: __token__ TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
Autentikasi menggunakan token API PyPI yang disimpan sebagai rahasia GitHub, lebih aman daripada kredensial konvensional.
==== 4. Build dan publikasi
```yaml
----
----
run: |
python setup.py sdist bdist_wheel
twine upload dist/*
----
- `sdist`: Buat distribusi sumber - `bdist_wheel`: Membuat sebuah wheel (distribusi biner) - `twine upload`Mempublikasikan distribusi pada PyPI
== Konfigurasi Paket Python
=== Struktur setup.py
Agar pipeline berfungsi, proyek Anda harus menyertakan sebuah file`setup.py`:
[source,python]
----
from setuptools import setup, find_packages
with open("README.adoc", "r", encoding="utf-8") as fh:
long_description = fh.read()
setup(
name="playlist-downloader",
version="1.0.0",
author="Votre Nom",
author_email="[email protected]",
description="CLI tool for managing YouTube playlists",
long_description=long_description,
long_description_content_type="text/plain",
url="https://github.com/cheroliv/playlist-downloader",
packages=find_packages(),
classifiers=[
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
],
python_requires=">=3.8",
install_requires=[
"typer>=0.9.0",
"yt-dlp>=2023.1.6",
"google-api-python-client>=2.70.0",
"google-auth-oauthlib>=0.7.1",
"pymonad>=2.4.0",
"pyyaml>=6.0",
],
entry_points={
"console_scripts": [
"playlist-downloader=cli:app",
],
},
)
----
=== poin-poin kunci setup.py
1. **metadata**: Nama, versi, penulis, deskripsi
2. **Ketergantungan**: Daftar packages yang diperlukan
3. **Titik Masuk**: Perintah CLI yang diekspos
4. **klasifikasi**: metadata untuk PyPI
== Keamanan dengan GitHub Secrets
=== Konfigurasi Token PyPI
1. **Membuat token API di PyPI**:
- Masuk ke PyPI Buka Pengaturan Akun > API tokens - Buat token baru dengan izin yang sesuai
1. **Tambahkan rahasia di GitHub**:
- Pengaturan Repositori > Rahasia dan variabel > Tindakan - Buat rahasia baru yang dinamai`PYPI_API_TOKEN` - Tempelkan token PyPI Anda
[plantuml, secrets-flow, svg]
----
@startuml
!theme plain
actor Developer as dev
participant "Repositori GitHub" as repo
participant "GitHub Actions" as actions
participant PyPI
dev -> repo : Configure PYPI_API_TOKEN secret
repo -> actions : Trigger CD pipeline on release
actions -> actions : Access secret securely
actions -> PyPI : Authenticate with token
PyPI -> PyPI : Validate and publish package
note over actions, PyPI
Token never exposed in logs
Automatic rotation possible
end note
@enduml
----
== Workflow Deployment Lengkap
=== Urutan Penyebaran
[plantuml, deployment-sequence, svg]
----
@startuml
!theme plain
actor Developer as dev
participant "Git lokal" as git
participant "GitHub" as github
participant "GitHub Tindakan" as actions
participant PyPI
participant "Pengguna akhir" as users
dev -> git : git tag v1.0.0
dev -> git : git push origin v1.0.0
git -> github : Push tag
dev -> github : Create release from tag
github -> actions : Trigger CD pipeline
actions -> actions : Checkout code
actions -> actions : Setup Python environment
actions -> actions : Install build tools
actions -> actions : Build distributions (sdist + wheel)
actions -> PyPI : Upload to PyPI with token
PyPI -> PyPI : Validate and publish
users -> PyPI : pip install playlist-downloader
note over dev, github
Release creation can be automated
or done manually through GitHub UI
end note
@enduml
----
=== Status Pipeline
[plantuml, pipeline-states, svg]
----
@startuml
!theme plain
[*] --> Idle
Idle --> CI_Running : Push/PR created
CI_Running --> CI_Success : All checks pass
CI_Running --> CI_Failed : Linting/Tests fail
CI_Success --> Idle : Merge completed
CI_Failed --> Idle : Fix and retry
Idle --> CD_Running : Release published
CD_Running --> CD_Success : Package published
CD_Running --> CD_Failed : Build/Upload error
CD_Success --> Idle : Package available on PyPI
CD_Failed --> Idle : Fix and retry release
note on link #red : Blocks merge
note on link #green : Allows deployment
@enduml
----
== Praktik Baik dan Optimasi
=== Manajemen Versi
Gunakan tag Git semantik :
----
git tag -a v1.2.3 -m "Release version 1.2.3" git push origin v1.2.3
=== 2. Uji Matriks
Untuk menguji pada beberapa versi Python:
```yaml
----
----
strategy:
matrix:
python-version: [3.8, 3.9, "3.10", "3.11"]
----
=== 3. Cache Dependensi
Percepat build dengan cache :
----
- name: Cache pip dependencies uses: actions/cache@v3 with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
=== 4. lingkungan penerapan
Gunakan lingkungan GitHub untuk penerapan yang terkontrol :
```yaml
----
----
jobs:
deploy:
environment: production
runs-on: ubuntu-latest
----
== Kasus Penggunaan dan Arsitektur
=== Diagram Kasus Penggunaan
[plantuml, use-cases, svg]
----
@startuml
!theme plain
left to right direction
actor "Pengembang" as dev
actor "GitHub Actions" as ga
actor "Pengguna akhir" as user
package "Sistem CI/CD" {
usecase "Jalankan Linting" as lint
usecase "Menjalankan tes" as test
usecase "Membangun Paket" as build
usecase "Terbitkan ke PyPI" as publish
usecase "Buat Rilis" as release
}
dev --> lint : Pushes code
dev --> test : Pushes code
dev --> release : Creates release
ga --> build : On release trigger
ga --> publish : After successful build
user --> publish : Downloads package
lint .> test : triggers
test .> build : on success
build .> publish : on success
@enduml
----
=== Arsitektur Penyebaran
[plantuml, deployment-architecture, svg]
----
@startuml
!theme plain
cloud "GitHub" {
[Source Repository]
[GitHub Actions]
[Secrets Store]
}
cloud "PyPI" {
[Package Registry]
[Distribution Files]
}
node "Alur CI/CD" {
[Linting]
[Testing]
[Building]
[Publishing]
}
[Source Repository] --> [GitHub Actions] : Triggers
[GitHub Actions] --> [Linting]
[Linting] --> [Testing]
[Testing] --> [Building]
[Building] --> [Publishing]
[Publishing] --> [Package Registry] : Uploads
[Secrets Store] --> [Publishing] : Provides token
note as N1
Secure token-based
authentication
end note
[Secrets Store] .. N1
@enduml
----
== Pengawasan dan Debugging
=== Log dan Pemantauan
GitHub Actions memberikan log terperinci untuk setiap langkah. Untuk debug:
1. **Periksa log**setiap step
2. **Aktifkan debug**dengan`ACTIONS_STEP_DEBUG`
3. **Gunakan artefak**untuk menyimpan file build
----
- name: Upload build artifacts uses: actions/upload-artifact@v3 if: failure() with: name: build-logs path: build/
=== Notifikasi
Tambahkan notifikasi Slack atau email :
```yaml
----
----
- name: Notify on failure
if: failure()
uses: 8398a7/action-slack@v3
with:
status: ${{ job.status }}
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
----
== Kesimpulan
Penerapan pipeline CI/CD yang kuat dengan GitHub Actions secara radikal mengubah pengalaman pengembangan. Dengan mengotomatisasi linting, pengujian, dan penyebaran, Anda :
- **Kurangi kesalahan**dalam produksi - **Percepat siklus**pengembangan - **Tingkatkan kepercayaan**dalam rilis Anda - **Mudahkan kolaborasi**dalam tim
Pipeline ini dapat disesuaikan dengan berbagai jenis proyek Python dengan menyesuaikan alat linting, kerangka kerja pengujian, atau destinasi penerapan.
Investasi awal dalam konfigurasi workflow-nya segera menguntungkan melalui penghematan waktu dan penurunan kesalahan manual selama penerapan.
== Sumber Daya Tambahan
- https://docs.github.com/en/actions[Dokumentasi GitHub Actions] - https://packaging.python.org/[Panduan Pengemasan Python] - https://docs.pytest.org/[Dokumentasi Pytest] - https://docs.astral.sh/ruff/[Dokumentasi Ruff] - https://twine.readthedocs.io/[Dokumentasi Twine]
✅ Pipeline fungsional tercapai! Anda kini memiliki pipeline CI/CD sederhana yang memungkinkan Anda mengotomatiskan pengujian dan menerbitkan paket Python Anda ke PyPI langsung dari GitHub Actions.
Namun, pipeline ini tetap sengaja minimalis. Ia belum mencakup beberapa aspek penting dalam konteks profesional :
Uji multi-versi Python,
Analisis keamanan otomatis,
Penyebaran bertahap melalui Test PyPI,
Pemantauan dan metrik pipeline,
Otomatisasi versioning dan integrasi praktik terbaik modern (pyproject.toml).
Di bagian berikutnya, kita akan melangkah ke tingkat yang lebih tinggi. Anda akan belajar mengubah pipeline dasar ini menjadi benar-benar rangkaian penyebaran industri, kuat dan aman, siap untuk proyek-produksi Python.
----