+7

Reusable Workflows - Tái sử dụng Workflows trong Github Actions

1. Mở đầu

Trong môi trường phát triển phần mềm hiện đại, tự động hóa là một yếu tố quan trọng giúp tăng cường hiệu suất làm việc và giảm thiểu sai sót. GitHub Actions là một công cụ mạnh mẽ giúp các nhà phát triển tự động hóa nhiều công việc trong quy trình CI/CD (Continuous Integration/Continuous Deployment). Một trong những tính năng nổi bật và hữu ích của GitHub Actions là khả năng tái sử dụng workflows (Reusable Workflows). Bài viết này sẽ giúp bạn hiểu rõ hơn về Reusable Workflows, lợi ích của chúng, các thành phần cấu thành, cách cấu hình và sử dụng chúng trong GitHub Actions.

2. Reusable Workflows là gì?

Reusable Workflows trong GitHub Actions là các workflows được thiết kế để có thể tái sử dụng nhiều lần trong các repository khác nhau hoặc trong cùng một repository. Thay vì phải sao chép và dán các đoạn mã workflow từ dự án này sang dự án khác, bạn có thể định nghĩa chúng một lần và sử dụng lại ở bất cứ đâu cần thiết. Điều này giúp giảm thiểu sự lặp lại và duy trì tính nhất quán trong quy trình làm việc.

image.png

Trên hình là minh họa cho một Workflows dùng Reusable Workflows trong Github Actions, chính tôi cũng đang sử dụng nó trong dự án của mình, giải thích sơ qua một chút về workflows trên:

  • Bên trái là ba job chạy build. Sau khi 3 jobs này chạy passed, công việc phụ thuộc tên là Deploy sẽ được chạy.
  • Job Deploy này đang gọi một reusable workflow chứa ba job là Staging, Review, và Production.
  • Job Production chỉ được chạy sau khi job Staging thành công. Khi một job nhắm vào một môi trường (environment) cụ thể, workflow sẽ hiển thị thanh tiến trình cho thấy số bước trong job đó. Trong hình, job Production có 8 bước và hiện tại đang xử lý bước 6.

Vậy việc sử dụng reusable workflow để chạy các job deployment như trên giúp bạn có thể chạy các job này cho mỗi môi trường cụ thể mà không cần lặp lại mã trong các workflows nữa.

3. Lợi ích của Reusable Workflows

a. Tiết kiệm thời gian và công sức

Việc tạo lại các workflow cho từng dự án có thể rất tốn thời gian và dễ mắc lỗi. Reusable Workflows giúp bạn tiết kiệm thời gian bằng cách tái sử dụng các cấu hình đã có sẵn.

b. Duy trì tính nhất quán

Bằng cách sử dụng cùng một workflow cho nhiều dự án, bạn đảm bảo rằng các quy trình CI/CD của bạn được thực hiện nhất quán. Điều này đặc biệt quan trọng trong các tổ chức lớn hoặc các dự án mã nguồn mở với nhiều đóng góp từ các nhà phát triển khác nhau.

c. Dễ dàng bảo trì và cập nhật

Khi có sự thay đổi trong workflow, bạn chỉ cần cập nhật nó ở một nơi và tất cả các dự án sử dụng workflow đó sẽ tự động nhận được bản cập nhật. Điều này giúp giảm thiểu công việc bảo trì và đảm bảo rằng các thay đổi được áp dụng đồng nhất.

d. Tăng cường khả năng tái sử dụng

Reusable Workflows khuyến khích việc xây dựng các workflows linh hoạt và mô-đun, dễ dàng tái sử dụng trong các ngữ cảnh khác nhau mà không cần thay đổi nhiều.

4. Các thành phần của Reusable Workflows

Một Reusable Workflow bao gồm các thành phần chính sau:

4.1. on

Phần này xác định các sự kiện sẽ kích hoạt workflow. Để một workflow có thể tái sử dụng, giá trị của on phải bao gồm workflow_call:

on:
  workflow_call:

4.2. Định nghĩa Inputs và Secrets

Bạn có thể định nghĩa các inputssecrets trong một Reusable Workflow để nhận chúng từ workflow gọi. Sử dụng các từ khóa inputssecrets cho mục đích này. Dưới đây là một ví dụ workflow với các chú thích:

on:  # Specifies the event triggering the workflow
  workflow_call:  # Indicates that this is a reusable workflow
    inputs:  # Defines the inputs that can be passed from the caller workflow
      config-path:  # Name of the input
        required: true  # Specifies that this input is mandatory
        type: string  # Specifies the type of the input
    secrets:  # Defines the secrets that can be passed from the caller workflow
      envPAT:  # Name of the secret
        required: true  # Specifies that this secret is mandatory

