跳至主要内容

从 GitLab CI/CD 迁移到 GitHub Actions

GitHub Actions 和 GitLab CI/CD 共享一些配置相似之处,这使得迁移到 GitHub Actions 相对简单。

简介

GitLab CI/CD 和 GitHub Actions 都允许您创建工作流,这些工作流可以自动构建、测试、发布、发行和部署代码。GitLab CI/CD 和 GitHub Actions 在工作流配置方面有一些相似之处

  • 工作流配置文件使用 YAML 编写,并存储在代码的存储库中。
  • 工作流包含一个或多个作业。
  • 作业包含一个或多个步骤或单个命令。
  • 作业可以在托管或自托管计算机上运行。

有一些区别,本指南将向您展示重要的区别,以便您可以将您的工作流迁移到 GitHub Actions。

作业

GitLab CI/CD 中的作业与 GitHub Actions 中的作业非常相似。在这两个系统中,作业都具有以下特征

  • 作业包含一系列按顺序运行的步骤或脚本。
  • 作业可以在单独的计算机或单独的容器中运行。
  • 默认情况下,作业并行运行,但可以配置为按顺序运行。

您可以在作业中运行脚本或 shell 命令。在 GitLab CI/CD 中,脚本步骤使用 `script` 键指定。在 GitHub Actions 中,所有脚本都使用 `run` 键指定。

以下是每个系统语法的示例。

GitLab CI/CD 作业语法

job1:
  variables:
    GIT_CHECKOUT: "true"
  script:
    - echo "Run your script here"

GitHub Actions 作业语法

jobs:
  job1:
    steps:
      - uses: actions/checkout@v4
      - run: echo "Run your script here"

运行器

运行器是在其上运行作业的机器。GitLab CI/CD 和 GitHub Actions 都提供了运行器的托管和自托管变体。在 GitLab CI/CD 中,使用tags在不同平台上运行作业,而在 GitHub Actions 中,则使用runs-on键完成。

以下是每个系统语法的示例。

GitLab CI/CD 运行器语法

windows_job:
  tags:
    - windows
  script:
    - echo Hello, %USERNAME%!

linux_job:
  tags:
    - linux
  script:
    - echo "Hello, $USER!"

GitHub Actions 运行器语法

windows_job:
  runs-on: windows-latest
  steps:
    - run: echo Hello, %USERNAME%!

linux_job:
  runs-on: ubuntu-latest
  steps:
    - run: echo "Hello, $USER!"

有关更多信息,请参阅“GitHub Actions 的工作流语法”。

Docker 镜像

GitLab CI/CD 和 GitHub Actions 都支持在 Docker 镜像中运行作业。在 GitLab CI/CD 中,使用image键定义 Docker 镜像,而在 GitHub Actions 中,则使用container键完成。

以下是每个系统语法的示例。

GitLab CI/CD Docker 镜像语法

my_job:
  image: node:20-bookworm-slim

GitHub Actions Docker 镜像语法

jobs:
  my_job:
    container: node:20-bookworm-slim

有关更多信息,请参阅“GitHub Actions 的工作流语法”。

条件和表达式语法

GitLab CI/CD 使用rules来确定是否为特定条件运行作业。GitHub Actions 使用if关键字来防止作业在满足条件之前运行。

以下是每个系统语法的示例。

GitLab CI/CD 条件和表达式语法

deploy_prod:
  stage: deploy
  script:
    - echo "Deploy to production server"
  rules:
    - if: '$CI_COMMIT_BRANCH == "master"'

GitHub Actions 条件和表达式语法

jobs:
  deploy_prod:
    if: contains( github.ref, 'master')
    runs-on: ubuntu-latest
    steps:
      - run: echo "Deploy to production server"

有关更多信息,请参阅“评估工作流和操作中的表达式”。

作业之间的依赖关系

GitLab CI/CD 和 GitHub Actions 都允许您为作业设置依赖关系。在这两个系统中,作业默认并行运行,但 GitHub Actions 中的作业依赖关系可以使用needs键显式指定。GitLab CI/CD 还具有stages的概念,其中一个阶段中的作业并发运行,但下一个阶段将在前一个阶段中的所有作业完成后开始。您可以使用needs键在 GitHub Actions 中重新创建此场景。

以下是每个系统语法的示例。工作流以两个名为build_abuild_b的作业并行运行开始,当这些作业完成后,另一个名为test_ab的作业将运行。最后,当test_ab完成后,deploy_ab作业将运行。

GitLab CI/CD 作业之间依赖关系语法

stages:
  - build
  - test
  - deploy

build_a:
  stage: build
  script:
    - echo "This job will run first."

