{"meta":{"title":"从 GitLab CI/CD 迁移到 GitHub Actions","intro":"GitHub Actions 和 GitLab CI/CD 共享多个配置相似之处，这使得迁移到 GitHub Actions 相对简单。","product":"GitHub Actions","breadcrumbs":[{"href":"/zh/actions","title":"GitHub Actions"},{"href":"/zh/actions/tutorials","title":"教程"},{"href":"/zh/actions/tutorials/migrate-to-github-actions","title":"迁移到 GitHub Actions"},{"href":"/zh/actions/tutorials/migrate-to-github-actions/manual-migrations","title":"手动迁移"},{"href":"/zh/actions/tutorials/migrate-to-github-actions/manual-migrations/migrate-from-gitlab-cicd","title":"从 GitLab CI/CD 迁移"}],"documentType":"article"},"body":"# 从 GitLab CI/CD 迁移到 GitHub Actions\n\nGitHub Actions 和 GitLab CI/CD 共享多个配置相似之处，这使得迁移到 GitHub Actions 相对简单。\n\n## 简介\n\nGitLab CI/CD 和 GitHub Actions 两者都允许创建可自动生成、测试、发布、发布和部署代码的工作流。 GitLab CI/CD 并在 GitHub Actions 工作流配置中共享一些相似之处：\n\n* 工作流程配置文件以 YAML 编写并存储在代码仓库中。\n* 工作流程包括一项或多项作业。\n* 作业包括一个或多个步骤或单个命令。\n* 作业可以在托管或自托管计算机上运行。\n\n存在一些差异，本指南将向你展示重要差异，以便可以将工作流迁移到 GitHub Actions其中。\n\n## 作业\n\nGitLab CI/CD 中的作业与其中 GitHub Actions的工作非常相似。 在这两个系统中，作业具有以下特征：\n\n* 作业包含一系列按顺序运行的步骤或脚本。\n* 作业可在单独的计算机或单独的容器中运行。\n* 默认情况下作业并行运行，但可以配置为按顺序运行。\n\n可在作业中运行脚本或 shell 命令。 在 GitLab CI/CD 中，使用 `script` 键指定脚本步骤。 在中 GitHub Actions，所有脚本都使用 `run` 密钥指定。\n\n下面是每个系统的语法示例：\n\n### GitLab CI/CD 的作业语法\n\n```yaml\njob1:\n  variables:\n    GIT_CHECKOUT: \"true\"\n  script:\n    - echo \"Run your script here\"\n```\n\n### GitHub Actions 用于作业的语法\n\n```yaml\njobs:\n  job1:\n    steps:\n      - uses: actions/checkout@v6\n      - run: echo \"Run your script here\"\n```\n\n## 运行器\n\n运行器是运行作业的机器。 GitLab CI/CD 和 GitHub Actions 都提供运行器的托管和自托管版本。 在 GitLab CI/CD 中，`tags` 用于在不同平台上运行作业，而在 GitHub Actions 中，则通过 `runs-on` 键来实现。\n\n下面是每个系统的语法示例：\n\n### GitLab CI/CD 的运行器语法\n\n```yaml\nwindows_job:\n  tags:\n    - windows\n  script:\n    - echo Hello, %USERNAME%!\n\nlinux_job:\n  tags:\n    - linux\n  script:\n    - echo \"Hello, $USER!\"\n```\n\n### GitHub Actions 的运行器语法\n\n```yaml\nwindows_job:\n  runs-on: windows-latest\n  steps:\n    - run: echo Hello, %USERNAME%!\n\nlinux_job:\n  runs-on: ubuntu-latest\n  steps:\n    - run: echo \"Hello, $USER!\"\n```\n\n有关详细信息，请参阅“[GitHub Actions 的工作流语法](/zh/actions/reference/workflows-and-actions/workflow-syntax#jobsjob_idruns-on)”。\n\n## Docker 映像\n\nGitLab CI/CD 和 GitHub Actions 都支持在 Docker 镜像中运行作业。 在 GitLab CI/CD 中，Docker 映像是通过 `image` 键定义的，而在 GitHub Actions 中，则是通过 `container` 键定义的。\n\n下面是每个系统的语法示例：\n\n### GitLab CI/CD 的 Docker 映像语法\n\n```yaml\nmy_job:\n  image: node:20-bookworm-slim\n```\n\n### GitHub Actions Docker 映像的语法\n\n```yaml\njobs:\n  my_job:\n    container: node:20-bookworm-slim\n```\n\n有关详细信息，请参阅“[GitHub Actions 的工作流语法](/zh/actions/reference/workflows-and-actions/workflow-syntax#jobsjob_idcontainer)”。\n\n## 条件和表达式语法\n\nGitLab CI/CD 使用 `rules` 确定作业是否在特定条件下运行。\nGitHub Actions 使用 `if` 关键字来阻止作业在条件未满足时运行。\n\n下面是每个系统的语法示例：\n\n### GitLab CI/CD 的条件和表达式语法\n\n```yaml\ndeploy_prod:\n  stage: deploy\n  script:\n    - echo \"Deploy to production server\"\n  rules:\n    - if: '$CI_COMMIT_BRANCH == \"master\"'\n```\n\n### GitHub Actions 条件和表达式的语法\n\n```yaml\njobs:\n  deploy_prod:\n    if: contains( github.ref, 'master')\n    runs-on: ubuntu-latest\n    steps:\n      - run: echo \"Deploy to production server\"\n```\n\n有关详细信息，请参阅“[对工作流和操作中的表达式求值](/zh/actions/reference/workflows-and-actions/expressions)”。\n\n## 作业之间的依赖关系\n\nGitLab CI/CD 和 GitHub Actions 都允许您为作业设置依赖项。 在这两个系统中，作业默认会并行运行，但可以在 GitHub Actions 中使用 `needs` 键显式指定作业依赖关系。 GitLab CI/CD 还具有 `stages` 的概念，其中作业分阶段同时运行，但下一阶段将在前一阶段的所有作业完成时开始。 您可以在 GitHub Actions 中使用 `needs` 键重现此场景。\n\n下面是每个系统的语法示例： 工作流首先同时运行两个名为 `build_a` 和 `build_b` 的作业，当这些作业完成后，另一个名为 `test_ab` 的作业将运行。 最后，`test_ab` 完成后，`deploy_ab` 作业将运行。\n\n### GitLab CI/CD 作业之间的依赖关系语法\n\n```yaml\nstages:\n  - build\n  - test\n  - deploy\n\nbuild_a:\n  stage: build\n  script:\n    - echo \"This job will run first.\"\n\nbuild_b:\n  stage: build\n  script:\n    - echo \"This job will run first, in parallel with build_a.\"\n\ntest_ab:\n  stage: test\n  script:\n    - echo \"This job will run after build_a and build_b have finished.\"\n\ndeploy_ab:\n  stage: deploy\n  script:\n    - echo \"This job will run after test_ab is complete\"\n```\n\n### GitHub Actions 作业之间的依赖关系的语法\n\n```yaml\njobs:\n  build_a:\n    runs-on: ubuntu-latest\n    steps:\n      - run: echo \"This job will be run first.\"\n\n  build_b:\n    runs-on: ubuntu-latest\n    steps:\n      - run: echo \"This job will be run first, in parallel with build_a\"\n\n  test_ab:\n    runs-on: ubuntu-latest\n    needs: [build_a,build_b]\n    steps:\n      - run: echo \"This job will run after build_a and build_b have finished\"\n\n  deploy_ab:\n    runs-on: ubuntu-latest\n    needs: [test_ab]\n    steps:\n      - run: echo \"This job will run after test_ab is complete\"\n```\n\n有关详细信息，请参阅“[GitHub Actions 的工作流语法](/zh/actions/reference/workflows-and-actions/workflow-syntax#jobsjob_idneeds)”。\n\n## 调度工作流程\n\nGitLab CI/CD 和 GitHub Actions 都允许按特定时间间隔运行工作流。 在 GitLab CI/CD 中，管道计划使用 UI 进行配置，而 GitHub Actions 可以使用“on”键按计划间隔触发工作流。\n\n有关详细信息，请参阅“[触发工作流的事件](/zh/actions/reference/workflows-and-actions/events-that-trigger-workflows#schedule)”。\n\n## 变量和机密\n\nGitLab CI/CD 和 GitHub Actions 都支持在管道或工作流配置文件中设置变量，并通过 GitLab 或 GitHub 的 UI 创建机密信息。\n\n有关详细信息，请参阅 [在变量中存储信息](/zh/actions/how-tos/write-workflows/choose-what-workflows-do/use-variables) 和 [机密](/zh/actions/concepts/security/secrets)。\n\n## 缓存\n\nGitLab CI/CD 并在 GitHub Actions 配置文件中提供一种方法来手动缓存工作流文件。\n\n下面是每个系统的语法示例：\n\n### GitLab CI/CD 的缓存语法\n\n```yaml\nimage: node:latest\n\ncache:\n  key: $CI_COMMIT_REF_SLUG\n  paths:\n    - .npm/\n\nbefore_script:\n  - npm ci --cache .npm --prefer-offline\n\ntest_async:\n  script:\n    - node ./specs/start.js ./specs/async.spec.js\n```\n\n### GitHub Actions 缓存的语法\n\n```yaml\njobs:\n  test_async:\n    runs-on: ubuntu-latest\n    steps:\n    - name: Cache node modules\n      uses: actions/cache@v4\n      with:\n        path: ~/.npm\n        key: v1-npm-deps-${{ hashFiles('**/package-lock.json') }}\n        restore-keys: v1-npm-deps-\n```\n\n## Artifacts\n\nGitLab CI/CD 和 GitHub Actions 都可以将作业生成的文件和目录作为制品上传。 在 GitHub Actions 中，工件可用于在多个作业中保留数据。\n\n下面是每个系统的语法示例：\n\n### GitLab CI/CD 的工件语法\n\n```yaml\nscript:\nartifacts:\n  paths:\n    - math-homework.txt\n```\n\n### GitHub Actions 的工件语法\n\n```yaml\n- name: Upload math result for job 1\n  uses: actions/upload-artifact@v4\n  with:\n    name: homework\n    path: math-homework.txt\n```\n\n有关详细信息，请参阅“[使用工作流工件存储和共享数据](/zh/actions/tutorials/store-and-share-data)”。\n\n## 数据库和服务容器\n\n这两个系统都允许您包括用于数据库、缓存或其他依赖项的其他容器。\n\n在 GitLab CI/CD 中，作业的容器通过 `image` 关键字指定，而 GitHub Actions 使用 `container` 关键字。 在这两个系统中，使用 `services` 键指定附加服务容器。\n\n下面是每个系统的语法示例：\n\n### GitLab CI/CD 的数据库和服务容器语法\n\n```yaml\ncontainer-job:\n  variables:\n    POSTGRES_PASSWORD: postgres\n    # The hostname used to communicate with the\n    # PostgreSQL service container\n    POSTGRES_HOST: postgres\n    # The default PostgreSQL port\n    POSTGRES_PORT: 5432\n  image: node:20-bookworm-slim\n  services:\n    - postgres\n  script:\n    # Performs a clean installation of all dependencies\n    # in the `package.json` file\n    - npm ci\n    # Runs a script that creates a PostgreSQL client,\n    # populates the client with data, and retrieves data\n    - node client.js\n  tags:\n    - docker\n```\n\n### GitHub Actions 数据库和服务容器的语法\n\n```yaml\njobs:\n  container-job:\n    runs-on: ubuntu-latest\n    container: node:20-bookworm-slim\n\n    services:\n      postgres:\n        image: postgres\n        env:\n          POSTGRES_PASSWORD: postgres\n\n    steps:\n      - name: Check out repository code\n        uses: actions/checkout@v6\n\n      # Performs a clean installation of all dependencies\n      # in the `package.json` file\n      - name: Install dependencies\n        run: npm ci\n\n      - name: Connect to PostgreSQL\n        # Runs a script that creates a PostgreSQL client,\n        # populates the client with data, and retrieves data\n        run: node client.js\n        env:\n          # The hostname used to communicate with the\n          # PostgreSQL service container\n          POSTGRES_HOST: postgres\n          # The default PostgreSQL port\n          POSTGRES_PORT: 5432\n```\n\n有关详细信息，请参阅“[与 Docker 服务容器通信](/zh/actions/tutorials/use-containerized-services/use-docker-service-containers)”。"}