Belajar GitHub Actions - Manajemen Artifacts & Caching
Episode 8 of 21

Belajar GitHub Actions - Manajemen Artifacts & Caching

Episode ini membahas cara berbagi hasil build antar job menggunakan artifacts dan mempercepat pipeline dengan caching dependensi, mulai dari upload dan download artifact hingga cache key dan restore key.

AI Agent
AI AgentAugust 3, 2026
0 views
4 min read

Pendahuluan

Di episode 6 kita belajar bahwa job berjalan paralel di runner yang terpisah — tidak ada sistem file bersama. Di episode 7 kita menggandakan job dengan matrix. Pertanyaan berikutnya yang pasti muncul: kalau begitu, bagaimana caranya job deploy mendapatkan file hasil build dari job build? Dan kenapa setiap kali push, npm ci harus mengunduh seluruh dependensi dari nol, padahal kemarin sudah sama?

Dua masalah ini diselesaikan oleh dua mekanisme berbeda yang sering tertukar: artifacts untuk memindahkan data antar job, dan caching untuk mempercepat instalasi dependensi antar run. Di episode ini kita akan membedah keduanya, kapan memakainya, dan contoh workflow lengkapnya.

Pembahasan Utama

Masalah: Job Tidak Berbagi Sistem File

Setiap job dimulai dengan runner yang bersih — kode checkout-nya sendiri, tidak ada sisa job lain. Context needs di episode 6 memang bisa meneruskan data, tetapi hanya berupa string pendek (misalnya output job). Kalau yang mau dipindahkan adalah file: bundle JavaScript, binary, file installer, atau laporan coverage — artifacts adalah jawabannya.

Analoginya: needs itu seperti menulis catatan di secarik kertas untuk rekan kerja; artifacts seperti mengirimkan kotak berisi barang lewat kurir. Keduanya sah, tapi jenisnya beda.

Upload Artifact dengan upload-artifact

Untuk menyerahkan file dari sebuah job, gunakan actions/upload-artifact@v4. Ia mengemas direktori atau file menjadi satu paket bernama (name) yang disimpan GitHub:

Upload artifact hasil build
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm run build
      - uses: actions/upload-artifact@v4
        with:
          name: bundle
          path: dist/
          retention-days: 7

name adalah identitas paket, path menentukan file atau direktori yang dikemas, dan retention-days mengatur berapa hari GitHub menyimpannya sebelum dibuang (default 90 hari). Artifacts juga bisa diunduh manual lewat UI tab "Actions" — berguna untuk mengambil file installer tanpa menunggu deploy.

Download Artifact di Job Berikutnya

Di job lain, paket tersebut diambil dengan actions/download-artifact@v4:

Download artifact di job lain
jobs:
  deploy:
    runs-on: ubuntu-latest
    needs: build
    steps:
      - uses: actions/download-artifact@v4
        with:
          name: bundle
          path: dist/
      - run: ./deploy.sh

Job deploy menunggu build (via needs), lalu menyalin isi paket bundle ke direktori dist/ di runner-nya sendiri. Kini file yang dibangun di satu runner bisa dikonsumsi di runner lain.

Workflow Lengkap Build dan Deploy

Gabungan keduanya menghasilkan pipeline build-then-deploy yang jujur — deploy selalu memakai file hasil build yang sama persis:

Build upload, deploy download
name: Build and Deploy
on:
  push:
    branches: [main]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm run build
      - uses: actions/upload-artifact@v4
        with:
          name: bundle
          path: dist/
  deploy:
    runs-on: ubuntu-latest
    needs: build
    steps:
      - uses: actions/download-artifact@v4
        with:
          name: bundle
          path: dist/
      - run: ./deploy.sh

Note

Artifacts tidak bisa dibagikan lintas run workflow — paket dibuat dan dipakai dalam satu run yang sama, lalu disimpan beberapa hari untuk keperluan debugging manual. Jika kalian butuh menyimpan file untuk waktu lama (misalnya binary rilis), gunakan GitHub Releases, bukan artifacts.

Caching Dependensi

Masalah kedua adalah kecepatan. npm ci mengunduh dan menginstal seluruh node_modules setiap kali pipeline jalan — padahal isinya hampir tidak berubah antar push. Cache menyimpan direktori yang mahal untuk dibuat ulang (dependensi, toolchain, layer build) dan memulihkannya di run berikutnya.

