Skip to main content
BlogDevOps

Reusable Workflow vs Composite Action di GitHub Actions

Dua cara berhenti menyalin-tempel YAML CI antar repo, dan aturan yang saya pakai untuk memilih di antaranya.

Matthews Wong

Software Engineer

Juli 20269 menit baca
Reusable Workflow vs Composite Action di GitHub Actions

Foto oleh RICHI Manufacture via Wikimedia Commons (CC BY 4.0)

Ringkasan Utama

Gunakan composite action untuk berbagi urutan langkah di dalam satu job, seperti awalan checkout-dan-setup yang berjalan di runner pemanggil. Gunakan reusable workflow untuk berbagi satu atau lebih job utuh, mengatur runner, menjaga environment, dan menerima secret. Composite action menyisip ke dalam job; reusable workflow dipanggil sebagai sebuah job.

Setiap tim yang menjalankan CI di lebih dari segelintir repositori menabrak tembok yang sama: empat puluh baris checkout, setup bahasa, restore cache, lint, dan test yang sama disalin-tempel ke setiap file workflow. Ketika versi Node naik atau cache key berubah, Anda menyuntingnya di dua belas tempat dan melewatkan dua. GitHub Actions memberi Anda dua alat untuk membunuh duplikasi itu, dan keduanya terus tertukar karena sama-sama disebut reuse. Keduanya tidak dapat saling menggantikan.

Perbedaannya lebih sederhana daripada yang dibuat kebanyakan artikel. Composite action membungkus langkah. Reusable workflow membungkus job. Begitu itu dipahami, hampir setiap keputusan mengikuti secara otomatis, termasuk ke mana secret bisa mengalir dan runner mana yang menjalankan kode Anda. Saya menjalankan CI di beberapa layanan kecil pada VPS swakelola, dan menetapkan pembagian ini dengan benar itulah yang menjaga logika deploy saya tetap di satu file alih-alih tersebar di setiap repo.

Perbedaan inti: langkah versus job

Composite action dirujuk dari dalam daftar steps sebuah job dengan sintaks uses yang sama yang sudah Anda pakai untuk action pihak ketiga. Ia tidak bisa mendefinisikan runner-nya sendiri, tidak bisa memuat job, dan langkah internalnya menyusut menjadi satu baris di log. Ia berjalan di mesin mana pun yang dipilih job pemanggil. Reusable workflow sebaliknya: ia dirujuk di tingkat job, mendefinisikan runner-nya sendiri dengan runs-on, bisa memuat beberapa job, dan setiap langkah tercatat secara real time. Perbedaan ketinggian itu menggerakkan segala hal lainnya.

DimensiComposite actionReusable workflow
Unit reuseUrutan langkahSatu atau lebih job utuh
Cara pemanggilanSebagai langkah (uses di dalam steps)Di tingkat job (uses pada job)
Kontrol runnerBerjalan di runner pemanggilMendefinisikan runs-on sendiri
SecretTidak ada blok secrets; kirim nilai sebagai inputSecret native plus secrets inherit
LoggingMenyusut jadi satu langkahSetiap langkah tercatat terpisah
MarketplaceBisa dipublikasikan ke MarketplaceTidak bisa dipublikasikan; dirujuk lewat path

Kapan memilih composite action

Pilih composite action ketika beberapa workflow butuh awalan yang sama tetapi masing-masing berlanjut berbeda sesudahnya. Kasus klasiknya adalah checkout, menyiapkan runtime bahasa, dan me-restore cache dependensi. Job test Anda menambah langkah test setelahnya, job build menambah langkah build, dan job release menambah langkah pengemasan. Composite action membiarkan tiap job memegang kendali penuh atas apa yang datang berikutnya sambil berbagi setup yang membosankan. Anda juga bisa menumpuk beberapa composite action dan langkah inline dalam job yang sama dalam urutan apa pun, yang tidak bisa dilakukan reusable workflow.

