软件工程

如何通过自定义GitHub Actions使我们能够简化数千个CI/CD流水线

本文主要是介绍如何通过自定义GitHub Actions使我们能够简化数千个CI/CD流水线,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
介绍

自从Permit.io早期开始,我们就认识到构建一个安全可靠的授权服务取决于它如何与软件开发生命周期集成。为此,除了为用户提供全面的授权即服务产品外,我们还大力投资于解决在保持跨各种环境一致的权限管理的同时自动化CI/CD流水线的挑战。

我们采用这种全面的授权方法的主要目标是确保这些流程不仅无缝衔接,而且对任何开发团队来说都易于访问和高效。

通过将GitHub Actions与我们的API集成,我们创建了一个支持大规模开发组织的模型。这篇博客将带您了解我们如何利用这些工具自动化工作空间中的环境管理,使其能够被CI/CD管道访问。

了解您的架构以进行 CI/CD

创建 GitHub Actions 的第一步(也许也是最重要的一步)是检查你的系统架构并理解你希望在 CI/CD 中优化的结构。

当构建Permit.io时,我们建立了一个系统,允许开发人员将他们的授权外部化到我们的混合云服务中。虽然产品的核心是让应用程序代码决定用户可以或不可以做什么,但它也被设计来支持软件开发组织的常见层级结构。

这在Permit的工作空间层级中显而易见:

  • Workspace - 相当于整个开发组织。你可以将其视为一个 GitHub 组织。
  • Project - 你组织管理的单个应用程序。它可以被视为一个代码仓库,但同时也足够灵活以支持多仓库或单仓库架构。一个 Workspace 可以包含多个 Project。
  • Environment - 每个项目内部的策略和配置隔离区。环境允许每个组织以相同的方式管理他们的 CI/CD 过程,就像他们在 SDLC 中管理一样。它类似于一个 Git 分支。每个 Project 默认包含 ProductionDevelopment 分支,但用户可以创建任意数量的分支。

api-model-f212cef178cf6984bd6009c26d0b62e8.svg

CI/CD 结构的优势

理解CI/CD流程的结构是优化流程的关键。环境-项目模型旨在提供灵活性和控制,贯穿开发的多个阶段。其核心功能在于允许我们的用户:

  1. 创建隔离的环境: 每个环境都是独立的,但可以复制生产环境设置,非常适合测试和开发。
  2. 无缝管理权限: 权限管理在各个环境中保持一致,确保您的CI/CD流程既安全又可靠。
  3. 自动化工作流: Permit与CI/CD工具(如GitHub Actions)无缝集成,可以实现环境创建、测试、合并和清理的自动化。

如前所述,此模型在需要动态创建、测试和合并环境的场景中特别有用,使其非常适合基于 PR(拉取请求)的工作流。

有了这个模型在心中,让我们来识别自动化和流程优化的挑战。

工作流摩擦:识别挑战

为了全面支持授权服务与现有用户环境和架构的无缝集成,我们需要识别权限系统与软件开发系统之间的事件和连接点。

在最基本层面上,对于每个拉取请求(PR),需要在Permit中创建一个新的环境。这允许从生产环境和预发布环境中隔离配置,运行测试以确保分支和环境的安全性,并将更改合并到生产环境中,所有这些操作都只需要最少的人工干预。

这个过程包括以下步骤:

  1. 环境创建: 我们希望让用户自动化创建每个PR的新Permit环境的过程。我们也明白,并不是每个PR都需要更改授权配置,所以我们希望确保只为相关的PR打开新的环境。
  2. 环境测试: 对于每个PR,我们希望在相关的环境中运行集成和产品测试,以确保权限和设置的准确性。
  3. 合并和清理: PR被批准后,我们希望将Permit环境与生产环境合并。这将使我们能够确保顺畅的部署和交付。

手动管理这些任务可能会出错且耗时,这迫使我们寻找一种可靠的方法来自动化它们。考虑到 CI/CD,我们希望简化前两个步骤的持续集成以及最后步骤的持续部署和交付。

现在我们了解了需求,让我们创建我们的GitHub Actions:

创建自定义 GitHub Actions

如上所述,我们的GitHub Actions包含了三个工作流,这些工作流可以完全自动化环境管理过程:

  1. new-env.yaml : 当创建或更新 PR 时,创建一个新的环境。

  2. run-pdp.yaml : 在新创建的环境中运行测试。

  3. merging.yaml : 将环境更改合并到生产环境,然后删除特定于 PR 的环境。

这些工作流利用Permit的API动态管理环境,提供了一个流畅且无误的过程。您可以在以下代码仓库中查看此工作流的实际操作:https://github.com/permitio/pink-mobile-demo-app/tree/main/.github/workflows

让我们来看一下代码并理解其步骤 -

工作流分解

1. 创建新环境 (new-env.yaml)

当有新的 PR 打开或更新时,我们会触发一个工作流,负责在 Permit 中创建一个新的环境。我们将使用 Permit 的复制环境 API 来复制生产设置,确保所有环境的一致性。

触发工作流:

运行我们工作流的第一步是通过代码中的事件触发它。我们可以通过以下命令来实现这一点:

    name: demo-new-env
    on:
      pull_request:
        types: [opened, reopened]

进入全屏模式 退出全屏模式

这将确保我们的工作流被触发。在下一步中,我们将用一些变量来设置它。

设置环境:

定义项目ID为环境变量。这将在后续的API调用中使用。

该项目是环境将要创建所在的项目。在生产环境中,你可以从GitHub变量中获取它。

    env:
      PROJECT_ID: 1238e459351a8470

进入全屏模式 退出全屏模式

检查创建的相关性

为了确保我们不会为不涉及权限更改的PR在Permit中打开冗余环境,您需要使用 Permissions 标签标记PR。这将作为创建环境的条件:

    jobs:
      demo-new-env:
        if: contains( github.event.pull_request.labels.*.name, '权限')

进入全屏模式 退出全屏模式

提取分支名称:

接下来,提取分支名称。我们需要它来命名我们的新环境:

    - name: 提取分支名称
      run: echo "branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> $GITHUB_OUTPUT
      id: extract_branch

进入全屏模式 退出全屏模式

创建新环境:

在Permit中创建一个新的环境。这是通过提交环境详情来完成的,包括从分支名称派生出的唯一密钥:

    - name: 创建新环境
      run: |
        response=$(curl -X POST \\
          <https://api.permit.io/v2/projects/$>{{ env.PROJECT_ID }}/envs \\
          -H 'Authorization: Bearer ${{ secrets.PROJECT_API_KEY }}' \\
          -H 'Content-Type: application/json' \\
          -d '{
            "key": "pr-${ steps.extract_branch.outputs.branch }",
            "name": "pr-${{ steps.extract_branch.outputs.branch }}"
          }')

        echo "ENV_ID=$(echo "$response" | jq -r '.id')" >> $GITHUB_ENV
        echo "新环境ID: $(echo "$response" | jq -r '.id')"

进入全屏模式 退出全屏模式

获取环境API密钥:

工作流将获取新创建的环境的API密钥,该密钥将在后续的工作流中使用:

    - name: 获取新环境的API密钥
      run: |
        response=$(curl -X GET \\
          <https://api.permit.io/v2/api-key/$>{{ env.PROJECT_ID }}/${{ env.ENV_ID }} \\
          -H 'Authorization: Bearer ${{ secrets.PROJECT_API_KEY }}')

        ENV_API_KEY=$(echo "$response" | jq -r '.secret')
        echo "ENV_API_KEY=$ENV_API_KEY" >> $GITHUB_ENV
        echo "新环境的API密钥: $ENV_API_KEY"

进入全屏模式 退出全屏模式

2. 在新环境中运行测试 (run-pdp.yaml)

对于我们在持续集成中的下一步,我们希望让流水线在新创建的环境中测试代码。Permit架构的一个关键方面是使用与应用程序一起运行的本地策略决策点(PDP)。

在此工作流中,我们希望在 GitHub Actions 中运行 PDP,这样测试就可以调用它了。我们还将利用这一步在 Permit 系统中设置一些模拟数据:

触发工作流:

此工作流会在 PR 同步时运行,确保任何更新都经过测试:

    name: demo-run-pdp-and-tests

    on:
      pull_request:
        types: [同步]

进入全屏模式 退出全屏模式

获取环境ID和API密钥:

接下来,我们将获取在上一个工作流中创建的现有环境ID:

    - name: 获取环境ID和API密钥
      run: |
        response=$(curl -s -X GET <https://api.permit.io/v2/projects/$>{{ env.PROJECT_ID }}/envs \\
          -H 'Authorization: Bearer ${{ secrets.PROJECT_API_KEY }}' \\
          -H 'Content-Type: application/json')
        EXISTING_ID=$(echo "$response" | jq -r '.[] | select(.key == "pr-${ steps.extract_branch.outputs.branch }") | .id')
        echo "EXISTING_ID=$EXISTING_ID" >> $GITHUB_ENV

进入全屏模式 退出全屏模式

运行本地PDP实例:

然后,需要使用 Docker 启动 PDP 的本地实例,以便对新创建的环境进行测试:

    - 名称: 运行本地PDP
      操作: docker run -d -p 7766:7000 --env PDP_API_KEY=${ env.ENV_API_KEY } --env PDP_DEBUG=true permitio/pdp-v2:latest

进入全屏模式 退出全屏模式

执行测试:

最后,我们可以使用环境的API密钥对本地PDP实例执行测试:

    - name: 运行测试
      run: PERMIT_TOKEN=${ env.ENV_API_KEY } PDP_URL=localhost:7766 npm run test

进入全屏模式 退出全屏模式

3. 合并更改和清理 (merging.yaml)

我们自定义的GitHub Actions的最后一步是确保部署和交付过程高效且顺畅。在这里我们将触发合并工作流,以确保我们安全地将创建的环境集成到Permit的生产环境中。

触发工作流:

当 PR 关闭时触发此工作流,表示是时候合并并清理了:

    name: demo-合并
    on:
      pull_request:
        types: [关闭]

进入全屏模式 退出全屏模式

获取生产环境和PR环境的ID:

接下来,获取生产环境和特定于PR的环境的ID:

    - name: 获取生产环境和PR环境的ID
      run: |
        response=$(curl -s -X GET <https://api.permit.io/v2/projects/$>{{ env.PROJECT_ID }}/envs \\
          -H 'Authorization: Bearer ${{ secrets.PROJECT_API_KEY }}' \\
          -H 'Content-Type: application/json')
        PROD_ID=$(echo "$response" | jq -r '.[] | select(.key == "production") | .id')
        echo "PROD_ID=$PROD_ID" >> $GITHUB_ENV

进入全屏模式 退出全屏模式

合并和删除PR环境:

最后,将特定于 PR 的环境合并到生产环境中,然后删除 PR 环境,确保没有残留的环境存在:

    - name: 合并并删除PR环境
      run: |
        curl -X POST <https://api.permit.io/v2/projects/$>{{ env.PROJECT_ID }}/envs/${{ env.EXISTING_ID }}/copy \\
          -H 'Authorization: Bearer ${{ secrets.PROJECT_API_KEY }}' \\
          -H 'Content-Type: application/json' \\
          -d '{
            "target_env": {
                "existing": "${{ env.PROD_ID }"
            }
        }'

        curl -X DELETE \\
          <https://api.permit.io/v2/projects/$>{{ env.PROJECT_ID }}/envs/${{ env.EXISTING_ID }} \\
          -H 'Authorization: Bearer ${{ secrets.PROJECT_API_KEY }}'

进入全屏模式 退出全屏模式

我们的自定义 GitHub Actions

看看我们刚刚创建的这三个步骤,我们可以很容易地看到这个操作是如何将我们授权服务的整个流程整合到用户的架构中的。这是我们使用自定义的GitHub Actions来实现的:

  1. 环境创建:通过 new-env.yaml 工作流自动化了为每个拉取请求(PR)创建新环境的过程。当相关PR被打开或更新时,此操作会触发在Permit中创建一个新的环境。通过使用Permit的API,我们在新环境中复制生产设置,确保不同阶段的一致性。我们还添加了一个条件,以避免为与权限更改无关的PR创建不必要的环境,使用标签系统来过滤相关PR。

  2. 环境测试run-pdp.yaml 工作流解决了对新创建的环境进行测试的需求。一旦新环境设置完成,工作流会通过 Docker 启动一个本地策略决策点(PDP)实例。这使得集成和产品测试可以针对环境运行,确保权限设置准确无误后再将更改合并到生产环境。这种自动化测试可以防止错误,并确保只有经过充分测试的更改才能推进。

  3. 合并与清理:在 PR 获得批准并关闭后,merging.yaml 工作流将 PR 特定的环境合并到生产环境中,简化部署流程。合并完成后,工作流会删除 PR 特定的环境,确保没有不必要的环境残留,从而减少混乱并保持干净的开发环境。

通过自动化这些步骤——环境创建、测试、合并和清理——我们大大减少了人工干预,减少了错误,并加快了整个CI/CD流程。

结论

通过将 GitHub Actions 与 Permit.io API 集成,我们成功地简化了 CI/CD 流程,并使环境模型对开发团队更加可访问和高效。这种方法不仅减少了人工工作量,还降低了错误的风险,提供了更顺畅和可靠的部署过程。

对于任何希望优化其CI/CD管道的团队来说,Permit.io 的灵活环境模型结合 GitHub Actions 提供了一种强大的解决方案,可以自动并安全地管理您的开发工作流程。

您可以在我们的文档中了解更多关于如何处理项目与环境的信息,或者亲自尝试Permit.io!

如果你有任何问题,加入我们的 Slack 社区,那里有数千名开发者正在构建和实现授权功能。

这篇关于如何通过自定义GitHub Actions使我们能够简化数千个CI/CD流水线的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!