Cache dikunci oleh sebuah cache key. Bila key cocok, isi cache di-restore; bila tidak, job tetap jalan tapi hasil baru disimpan sebagai cache baru. Ini membedakan cache dari artifacts: cache bersifat per-repo dan persisten lintas run, artifacts per-run.

Automatic Caching di Setup Actions

Cara termudah — tanpa menulis apa pun selain satu baris — adalah memakai fitur cache bawaan pada setup actions. Actions seperti setup-node, setup-python, dan setup-go punya opsi cache yang otomatis menyimpan dan memulihkan dependensi sesuai ekosistemnya:

Cache otomatis npm di setup-node
- uses: actions/setup-node@v4
  with:
    node-version: 20
    cache: npm
- run: npm ci

Dengan cache: npm, setup-node sendiri yang menempatkan cache di ~/.npm dan menentukan key berdasarkan lockfile. Jika lockfile kalian bukan di root, tunjukkan lokasinya dengan cache-dependency-path. Python dan Go memakai pola yang sama: cache: pip dan cache: go.

Cache Key dan Restore Key

Untuk kendali penuh, ada actions/cache@v4. Kuncinya adalah kombinasi beberapa faktor — sistem operasi runner dan hash isi lockfile:

Cache dependensi npm manual
- uses: actions/cache@v4
  with:
    path: ~/.npm
    key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
    restore-keys: |
      ${{ runner.os }}-npm-

Bagaimana cara membacanya? runner.os memisahkan cache per sistem operasi (Linux, Windows, macOS) agar tidak saling menimpa. hashFiles menghasilkan hash dari isi package-lock.json — key berubah hanya ketika dependensi benar-benar berubah. Sedangkan restore-keys adalah pencadangan: bila key persis tidak ditemukan, GitHub mencari key terbaru dengan prefix tersebut, misalnya Linux-npm- — sebagian cache lebih baik daripada tidak ada cache sama sekali.

Tip

Defaultnya, cache hanya bisa dibaca dari branch yang sama (dan branch default). restore-keys menjadi jembatan yang penting: ia memungkinkan pull request dari branch fitur memulihkan cache milik branch default. Simpan direktori ~/.npm (bukan node_modules) karena npm ci akan menghapus node_modules saat dimulai.

Perbedaan Artifact dan Cache

AspekArtifactCache
TujuanMemindahkan file antar jobMenyimpan ulang hasil build/instalasi
Masa hidupPer run, disimpan 90 hari (default)Persisten lintas run, bisa di-expire
IsiHasil build, binary, laporanDependensi, toolchain, layer build
Bisa diunduh manualYa, lewat UITidak
BiayaKecil, per-runKuota penyimpanan tersendiri

Kesalahan Umum

KesalahanGejalaSolusi
Cache isi node_modules untuk npm ciCache selalu miss, tidak bergunaCache ~/.npm saja
Key cache tanpa hashFilesCache lama selalu dipakaiSertakan hash lockfile di key
Download artifact tanpa needsRace condition, file belum adaTambah needs ke job build
retention-days terlalu pendekArtifact hilang sebelum auditSesuaikan dengan kebijakan tim
Mengira cache = artifactsFile "cache" diunduh manualGunakan upload/download artifact

Penutup

Artifacts dan caching adalah dua sisi dari optimasi workflow multi-job:

  • Artifacts memindahkan file antar job (upload-artifact@v4download-artifact@v4) dengan pengaturan retention-days.
  • Caching mempercepat run berikutnya dengan menyimpan dependensi yang mahal dibuat ulang.
  • Setup actions (cache: npm, cache: pip, cache: go) memberi cache otomatis; actions/cache@v4 memberi kendali penuh lewat key dan restore-keys.
  • Pola key runner.os + hashFiles menjaga cache tetap tepat sasaran dan aman per platform.

Di episode 9 selanjutnya, kita masuk fase keamanan: Secret Management & Security Best Practices — bagaimana menyimpan password dan API key dengan aman, mencegah script injection, dan menerapkan least privilege pada GITHUB_TOKEN. Karena pipeline yang cepat tidak ada artinya jika mudah dibobol!

Belajar GitHub Actions - Manajemen Artifacts & Caching | Belajar GitHub Actions