4.3. Passing inputs và Secrets value

Để chuyển các inputs được đặt tên vào một workflow được gọi tới, hãy sử dụng từ khóa with trong job và sử dụng từ khóa secrets để chuyển các biến secrets được đặt tên. Đối với inputs, kiểu dữ liệu của giá trị đầu vào phải khớp với loại được chỉ định trong called workflow (boolean, số hoặc chuỗi).

jobs:
  call-workflow-passing-data:
    uses: octo-org/example-repo/.github/workflows/reusable-workflow.yml@main
    with:
      config-path: .github/labeler.yml
    secrets:
      envPAT: ${{ secrets.envPAT }}

Các workflows sử dụng các reusable workflows trong cùng một org hoặc enterpise có thể sử dụng từ khóa inherit để truyền các secrets một cách ngầm định mà không phải khai báo lại các secret đó nữa.

4.4. outputs

Outputs cho phép bạn truyền dữ liệu giữa các jobs hoặc workflows khác nhau. Chúng giúp bạn xây dựng các workflows phức tạp và liên kết các công việc với nhau một cách hiệu quả. Để sử dụng những kết quả đầu ra này, bạn phải chỉ định chúng làm kết quả đầu ra của một reusable workflow. Tôi có ví dụ sau:

name: Reusable workflow

on:
  workflow_call:
    # Map the workflow outputs to job outputs
    outputs: # Đây là nơi định nghĩa các outputs cho toàn bộ workflow. Trong ví dụ này, chúng ta định nghĩa hai outputs là firstword và secondword.
      firstword:
        description: "The first output string"
        value: ${{ jobs.example_job.outputs.output1 }}
      secondword:
        description: "The second output string"
        value: ${{ jobs.example_job.outputs.output2 }}

jobs:
  example_job:
    name: Generate output
    runs-on: ubuntu-latest
    # Map the job outputs to step outputs
    outputs:
      output1: ${{ steps.step1.outputs.firstword }}
      output2: ${{ steps.step2.outputs.secondword }}
    steps:
      - id: step1
        run: echo "firstword=hello" >> $GITHUB_OUTPUT
      - id: step2
        run: echo "secondword=world" >> $GITHUB_OUTPUT
name: Call a reusable workflow and use its outputs

on:
  workflow_dispatch:

jobs:
  job1: # thực hiện chạy reusable workflow trên, tạo ra hai outputs là firstword và secondword.
    uses: octo-org/example-repo/.github/workflows/called-workflow.yml@v1

  job2:
    runs-on: ubuntu-latest
    needs: job1 # Chạy sau khi job1 hoàn thành
    steps: # Sử dụng outputs từ job1 để in ra dòng chữ
      - run: echo ${{ needs.job1.outputs.firstword }} ${{ needs.job1.outputs.secondword }}

5. Tạo và sử dụng Reusable Workflows

5.1. Tạo Reusable Workflow

Để tạo một Reusable Workflow, bạn cần định nghĩa nó trong một file YAML và lưu trữ trong thư mục .github/workflows của repository. Dưới đây là một ví dụ cơ bản về Reusable Workflow:

name: CI Workflow

on:
  workflow_call:
    inputs:
      branch:
        required: true
        type: string
      run-tests:
        required: true
        type: boolean

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v2

      - name: Set up Node.js
        uses: actions/setup-node@v2
        with:
          node-version: '14'

      - name: Install dependencies
        run: npm install

      - name: Run tests
        if: ${{ inputs.run-tests }}
        run: npm test

Trong ví dụ trên, workflow này nhận vào hai inputs là branchrun-tests. Workflow sẽ kiểm tra mã nguồn và chạy các bài kiểm tra nếu biến run-tests được đặt là true.

5.2 Sử dụng Reusable Workflow

Để sử dụng Reusable Workflow đã được định nghĩa, bạn cần gọi nó từ một workflow khác. Dưới đây là ví dụ về cách sử dụng workflow trên:

name: Use Reusable Workflow

on:
  push:
    branches:
      - main

jobs:
  call-reusable-workflow:
    uses: your-repo/.github/workflows/ci-workflow.yml@main
    with:
      branch: 'main'
      run-tests: true

Trong ví dụ này, khi có một push đến nhánh main, workflow sẽ gọi và sử dụng Reusable Workflow được định nghĩa trong file ci-workflow.yml.

6. Một số lưu ý khi cấu hình Reusable Workflows

