build-q (bq) 🚀
build-q (dibaca bq) adalah CLI Python zero-dependency untuk operasi docker buildx lokal & remote yang selaras dengan pipeline CI/CD (Jenkins X). Satu perintah pendek bq menggantikan docker buildx build yang panjang, dengan auto-detect Git, cicd/cicd.json, secret netrc, resource limit, dan idempotency check terhadap registry.
Selain build, bq menyediakan scaffolding CI/CD (--init-jx, --init-legacy), bootstrap GitHub Actions trigger (--gh-action-init), setup secrets (--init-secrets), migrasi Dockerfile legacy ke pola --mount=type=secret (--fix-dockerfile), auto-init Docker Buildx builder (--init), dan mode compose (--compose) untuk build via make build && make release.
📚 Panduan Cepat untuk Pemula
Bagian ini untuk yang baru pertama kali pakai bq. Kalau sudah familiar, lanjut ke Instalasi.
Apa saja yang perlu di-install?
Sebelum pakai bq, siapkan tools berikut di laptop:
| Tools | Wajib? | Kegunaan | Cara install (macOS via Homebrew) |
|---|---|---|---|
| Python 3.7+ | ✅ Wajib | Runtime bq |
brew install python (biasanya sudah ada) |
| pipx | ✅ Rekomendasi | Install CLI Python secara terisolasi | brew install pipx && pipx ensurepath |
| Docker Desktop / Colima | ✅ Wajib | Docker engine + Buildx plugin | brew install --cask docker atau brew install colima docker docker-buildx |
| Git | ✅ Wajib | Auto-detect repo/branch | brew install git (biasanya sudah ada) |
GitHub CLI (gh) |
⚠️ Wajib untuk --clone, --remote, --gh-auth, --init-secrets, --gh-action-init |
Autentikasi GitHub, fetch token, clone repo | brew install gh && gh auth login |
| kubectl | ⚙️ Opsional | Fetch webhook token otomatis dari k8s (--init-secrets) |
brew install kubectl |
Cek versi setelah install:
python3 --version # >= 3.7
pipx --version
docker --version
docker buildx version
git --version
gh --version && gh auth status
kubectl version --client # opsional
Install bq (pemula, langkah demi langkah)
# 1. Install pipx (kalau belum ada)
brew install pipx
pipx ensurepath # tambahkan pipx ke PATH — restart terminal setelah ini
# 2. Install build-q
pipx install build-q
# 3. Verifikasi
bq --version # harus menampilkan versi terpasang
build-q --version # alias — sama saja
# 4. Bootstrap awal (buat config + Docker buildx builder)
bq --init
Setelah bq --init selesai, file config akan ada di ~/.build-q/.env dan Docker Buildx builder siap dipakai.
Upgrade ke versi terbaru
# Rekomendasi (pipx)
pipx upgrade build-q
# Kalau pakai pip biasa
pip install --upgrade build-q
# Pin versi tertentu (opsional)
pipx install --force build-q==0.1.11
# Cek versi yang sedang terpasang
bq --version
Tips: jika pipx upgrade bilang "already at latest" tapi kamu yakin ada rilis baru, refresh cache PyPI:
pipx install --force build-q # reinstall dari PyPI terbaru
Uninstall
pipx uninstall build-q # kalau install via pipx
pip uninstall build-q # kalau install via pip
rm -rf ~/.build-q # hapus config (opsional)
Alur 5 menit pertama (pemula)
# 1. Masuk ke folder service Go/.NET yang sudah ada Dockerfile
cd my-service
# 2. Preview command yang akan dijalankan (aman — tidak eksekusi)
bq --dry-run
# 3. Build tanpa push ke registry
bq --no-push
# 4. Build + push ke registry (mode default)
bq
Kalau muncul error builder not found → jalankan bq --init sekali dulu.
Kalau muncul error authentication required saat push → login ke Docker Hub / registry: docker login.
🛠 Fitur
Build & Push
-
Zero-dependency: hanya Python 3.7+ standard library.
-
Git auto-detection: nama repo & ref (branch/tag/short-SHA) dari Git.
-
Mode sumber kode: build lokal,
--clone(viaghCLI), atau--remote(Buildx Git context). -
Registry idempotency: cek image di registry sebelum build → skip bila sudah ada (bypass
--rebuild). -
Smart env mapping (ref → env):
bq(danbq --clone/bq --compose) menyimpulkan environment otomatis dari nama ref (branch/tag). Nilai ini dipakai sebagai--build-arg BRANCH=(buildx) danENV=(compose):Ref (branch/tag) ENV Alasan v1.2.3,v0.x.y(semver tag)productionkonvensi rilis semver main,masterproductionbranch rilis utama staging,sandboxstagingpra-prod develop,developmentdevelopdev environment feature/foo,hotfix-x, dlldevelopsafe default Override manual:
--build-arg BRANCH=custom(buildx). -
Default netrc secret:
--secret id=netrc,src=$HOME/.netrcotomatis. -
Resource limit default: memory & CPU aman untuk laptop.
-
CI/CD alignment: baca
PORT/PORT2/PROJECT/IMAGEdaricicd/cicd.json. -
Dry run: pratinjau command tanpa eksekusi.
-
GitHub org shorthand: set
GITHUB_ORG=...di config → cukupbq <repo>bukanbq <owner>/<repo>. -
--remotefallback HTTPS: bilaSSH_AUTH_SOCKtidak tersetel,bqotomatis pindah ke HTTPS +GIT_AUTH_TOKEN(viagh auth token) untuk Buildx Git context — tidak perlu ssh-agent. -
--composemode: jalankanmake build ENV=...+make release ENV=...sebagai alternatifdocker buildx(cocok untuk repo yang alur build-nya via Makefile + docker compose).
Setup & Automation
--init: buat file config~/.build-q/.envdan auto-create Docker Buildx builder (bootstrap).- Template terpusat di gist: sejak
v0.1.14,--init-jx,--init-legacy, dan--gh-action-initfetch template dari gist mamatnurahmat (6 file). Cache lokal di~/.build-q/templates/(TTL 1 jam). Fallback ke bundled snapshot bila offline. Update / perbaikan template harus dilakukan di gist (viagh gist edit) — semua userbqotomatis dapat versi terbaru pada scaffold berikutnya. --init-jx: scaffoldMakefile+compose.yaml+Dockerfile(modern secret mount) +.github/workflows/trigger-ci.ymldaricicd/cicd.json. Auto-panggil--init-secretsbila git remote GitHub terdeteksi.--init-legacy: scaffoldMakefile+compose.yamluntuk pola legacy (Dockerfile pakaiARG GITHUB_USER/GITHUB_TOKEN— bukan BuildKit secret). Makefile auto-ambilgh auth tokenuntuk local dev. Dockerfile tidak di-overwrite — cocok untuk repo lama yang belum bisa migrasi ke secret mount.--gh-action-init: bootstrap standar.github/workflows/trigger-ci.ymlsebagai satu-satunya workflow — hapus semua workflow YAML lain di.github/workflows/, tulis ulang trigger-ci.yml, lalu set webhook secrets (WEBHOOK_TRIGGER_URL,WEBHOOK_TRIGGER_TOKEN).--init-secrets: set GitHub Actions secrets (WEBHOOK_TRIGGER_URL,WEBHOOK_TRIGGER_TOKEN) — auto-fetch token dari k8s secretwebhook-trigger-tokendi namespacejenkins-x, auto-detect target repo darigit remote.--fix-dockerfile: migrasi Dockerfile legacy menjadi modern. Deteksi & auto-fix:FROM ... as ...→AS(uppercase)- Hapus
ARG GITHUB_USER/ARG GITHUB_TOKEN RUN echo "machine github.com ..." > ~/.netrc && chmod ... && <cmd>→RUN --mount=type=secret,id=netrc,target=/root/.netrc \ ...- Baru: standalone
RUN echo ... > ~/.netrc(tanpa&& chmod && ...) → dihapus, lalu mount secret otomatis ditambahkan ke RUN line yang berisigo mod tidy/downloadataugo get. - Baru:
MAINTAINER foo(deprecated) →LABEL maintainer="foo" - Baru:
ENV KEY value(legacy) →ENV KEY=value - Backup asli disimpan ke
Dockerfile.bak.
--gh-auth: injeksi--build-arg GITHUB_USER+GITHUB_TOKENdarighCLI (workaround untuk Dockerfile legacy yang belum dimigrasi).- Auto-recover builder stale:
ensure_builderdeteksi endpoint rusak (misal socket Colima lama) dan recreate otomatis.
📦 Instalasi
pipx install build-q # rekomendasi (CLI global, virtualenv terisolasi)
# atau
pip install build-q
Dua entry point tersedia: build-q dan shorthand bq.
Upgrade ke versi terbaru:
pipx upgrade build-q
# atau
pip install --upgrade build-q
⚙️ Konfigurasi Awal (sekali saja)
bq --init # buat ~/.build-q/.env + create Docker buildx builder
bq --init --force # recreate config; builder tetap aman (cek dulu, buat bila tidak ada)
bq --config # tampilkan konfigurasi aktif
~/.build-q/.env
| Variable | Default | Keterangan |
|---|---|---|
BUILDER_NAME |
mybuilder |
Nama Docker Buildx builder |
REGISTRY_URL |
registry.example.com |
Docker registry (Qoin: loyaltolpi) |
DEFAULT_MEMORY |
4g |
Memory limit build |
DEFAULT_CPU_PERIOD |
100000 |
CPU period |
DEFAULT_CPU_QUOTA |
200000 |
CPU quota |
GIT_SSH_PREFIX |
git@github.com: |
Prefix SSH untuk --remote |
GITHUB_ORG |
(kosong) | Default org untuk shorthand bq <repo> |
WEBHOOK_TRIGGER_URL |
https://cicd-hw.qoin.id/trigger |
Endpoint webhook Jenkins X |
JX_KUBE_CONTEXT |
(kosong = current) | kubectl context untuk fetch token |
JX_KUBE_NAMESPACE |
jenkins-x |
Namespace secret |
JX_TOKEN_SECRET |
webhook-trigger-token |
Nama k8s secret berisi token |
Contoh minimal untuk Qoin:
BUILDER_NAME=cloud-loyaltolpi
REGISTRY_URL=loyaltolpi
GITHUB_ORG=Qoin-Digital-Indonesia
WEBHOOK_TRIGGER_URL=https://cicd-hw.qoin.id/trigger
🚀 Panduan Penggunaan
1. Build dari direktori lokal
Auto-detect nama repo & branch dari git:
cd my-service
bq # build + push (default)
bq --no-push # build tanpa push
bq --dry-run # preview command saja
bq my-service staging # eksplisit repo/ref
2. Build dari repo remote tanpa clone
# Dengan GITHUB_ORG di config → shorthand
bq plus-be-paymentlink-manager staging --remote
# Tanpa GITHUB_ORG → sertakan owner
bq Qoin-Digital-Indonesia/plus-be-paymentlink-manager staging --remote
# URL SSH/HTTPS penuh juga OK
bq git@github.com:owner/repo.git v1.0.0 --remote
Catatan
--remote: bilaSSH_AUTH_SOCKtidak tersetel (tidak jalaninssh-agent),bqotomatis fallback ke HTTPS +GIT_AUTH_TOKENsecret (viagh auth token) supaya Buildx Git context tetap bisa jalan tanpa perlu bootstrap ssh-agent.
3. Build dengan clone via gh CLI
bq --clone plus-be-paymentlink-manager staging
bq --clone plus-be-paymentlink-manager staging --clean # hapus folder setelah build
4. Preview command (dry-run)
bq --dry-run
bq plus-be-paymentlink-manager staging --remote --no-image-check --dry-run
5. Paksa rebuild (bypass image check)
bq plus-be-paymentlink-manager staging --remote --rebuild
6. Bootstrap CI/CD service baru (Jenkins X — modern, secret mount)
mkdir my-new-service && cd my-new-service
mkdir cicd && cat > cicd/cicd.json <<EOF
{"IMAGE":"my-new-service","PROJECT":"qoinplus","PORT":"8080"}
EOF
bq --init-jx # scaffold Makefile/compose/Dockerfile/workflow
git init && git remote add origin git@github.com:Qoin-Digital-Indonesia/my-new-service.git
bq --init-secrets # set webhook secrets di GitHub (auto-detect repo)
git add . && git commit -m "chore: bootstrap CI/CD"
git push -u origin main # trigger Jenkins X pipeline via GitHub Actions
7. Bootstrap CI/CD service legacy (Dockerfile pakai ARG GITHUB_USER/TOKEN)
Kalau Dockerfile di repo lama belum bisa dimigrasi ke --mount=type=secret, pakai --init-legacy. Makefile-nya akan auto-ambil gh auth token untuk local dev.
cd my-old-service # Dockerfile-nya masih pakai ARG GITHUB_USER/TOKEN
bq --init-legacy # scaffold Makefile + compose.yaml (Dockerfile TIDAK ditimpa)
gh auth login # sekali saja
make build ENV=staging # token auto-diambil dari `gh auth token`
make release ENV=staging
8. Bootstrap GitHub Actions trigger sebagai satu-satunya workflow
Berguna kalau repo punya banyak workflow lama yang tidak dipakai lagi:
cd existing-repo
bq --gh-action-init # hapus workflow lain + tulis trigger-ci.yml + set webhook secrets
bq --gh-action-init --token xxxx # skip kubectl fetch, pakai token eksplisit
9. Migrasi Dockerfile legacy (ARG-based netrc → secret mount)
cd my-old-service
bq --fix-dockerfile # migrasi ./Dockerfile (backup ke .bak)
bq --fix-dockerfile path/to/Dockerfile
bq --no-push --rebuild # test build hasil migrasi
Yang di-fix otomatis:
FROM x as y→FROM x AS yARG GITHUB_USER/TOKENdihapusRUN echo "machine github.com ..." > ~/.netrc && chmod ... && <cmd>→RUN --mount=type=secret,id=netrc,...- Standalone
RUN echo ... > ~/.netrc→ dihapus, secret mount otomatis nempel diRUN go mod tidy/download/get MAINTAINER foo→LABEL maintainer="foo"ENV KEY value→ENV KEY=value
10. Workaround Dockerfile legacy tanpa migrasi (--gh-auth)
bq plus-be-service staging --remote --rebuild --gh-auth
# → inject GITHUB_USER dari `gh api user` + GITHUB_TOKEN dari `gh auth token`
11. Setup secrets Jenkins X untuk repo existing
cd existing-repo
bq --init-secrets # auto-detect dari git
bq --init-secrets Qoin-Digital-Indonesia/foo-service # eksplisit
bq --init-secrets foo-service --token xxxx # skip kubectl
12. Mode --compose (build via make build && make release)
Untuk repo yang alur build-nya sudah pakai Makefile + docker compose (mis. hasil --init-jx / --init-legacy). ENV= disimpulkan dari ref — lihat tabel Smart env mapping di atas:
# auto-detect: repo & ref dari git di direktori aktif
bq --compose # branch `develop` → ENV=develop
bq --compose my-service staging # ENV=staging
bq --compose my-service v1.2.3 # ENV=production
bq --compose my-service main # ENV=production
bq --compose --dry-run # preview command
# gabung dengan --clone (clone dulu, cd, lalu make build+release)
bq --clone Qoin-Digital-Indonesia/foo staging --compose # ENV=staging
bq --clone Qoin-Digital-Indonesia/foo v1.2.3 --compose # ENV=production
Registry idempotency di --compose: tag yang di-probe mengikuti aturan Makefile — git describe --tags --exact-match || git rev-parse --short HEAD. Jadi kalau HEAD di tag v1.2.3, bq cek registry/image:v1.2.3 (bukan short commit) — sama dengan tag yang di-push make release, sehingga early skip berfungsi benar.
13. Contoh full (customize secret, platform, build-arg)
bq plus-be-service staging \
--secret id=custom,src=/path/to/secret \
--platform linux/amd64 \
--no-push \
--build-arg BRANCH=custom-branch \
--build-arg FEATURE_FLAG=on
🔗 Perintah Lengkap
bq [<repo> [<ref>]] [OPTIONS]
Subcommands (mutually exclusive):
--init Buat ~/.build-q/.env + init Buildx builder
--init --force Recreate config
--config Tampilkan konfigurasi aktif
--init-jx Scaffold Makefile/compose/Dockerfile/workflow (modern secret mount)
--init-jx --force Overwrite file existing
--init-legacy Scaffold Makefile + compose.yaml pola legacy (ARG GITHUB_USER/TOKEN)
--init-legacy --force Overwrite file existing
--gh-action-init Bootstrap standar trigger-ci.yml (hapus workflow lain + set secrets)
--init-secrets [<repo>] Set GitHub Actions webhook secrets
--fix-dockerfile [PATH] Migrasi Dockerfile legacy ke secret mount (+ MAINTAINER/ENV/standalone netrc)
Build modes:
(default) Build dari direktori lokal via docker buildx
--clone <owner/repo> Clone via `gh` CLI, lalu build
--clone ... --clean Hapus folder clone setelah build
--remote Build via Buildx Git context (tanpa clone) — auto-fallback HTTPS bila SSH_AUTH_SOCK kosong
--compose Jalankan `make build ENV=... && make release ENV=...` (bukan buildx)
Build options:
--cicd PATH Path cicd.json (default: cicd/cicd.json)
--context DIR Build context (default: .)
-f, --dockerfile PATH Path Dockerfile (default: Dockerfile)
-t, --tag IMAGE:TAG Override image tag
--push / --no-push Push image (default: push)
--image-check / --rebuild Cek image di registry, skip bila ada (default: on)
--no-image-check Sama dengan --rebuild
--platform PLATFORM Target platform (default: linux/amd64)
--build-arg KEY=VALUE Build arg (dapat diulang)
--secret id=ID,src=PATH Secret build (dapat diulang; netrc otomatis)
--gh-auth Inject GITHUB_USER/TOKEN dari `gh` CLI
--token VALUE Webhook token (dengan --init-secrets / --gh-action-init)
--dry-run Preview command tanpa eksekusi
--version Tampilkan versi
📋 Requirements
- Python 3.7+
- Docker + Buildx plugin
- Git (opsional; wajib untuk auto-detect & mode local)
- GitHub CLI (
gh) — wajib untuk--clone,--remote,--gh-auth,--init-secrets,--gh-action-init - kubectl — opsional; hanya untuk
--init-secrets/--gh-action-init(fetch token otomatis dari cluster)
📄 Template Terpusat (Gist)
Sejak v0.1.14, template scaffolding hidup di gist publik, bukan hard-coded di package:
- URL gist: https://gist.github.com/mamatnurahmat/35cc4c36e7c7c2d236a1b5149cdbcfd9
- Raw base:
https://gist.githubusercontent.com/mamatnurahmat/<gist-id>/raw/<filename> - 6 file:
Makefile.modern,compose.yaml.modern,Dockerfile.modern,Makefile.legacy,compose.yaml.legacy,trigger-ci.yml
Alur load:
load_template(name)
├── 1. cache ~/.build-q/templates/<file> (TTL 3600s, fresh?) ─► pakai
├── 2. fetch dari gist raw URL ─► refresh cache + pakai
├── 3. cache lama (expired) ─► pakai (dengan warning)
└── 4. bundled snapshot di build_q/templates.py ─► pakai (warning)
Cara update template
Update HARUS via gist, jangan edit build_q/templates.py. _BUNDLED_* di file itu hanya snapshot offline-fallback.
# Clone gist untuk edit local
gh gist clone 35cc4c36e7c7c2d236a1b5149cdbcfd9 build-q-templates
cd build-q-templates
# Edit file yang ingin diubah (mis. Makefile.modern)
vim Makefile.modern
# Commit + push (gist adalah git repo — otomatis publish)
git commit -am "fix: adjust Makefile.modern IMAGE_TAG logic"
git push
# Verifikasi raw URL sudah kepakai
curl -s https://gist.githubusercontent.com/mamatnurahmat/35cc4c36e7c7c2d236a1b5149cdbcfd9/raw/Makefile.modern | head
Force refresh cache di sisi user
Kalau user ingin ambil template terbaru sebelum TTL expired:
rm -rf ~/.build-q/templates # hapus cache — next scaffold auto-fetch
# atau override TTL per-invocation:
BUILD_Q_GIST_TTL=0 bq --init-jx
Override gist source (advanced)
Untuk fork/private mirror, override via env vars:
export BUILD_Q_GIST_USER=your-org
export BUILD_Q_GIST_ID=abcd1234...
export BUILD_Q_GIST_TTL=7200 # 2 jam
export BUILD_Q_GIST_TIMEOUT=15 # 15 detik
bq --init-jx
Sinkronisasi bundled fallback (maintainer only)
Saat rilis bq baru, refresh _BUNDLED_* di build_q/templates.py agar offline user tetap dapat template terkini:
GID=35cc4c36e7c7c2d236a1b5149cdbcfd9
for f in Makefile.modern compose.yaml.modern Dockerfile.modern Makefile.legacy compose.yaml.legacy trigger-ci.yml; do
curl -s "https://gist.githubusercontent.com/mamatnurahmat/$GID/raw/$f" > "/tmp/$f"
done
# lalu paste isi ke masing-masing _BUNDLED_* di build_q/templates.py
🧭 Troubleshooting
| Gejala | Kemungkinan penyebab | Solusi |
|---|---|---|
builder "mybuilder" not found |
Buildx belum di-bootstrap | bq --init |
authentication required saat push |
Belum login registry | docker login (atau docker login <registry>) |
invalid empty ssh agent socket (mode --remote) |
SSH_AUTH_SOCK kosong |
Sudah auto-fallback ke HTTPS + gh auth token. Kalau tetap gagal → gh auth login |
gh: command not found |
GitHub CLI belum ter-install | brew install gh && gh auth login |
--init-secrets gagal fetch token |
Konteks kubectl salah / secret tidak ada | Set JX_KUBE_CONTEXT di ~/.build-q/.env, atau --token xxxx |
| Build sukses tapi image tidak muncul di registry | Salah REGISTRY_URL di config |
bq --config → verifikasi, lalu bq --init --force |
bq --version tidak berubah setelah upgrade |
pipx cache | pipx install --force build-q |
🚀 Development & Release
Ada dua cara rilis: (A) via GitHub Actions otomatis dari tag — direkomendasikan, dan (B) via Makefile lokal — cocok untuk hotfix/debug.
A. Auto-release via GitHub Actions (rekomendasi)
Workflow .github/workflows/pypi-release.yml dipicu oleh push tag v* (atau manual via workflow_dispatch) dan otomatis build + upload ke PyPI.
Flow rilis versi berikutnya:
# 1. Bump versi (patch) — auto-update pyproject.toml + build_q/__init__.py
python3 scripts/bump_version.py # bump patch (0.1.12 → 0.1.13)
# atau versi eksplisit:
python3 scripts/bump_version.py 0.2.0
# 2. Baca versi baru
VER=$(grep -m1 '^version = ' pyproject.toml | sed 's/.*"\(.*\)".*/\1/')
echo "Releasing v$VER"
# 3. Commit bump
git add pyproject.toml build_q/__init__.py
git commit -m "release: v$VER"
# 4. Tag + push (tag inilah yang memicu workflow)
git tag "v$VER"
git push origin main "v$VER"
# 5. Pantau workflow
gh run watch --repo mamatnurahmat/build-q --exit-status
# atau lihat di browser:
gh run list --workflow=pypi-release.yml --repo mamatnurahmat/build-q --limit 3
Setelah workflow selesai (± 15 detik), package tersedia di:
- https://pypi.org/project/build-q//
- Upgrade user:
pipx upgrade build-q
Apa yang dilakukan workflow (lihat .github/workflows/pypi-release.yml):
- Checkout repo pada commit tag.
- Setup Python 3.12.
- Verifikasi tag — pastikan
v<X>cocok dengan version dipyproject.tomldanbuild_q/__init__.py. Bila mismatch, gagal (mencegah rilis "kosong"). - Install
build+twine. - Build sdist + wheel via
python -m build. - Validate dengan
twine check dist/*. - Upload via
twine upload --skip-existing— kalau versi sudah ada di PyPI, aman skip (idempoten). - Summary dengan link PyPI.
Autentikasi: workflow pakai GitHub Actions secret PYPI_API_TOKEN (username __token__). Token PyPI project-scoped ini di-set sekali via gh secret set. Cara set/rotate token:
# Metode andal — pakai env-file (JANGAN pakai --body - karena pipe stdin
# rawan corrupt untuk token panjang).
TMPFILE=$(mktemp) && chmod 600 "$TMPFILE"
python3 -c "
import configparser, os
c = configparser.ConfigParser()
c.read(os.path.expanduser('~/.pypirc'))
print('PYPI_API_TOKEN=' + c['pypi']['password'])
" > "$TMPFILE"
gh secret set -f "$TMPFILE" --repo mamatnurahmat/build-q
rm -f "$TMPFILE"
# Verifikasi:
gh secret list --repo mamatnurahmat/build-q
Manual trigger tanpa tag (misal untuk re-upload versi yang sudah ada di pyproject.toml — --skip-existing akan handle):
gh workflow run pypi-release.yml --repo mamatnurahmat/build-q
Cek/re-run workflow yang gagal:
gh run list --workflow=pypi-release.yml --repo mamatnurahmat/build-q --limit 5
gh run view <RUN_ID> --repo mamatnurahmat/build-q --log-failed
gh run rerun <RUN_ID> --failed --repo mamatnurahmat/build-q
B. Release manual via Makefile (lokal)
Cocok untuk hotfix cepat / troubleshoot. Baca kredensial dari ~/.pypirc lokal.
make build # build sdist + wheel ke dist/
make install # install lokal (pipx editable)
make release # bump patch, build, install, upload ke PyPI
make release V=1.0.0 # release versi spesifik
make clean # bersihkan artefak
Langkah make release:
scripts/bump_version.pybump patch dipyproject.toml+build_q/__init__.py.- Build sdist + wheel via
python3 -m build(fallback:pipx run --spec build pyproject-build). - Install lokal editable via
pipx install -e . --force. - Upload ke PyPI via
pipx run twine upload --skip-existing dist/*— kredensial dari~/.pypirc.
⚠️ Setelah
make release, jangan lupa commit + tag + push supaya history Git & GitHub Actions selaras dengan PyPI:VER=$(grep -m1 '^version = ' pyproject.toml | sed 's/.*"\(.*\)".*/\1/') git add pyproject.toml build_q/__init__.py git commit -m "release: v$VER" git tag "v$VER" && git push origin main "v$VER"Tag push tetap akan memicu workflow, tapi karena
--skip-existing, upload akan skip (idempoten).
Release troubleshooting
| Gejala | Penyebab | Solusi |
|---|---|---|
| Workflow gagal di step Verify tag matches | Tag v0.1.13 tapi pyproject.toml masih 0.1.12 |
Jalankan python3 scripts/bump_version.py 0.1.13 dulu, commit, re-tag |
Workflow gagal 403 Forbidden di upload |
Secret PYPI_API_TOKEN corrupt / kadaluwarsa |
Re-set secret via metode env-file di atas |
PyPI 400 File already exists |
Versi sudah pernah di-upload dari lokal | Sudah di-handle --skip-existing — workflow tetap hijau |
| Version di PyPI tidak berubah setelah tag | Tag lama di-hapus & re-push versi sama | PyPI TIDAK menerima re-upload versi yang sama — bump patch dulu |
📄 License
MIT
Release files for build-q 0.1.14
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| build_q-0.1.14.tar.gz | 40.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| build_q-0.1.14-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 74.8 kB
Release files / build_q-0.1.14.tar.gz
| Download URL | build_q-0.1.14.tar.gz |
|---|---|
| Size | 40.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e4628fc82a789c3ab93c7042a674aa7b434d026631be3f5e5ecea7c23f3a485f
|
|
BLAKE2b-256 checksum How to use checksums |
55c863426d99cd702a7c90f299f66f142e6a60ed28abe9e91c445234bddac6cd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|
Release files / build_q-0.1.14-py3-none-any.whl
| Download URL | build_q-0.1.14-py3-none-any.whl |
|---|---|
| Size | 34.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9163434b06cb24ab5fc6df44a126321fad43aa65ac4afe91dc36efbfd29d621c
|
|
BLAKE2b-256 checksum How to use checksums |
e92b0ccc6f7ea192106f7953590ca2ff4a8c5101ab87d80439d654573e7e01b0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|