build_b:
  stage: build
  script:
    - echo "This job will run first, in parallel with build_a."

test_ab:
  stage: test
  script:
    - echo "This job will run after build_a and build_b have finished."

deploy_ab:
  stage: deploy
  script:
    - echo "This job will run after test_ab is complete"

GitHub Actions 作业之间依赖关系语法

jobs:
  build_a:
    runs-on: ubuntu-latest
    steps:
      - run: echo "This job will be run first."

  build_b:
    runs-on: ubuntu-latest
    steps:
      - run: echo "This job will be run first, in parallel with build_a"

  test_ab:
    runs-on: ubuntu-latest
    needs: [build_a,build_b]
    steps:
      - run: echo "This job will run after build_a and build_b have finished"

  deploy_ab:
    runs-on: ubuntu-latest
    needs: [test_ab]
    steps:
      - run: echo "This job will run after test_ab is complete"

有关更多信息,请参阅“GitHub Actions 的工作流语法”。

调度工作流

GitLab CI/CD 和 GitHub Actions 都允许您以特定间隔运行工作流。在 GitLab CI/CD 中,管道计划使用 UI 配置,而在 GitHub Actions 中,您可以使用“on”键以计划的间隔触发工作流。

有关更多信息,请参阅“触发工作流的事件”。

变量和机密

GitLab CI/CD 和 GitHub Actions 支持在管道或工作流配置文件中设置变量,并使用 GitLab 或 GitHub UI 创建机密。

有关更多信息,请参阅“在变量中存储信息”和“在 GitHub Actions 中使用机密”。

缓存

GitLab CI/CD 和 GitHub Actions 在配置文件中提供了一种手动缓存工作流文件的方法。

以下是每个系统语法的示例。

GitLab CI/CD 缓存语法

image: node:latest

cache:
  key: $CI_COMMIT_REF_SLUG
  paths:
    - .npm/

before_script:
  - npm ci --cache .npm --prefer-offline

test_async:
  script:
    - node ./specs/start.js ./specs/async.spec.js

GitHub Actions 缓存语法

jobs:
  test_async:
    runs-on: ubuntu-latest
    steps:
    - name: Cache node modules
      uses: actions/cache@v3
      with:
        path: ~/.npm
        key: v1-npm-deps-${{ hashFiles('**/package-lock.json') }}
        restore-keys: v1-npm-deps-

工件

GitLab CI/CD 和 GitHub Actions 都可以将作业创建的文件和目录作为工件上传。在 GitHub Actions 中,工件可用于在多个作业之间持久化数据。

以下是每个系统语法的示例。

GitLab CI/CD 工件语法

script:
artifacts:
  paths:
    - math-homework.txt

GitHub Actions 工件语法

- name: Upload math result for job 1
  uses: actions/upload-artifact@v4
  with:
    name: homework
    path: math-homework.txt

有关更多信息,请参阅“存储和共享来自工作流的数据”。

数据库和服务容器

这两个系统都允许您包含用于数据库、缓存或其他依赖项的其他容器。

在 GitLab CI/CD 中,作业的容器使用image键指定,而 GitHub Actions 使用container键。在这两个系统中,其他服务容器都使用services键指定。

以下是每个系统语法的示例。

GitLab CI/CD 数据库和服务容器语法

container-job:
  variables:
    POSTGRES_PASSWORD: postgres
    # The hostname used to communicate with the
    # PostgreSQL service container
    POSTGRES_HOST: postgres
    # The default PostgreSQL port
    POSTGRES_PORT: 5432
  image: node:20-bookworm-slim
  services:
    - postgres
  script:
    # Performs a clean installation of all dependencies
    # in the `package.json` file
    - npm ci
    # Runs a script that creates a PostgreSQL client,
    # populates the client with data, and retrieves data
    - node client.js
  tags:
    - docker

GitHub Actions 数据库和服务容器语法

jobs:
  container-job:
    runs-on: ubuntu-latest
    container: node:20-bookworm-slim

    services:
      postgres:
        image: postgres
        env:
          POSTGRES_PASSWORD: postgres

    steps:
      - name: Check out repository code
        uses: actions/checkout@v4

      # Performs a clean installation of all dependencies
      # in the `package.json` file
      - name: Install dependencies
        run: npm ci

      - name: Connect to PostgreSQL
        # Runs a script that creates a PostgreSQL client,
        # populates the client with data, and retrieves data
        run: node client.js
        env:
          # The hostname used to communicate with the
          # PostgreSQL service container
          POSTGRES_HOST: postgres
          # The default PostgreSQL port
          POSTGRES_PORT: 5432

有关更多信息,请参阅“关于服务容器”。