# .github/actions/setup-node-app/action.yml
name: "Setup Node app"
description: "Checkout, install Node, restore cache, install deps"
inputs:
  node-version:
    description: "Node version to install"
    required: false
    default: "20"
runs:
  using: "composite"
  steps:
    - uses: actions/checkout@v4
    - uses: actions/setup-node@v4
      with:
        node-version: ${{ inputs.node-version }}
        cache: "npm"
    - run: npm ci
      shell: bash   # required on every run step in a composite action
# a workflow in the same repo consuming the composite action
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: ./.github/actions/setup-node-app
        with:
          node-version: "22"
      - run: npm test        # this job keeps control after setup

Setiap langkah run di dalam composite action harus mendeklarasikan shell-nya sendiri (misalnya shell: bash). Ia tidak diwarisi dari pemanggil, dan melupakannya adalah alasan paling umum sebuah composite action gagal dimuat dengan galat validasi yang membingungkan.

Kapan memilih reusable workflow

Pilih reusable workflow ketika Anda ingin membakukan seluruh pipeline, bukan sekadar awalan. Tim platform memiliki pemilihan runner, gerbang environment, graf job, dan kontrak secret; tim pemakai cukup memanggilnya dan mengirim parameter. Ini alat yang tepat ketika logika bersama harus berjalan di runner tertentu terlepas dari pemanggil, ketika ia perlu memakai secret, atau ketika eksekusi bergantung pada kondisi if yang dievaluasi di tingkat job. Pipeline deploy saya ada di sini: satu reusable workflow mendefinisikan build, push ke registry, dan deploy SSH, dan setiap repo layanan memanggilnya dengan input environment yang berbeda.

# .github/workflows/deploy.yml in the org/ci-templates repo
on:
  workflow_call:
    inputs:
      environment:
        required: true
        type: string
    secrets:
      SSH_KEY:
        required: true
jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: ${{ inputs.environment }}
    steps:
      - uses: actions/checkout@v4
      - run: ./deploy.sh
        env:
          SSH_KEY: ${{ secrets.SSH_KEY }}

Mengirim input dan secret, bagian yang salah dipahami semua orang

Input bertipe dan berperilaku sama untuk keduanya: Anda mendeklarasikannya dan mengirimnya dengan kata kunci with. Secret adalah tempat keduanya berbeda tajam. Reusable workflow punya blok secrets kelas satu di trigger workflow_call-nya, dan pemanggil boleh mengirim setiap secret secara eksplisit atau memakai secrets inherit untuk menyerahkan semua secret workflow pemanggil sekaligus. Inherit hanya bekerja ketika pemanggil dan workflow yang dipanggil berada di organisasi atau enterprise yang sama.

# the caller: reusable workflow is invoked as the job itself
jobs:
  call-deploy:
    uses: my-org/ci-templates/.github/workflows/deploy.yml@v1
    with:
      environment: production
    secrets: inherit   # hands over all caller secrets at once

Composite action tidak punya blok secrets dan tidak bisa membaca konteks secrets sendiri. Untuk memakai secret di dalamnya Anda harus mengirim nilainya sebagai input biasa dari langkah pemanggil. GitHub tetap menyamarkan nilai secret terdaftar di log, tetapi Anda kehilangan kontrak secret bertipe, jadi anggap logika yang penuh secret sebagai sinyal bahwa Anda ingin reusable workflow, bukan composite action.

Memangkas duplikasi di banyak repositori

Untuk reuse antar repo, taruh kedua artefak di satu repositori terpusat, biasa dinamai seperti ci-templates, dan rujuk dari setiap repo lain. Sematkan rujukan Anda ke tag atau SHA commit penuh, jangan pernah ke branch yang bergerak, agar perubahan pada logika bersama tidak diam-diam merusak setiap pipeline hilir sekaligus. Luncurkan versi baru maju dengan tag seperti v1, v2 dan biarkan pemakai memutakhirkan dengan sengaja. Sadari batas platform saat Anda menyusunnya: satu workflow hanya bisa merujuk sejumlah terbatas reusable workflow, dan nesting punya kedalaman maksimum, jadi jaga rantai tetap dangkal dan datar alih-alih membangun menara dalam berisi workflow memanggil workflow.