6.1. Access to reusable workflows

Một workflow có thể sử dụng một reusable workflow nếu một trong các điều kiện sau đây đúng:

  • Cả hai workflows đều nằm trong cùng một repository.
  • Workflow được gọi nằm trong một repository công khai và tổ chức của bạn cho phép sử dụng các reusable workflows công khai.
  • Workflow được gọi nằm trong một repository riêng tư và các thiết lập của repository đó cho phép truy cập.

Lưu ý: Để tăng cường bảo mật, GitHub Actions không hỗ trợ chuyển hướng cho actions hoặc reusable workflows. Điều này có nghĩa là khi chủ sở hữu, tên của repository chứa action, hoặc tên của action bị thay đổi, bất kỳ workflows nào sử dụng action với tên trước đó sẽ bị lỗi.

6.2. Limitations

  • Bạn có thể kết nối tối đa bốn cấp độ workflows. Tham khảo tại "Nesting reusable workflows."

  • Bạn có thể gọi tối đa 20 reusable workflows khác nhau từ một file workflow duy nhất. Giới hạn này bao gồm cả bất kỳ cây cấu trúc của các reusable workflows lồng nhau có thể được gọi bắt đầu từ file caller workflow cấp cao nhất của bạn. Ví dụ: top-level-caller-workflow.ymlcalled-workflow-1.ymlcalled-workflow-2.yml được tính là 2 reusable workflows.

  • Bất kỳ biến môi trường nào được đặt trong một ngữ cảnh env được định nghĩa ở cấp độ workflow trong caller workflow sẽ không được truyền đến workflow được gọi. Tham khảo tại "Variables" và "Contexts."

  • Tương tự, các biến môi trường được đặt trong ngữ cảnh env, được định nghĩa trong workflow được gọi, không thể truy cập trong ngữ cảnh env của caller workflow. Thay vào đó, bạn phải sử dụng outputs của reusable workflow. Tương tự như cách sử dụng output mà tôi vừa trình bày ở trên.

  • Để tái sử dụng biến trong nhiều workflows, hãy đặt chúng ở cấp tổ chức, repository hoặc môi trường và tham chiếu chúng bằng ngữ cảnh vars. Tham khảo tại "Variables" và "Contexts."

  • Reusable workflows được gọi trực tiếp trong một job, và không phải từ bên trong một bước của job. Vì vậy, bạn không thể sử dụng GITHUB_ENV để truyền giá trị cho các bước của job trong caller workflow.

6.3. Định nghĩa các inputs và outputs một cách rõ ràng

Việc định nghĩa rõ ràng các inputs và outputs sẽ giúp bạn dễ dàng truyền dữ liệu và điều chỉnh workflow theo nhu cầu cụ thể của từng dự án.

6.4. Sử dụng các actions có sẵn

GitHub Marketplace cung cấp rất nhiều actions mà bạn có thể sử dụng để xây dựng workflows của mình. Hãy tận dụng chúng để giảm thiểu công việc viết lại từ đầu.

6.5 Đảm bảo tính bảo mật

Khi sử dụng Reusable Workflows, hãy đảm bảo rằng các secrets và thông tin nhạy cảm được bảo vệ. Sử dụng các tính năng bảo mật của GitHub Actions để lưu trữ và quản lý secrets một cách an toàn.

6.6. Kiểm tra và debug kỹ lưỡng

Trước khi triển khai Reusable Workflows trên diện rộng, hãy đảm bảo rằng chúng được kiểm tra và debug kỹ lưỡng. Sử dụng các logs và outputs để xác định và khắc phục các vấn đề.

6.7. Tài liệu hóa

Việc tài liệu hóa các Reusable Workflows sẽ giúp các thành viên trong nhóm dễ dàng hiểu và sử dụng chúng. Bao gồm các hướng dẫn chi tiết về cách sử dụng và cấu hình inputs và outputs.

Tổng kết

Reusable Workflows trong GitHub Actions là một công cụ mạnh mẽ giúp bạn tối ưu hóa và tự động hóa quy trình CI/CD một cách hiệu quả. Chúng giúp tiết kiệm thời gian, duy trì tính nhất quán, dễ dàng bảo trì và tăng cường khả năng tái sử dụng của workflows. Bằng cách hiểu và áp dụng các Reusable Workflows, bạn có thể cải thiện quy trình phát triển phần mềm và tăng cường hiệu suất làm việc của nhóm. Hãy bắt đầu tạo và sử dụng Reusable Workflows ngay hôm nay để khám phá hết tiềm năng của chúng!

Tài liệu tham khảo:


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí