如何使用可重用的Github Actions和Heroku构建简单的部署管道

发布时间 2023-06-02 08:37:57作者: 晓风晓浪

如果您使用 GitHub 有一段时间了,您可能听说过或使用过 GitHub 操作。

如果您之前没有听说过 Github Actions 或使用过它们,您可以使用它们来自动化您的构建、测试或部署管道。您可以创建将在某些操作(例如打开拉取请求或推送到分支)时触发的工作流。

这些操作对于创建自动化部署的构建管道很有用。它们还通过对所有推送/拉取请求运行测试来帮助维护分支的完整性。

(更多教程:https://www.java567.com/?v=2306025

这是一个简单的工作流程,只要您在 Github 中推送分支或打开拉取请求,它就会运行测试:

 ---
 name: Run tests
 on: [push, pull_request]
 
 jobs:
  test:
    runs-on: ubuntu-latest
 
    steps:
      - name: Checkout
        uses: actions/checkout@v2
 
      - name: Setup and Run Tests
        run: |
          docker-compose build
          docker-compose run web rake db:setup
          docker-compose run web rspec

触发器列在“on”标签之后。此工作流在推送到远程时触发。您将在下面看到工作流有多个触发器的示例。如果您有多个触发器,您可以像数组一样在括号中列出触发器。

接下来,你有你的工作标签。在此标签下,您可以列出要运行的各种作业。您可能有几个不同的测试作业用于单元测试、集成测试,然后可能有一个构建作业来构建一个被推送到远程存储库的图像。

在工作中,您有多个步骤。第一步通常是结帐步骤。GitHub 操作将启动一个虚拟机运行器来运行您的作业,因此您需要包括为您的应用程序设置此虚拟机所需的所有步骤。

这意味着您要做的第一件事就是将代码放到虚拟机上。这发生在上面的结帐步骤中。

然后,您的工作需要向 GitHub 提供有关如何运行测试等内容的说明。上面的工作流程通过 Docker 运行所有内容。GitHub runner 在签出项目时可以看到 docker-compose 文件。然后它可以运行上面列出的三个 Docker 步骤来启动容器,然后在该容器内运行单元测试。

使用此工作流程,如果您要在 GitHub 中打开拉取请求并且分支测试失败,您将收到一条警报,告诉您您引入了如下输出的重大更改:

图片-189GitHub 操作警报示例

这些工作流程有时会变得复杂且非常复杂。在本教程中,我将解释一些清理工作流的简单方法,以避免复制粘贴 yaml 配置。

然后,我将继续解释如何创建一个简单的部署管道,强制执行一个作业在另一个作业运行之前通过。

您可能在哪里找到重复的工作

假设您有一个运行测试的作业,并且该作业需要在多个不同的工作流中运行。您想要对所有拉取请求运行测试。如果测试未通过,您还希望在合并到 main 时以阻止生产构建/部署步骤的方式运行它们。

也许您在这里的第一个想法是构建两个工作流,一个名为 test,另一个名为 deploy。测试工作流程只有一项工作:设置和运行所有单元测试。在另一个工作流中,您可以从测试工作流中的测试作业复制 yaml,并将其粘贴为部署工作流中的第一个作业。

您的测试工作流程如下所示:

 ---
 name: Run tests
 on: pull-request
 
 jobs:
  test:
    runs-on: ubuntu-latest
 
    steps:
      - name: Checkout
        uses: actions/checkout@v2
 
      - name: Setup and Run Tests
        run: |
          docker-compose build
          docker-compose run web rake db:setup
          docker-compose run web rspec

您的部署工作流程将如下所示:

 ---
 name: Deploy
 on:
  push:
    branches: [main]
 
 jobs:
  tests:
  runs-on: ubuntu-latest
 
    steps:
      - name: Checkout
        uses: actions/checkout@v2
 
      - name: Setup and Run Tests
        run: |
          docker-compose build
          docker-compose run web rake db:setup
          docker-compose run web rspec
  deploy:
    name: deploy
    runs-on: ubuntu-latest
    steps:
      - run: echo 'The triggering workflow succeeded deploying now'
      - uses: actions/checkout@v2
      - uses: akhileshns/heroku-deploy@v3.12.13 # This is the action
        with:
          usedocker: true

部署工作流允许两个作业(测试和部署)在合并到 main 时运行,但如果测试失败,它实际上不会阻止部署作业运行。

但我们可以通过两种方式使它变得更好:第一种是使用可重用的 GitHub 操作,这样我们就可以消除作业 yaml 的复制粘贴。其次,使用 GitHub 作业“需要”关键字,这样我们就可以让我们的部署作业取决于我们的测试作业是否成功。

如何创建可重用的 Github 操作

对我们来说重要的信息是对什么是可重用操作的解释。可重复使用的操作是您在一个地方创建作业然后将其称为单独的工作流的操作。

如果我希望我的测试工作流程可重复使用,我需要添加一个标记为“workflow_call”的触发器。我还希望在推送和拉取请求时触发我的工作流。所以我的触发器看起来像这样:

 ---
 name: Run CI Process for the app
 on: [workflow_call, push, pull_request, workflow_dispatch]

完整的工作流程如下所示:

 ---
 name: Run tests
 on: [workflow_call, push, pull_request, workflow_dispatch]
 
 
 jobs:
  test:
    runs-on: ubuntu-latest
 
    steps:
      - name: Checkout
        uses: actions/checkout@v2
 
      - name: Setup and Run Tests
        run: |
          docker-compose build
          docker-compose run web rake db:setup
          docker-compose run web rspec

要在部署工作流(我想在其中运行测试和部署我的应用程序)中重用测试工作流,我可以执行以下操作:

 jobs:
    test:
        uses:./.github/workflows/test.yml

这将允许测试作业在单独的工作流程中运行,而无需将与测试作业关联的 yaml 从一个工作流程复制到另一个工作流程。

依赖工作

这很酷,但我们不只是希望我们的测试工作在我们的部署工作流程中被重用。如果测试工作在部署工作流中碰巧失败,我们实际上希望它阻止部署

现在,我们可以查看此处记录的“needs”关键字。使用“需要”,我们可以要求部署作业甚至不会运行,除非测试作业成功。

在开始使用“需要”标签之前,让我简要解释一下部署作业的作用。

我已经使用 Heroku 部署了示例应用程序。我没有使用 Heroku Git 远程,而是针对主分支打开拉取请求。在合并到 main 时,我使用这个开源 Github 操作将主分支部署到 Heroku。

我的部署工作看起来像这样:

 deploy:
    name: deploy
    runs-on: ubuntu-latest
    steps:
      - run: echo 'The triggering workflow succeeded deploying now'
      - uses: actions/checkout@v2
      - uses: akhileshns/heroku-deploy@v3.12.13 # This is the action
        with:
            usedocker: true

上面的“usedocker”标签指定我想通过构建一个推送 docker 镜像到 Heroku Container Registry 来将这个应用程序部署到 Heroku。如果您查看上面引用的 Heroku 部署操作的源代码,您会看到当我将“usedocker”设置为“true”时,它将运行此命令:

 heroku container:push

如果我们希望此作业在运行部署作业之前需要成功测试运行,我们可以将测试作业添加到我们的工作流中,以引用我们创建的可重用测试作业:

 ---
 name: Deploy
 on:
  push:
    branches: [main]
 
 jobs:
  tests:
    uses: ./.github/workflows/test.yml

现在我们可以将needs标签添加到我们的部署操作中,我们的完整工作流程 yaml 将如下所示:

 ---
 name: Deploy
 on:
  push:
    branches: [main]
 
 jobs:
  tests:
    uses: ./.github/workflows/test.yml
  deploy:
    name: deploy
    needs: [ tests ]
    runs-on: ubuntu-latest
    steps:
      - run: echo 'The triggering workflow succeeded deploying now'
      - uses: actions/checkout@v2
      - uses: akhileshns/heroku-deploy@v3.12.13 # This is the action
        with:
          usedocker: true

就是这样!现在,当我们将分支合并到主分支时,GitHub 为我们提供了一个可视化的依赖作业,如下所示:

图片-159

如果我们有一个更复杂的工作流程,我们可以准确地看到它在哪个工作上失败了。

包起来

通过这些步骤,我们可以清理我们的工作流 yaml,以在可能的情况下引用现有的作业/工作流。我们还可以构建一个简单的依赖操作管道,其中一个步骤取决于前一步的成功。

这些是允许频繁部署的 CI/CD 管道的开始。反过来,这将使我们能够更快地为用户提供新功能和修复。

(更多教程:https://www.java567.com/?v=2306025