Hibrida praktis bekerja paling baik dalam skala besar: simpan logika setup kecil dan generik sebagai composite action agar job mana pun bisa menyusunnya, dan simpan seluruh pipeline baku sebagai reusable workflow. Reusable workflow itu sendiri bisa memakai composite action Anda secara internal, memberi Anda satu tempat untuk reuse tingkat langkah dan satu tempat untuk reuse tingkat job.

Aturan keputusan yang benar-benar saya pakai

  • Apakah saya berbagi langkah yang menyisip ke job lebih besar yang tetap dikendalikan pemanggil? Composite action.
  • Apakah saya berbagi satu atau lebih job utuh, termasuk runner dan graf job? Reusable workflow.
  • Apakah logika bersama butuh secret asli atau gerbang environment? Reusable workflow, selalu.
  • Haruskah ia berjalan di runner tertentu terlepas dari siapa yang memanggil? Reusable workflow.
  • Apakah saya ingin ia dipublikasikan di Marketplace untuk dipakai orang lain? Composite action.

Keduanya saling melengkapi, bukan bersaing. Tim dengan CI paling rapi yang pernah saya lihat memakai keduanya dengan sengaja: composite action untuk awalan langkah yang dapat dipakai ulang dan reusable workflow untuk pipeline baku yang memakainya. Tetapkan perbedaan langkah-versus-job dengan benar dan sisanya hanyalah menyambung input dan, dengan hati-hati, secret.

FAQ

Pertanyaan Umum

Jawaban singkat untuk pertanyaan yang paling sering diajukan pembaca tentang topik ini.

Apa perbedaan utama antara reusable workflow dan composite action?

Composite action membungkus urutan langkah yang menyisip ke sebuah job yang tetap dikendalikan pemanggil, dan ia berjalan di runner pemanggil. Reusable workflow membungkus satu atau lebih job utuh, mendefinisikan runner-nya sendiri, dan dipanggil di tingkat job alih-alih sebagai langkah. Singkatnya, composite action berbagi langkah dan reusable workflow berbagi job.

Bisakah composite action memakai secret di GitHub Actions?

Tidak secara langsung. Composite action tidak punya blok secrets dan tidak bisa membaca konteks secrets sendiri. Untuk memakai secret Anda harus mengirim nilainya sebagai input biasa dari langkah pemanggil. Jika logika bersama Anda sangat bergantung pada secret, itu sinyal kuat untuk memakai reusable workflow.

Bagaimana cara mengirim semua secret ke reusable workflow sekaligus?

Gunakan secrets: inherit pada job pemanggil alih-alih mendaftar setiap secret. Ini menyerahkan semua secret workflow pemanggil ke workflow yang dipanggil. Ini hanya bekerja ketika pemanggil dan reusable workflow berada di organisasi atau enterprise yang sama.

Bagaimana cara berbagi logika CI di banyak repositori berbeda?

Taruh composite action dan reusable workflow Anda di satu repositori terpusat, sering dinamai ci-templates, dan rujuk dari setiap repo lain. Sematkan rujukan ke tag atau SHA commit penuh alih-alih branch yang bergerak agar perubahan tidak diam-diam merusak setiap pipeline hilir. Publikasikan versi baru di balik tag seperti v1 dan v2 agar pemakai memutakhirkan dengan sengaja.

Kenapa composite action saya gagal dengan galat shell?

Setiap langkah run di dalam composite action harus mendeklarasikan shell-nya sendiri, seperti shell: bash. Berbeda dari langkah workflow biasa, shell tidak diwarisi dari pemanggil. Melupakannya adalah alasan paling umum composite action gagal dimuat dengan galat validasi yang membingungkan.