使用合并队列处理紧急拉取请求

自敏捷和DevOps实践兴起以来,处理紧急拉取请求(PR)一直是开发者社区争论的话题。

在这种情况下,我们需要一个系统,能够将这些“紧急”请求优先于常规PR处理,并在必要时允许我们推迟某些CI检查。

一个有效的策略是实施一个独立的合并队列,使我们能在CI测试通过之前,甚至在默认队列之前,加速将紧急修复部署到生产环境。

本文将介绍如何通过Mergify和PR标签创建两个合并队列。我们将配置一个用于常规PR,另一个专门处理紧急PR。

现在,让我们挽起袖子开始吧!

本演示将以一个简单的React应用为基础,CI工具选用CircleCI

我们将创建两个合并队列:

  • default:所有常规PR都将通过此队列,需要CircleCI检查通过后才能处理。
  • urgent:此队列专门用于带有urgent标签的PR。这使得这些PR能够跳过default队列中的其他PR,无需运行CircleCI检查即可优先处理。

通过这种配置,带有urgent标签的拉取请求将在CI运行之前进入队列。

它将位于默认队列的前面。Mergify将根据需要更新拉取请求的基分支,等待CI通过,然后执行合并操作。

从开发团队的角度来看,这也是一个相当简单的流程。开发者在创建PR时只需添加一个urgent标签,以加速流程。

项目搭建

让我们开始搭建项目。我们将使用create-react-app创建一个新的React应用。

Shell

 

mkdir emergency-pr-demo
cd emergency-pr-demo
git init
npx create-react-app .

作为参考,这是我们添加CI和Mergify配置后最终的项目结构。

YAML

 

emergency-pr-demo/
├── .circleci
│   └── config.yml
├── README.md
├── package-lock.json
├── package.json
├── .gitignore
├── .mergify.yml
├── .vscode
├── public
│   ├── favicon.ico
│   ├── index.html
│   ├── logo192.png
│   ├── logo512.png
│   ├── manifest.json
│   └── robots.txt
└── src
    ├── App.css
    ├── App.js
    ├── App.test.js
    ├── index.css
    ├── index.js
    ├── logo.svg
    ├── reportWebVitals.js
    └── setupTests.js

创建CI配置

为了运行我们的测试,我们将使用CircleCI。它易于设置和开始使用。

在这里,我们将在项目根目录下新建一个.circleci目录,并创建一个config.yml文件。

我们将创建一个简单的任务build_and_test,首先帮助我们检查项目是否按预期构建,然后使用npm run test命令运行单元测试。

YAML

 

version: 2.1
orbs:
  node: circleci/[email protected]

jobs:
  build_and_test:
    executor: node/default
    steps:
      - checkout
      - node/install-packages:
          pkg-manager: npm
      - run:
          command: npm run test
          name: Run tests
      - run:
          command: npm run build
          name: Build app
      - persist_to_workspace:
          root: ~/project
          paths:
            - .

workflows:
  test_my_app:
    jobs:
      - build_and_test

.circleci/config.yml

创建Mergify配置

现在是时候创建我们的Mergify配置文件了。

Mergify是一个工具,它根据预定义的规则和条件自动化代码仓库中合并拉取请求的过程。

我们需要在配置文件中定义两个队列,如计划中的urgentdefault

两者均采用相同的merge_conditions, check-success=ci/circleci: build_and_test,这意味着代码必须先在CircleCI中成功通过build_and_test检查,才能进行合并。

pull_request_rules部分,详细说明了如何处理拉取请求。若我们的PR带有“紧急”标签,则会被放入urgent队列;否则,将进入默认队列。

.mergify.yml

YAML

 

queue_rules:
  - name: urgent
    merge_conditions:
      - "check-success=ci/circleci: build_and_test"

  - name: default
    merge_conditions:
      - "check-success=ci/circleci: build_and_test"

pull_request_rules:
  - name: move to urgent queue when label urgent
    conditions:
      - base=main
      - label=urgent
    actions:
      queue:
        name: urgent

  - name: merge using the default queue after running the CI checks
    conditions:
      - base=main
      - "check-success=ci/circleci: build_and_test"
      - label!=urgent
    actions:
      queue:
        name: default

设置仓库

不,我们将继续在GitHub上创建一个新仓库。

接下来,我们需要进行初始提交,并通过以下命令推送代码:

Shell

 

git add .
git commit -m "Initial commit"
git remote add origin <REPO_URL>
git push -u origin master

随后,我们需要配置CircleCI。为此,我们将访问CircleCI Dashboard,然后进入项目部分并设置我们的项目。

我们还需指定main分支,此时CircleCI将自动检测我们的config文件。

通过访问dashboard.mergify.comgithub.com/apps/mergify/installations/new并使用GitHub账户登录,我们可以在GitHub账户中安装Mergify。

接着,我们可以选择希望授权Mergify访问的仓库。

设置完成后,我们可以在Mergify Dashboard中看到双方的队列。

创建第一个PR(常规PR)

现在开始创建我们的第一个PR。首先创建一个新分支regular-pr

Shell

 

git checkout -b regular-pr
git add .

仅作演示,我们将在App.css文件中添加一个类。

CSS

 

.Regular-change-class {
    background-color: white;
}

之后,我们将提交更改并推送到GitHub。

Shell

 

git commit -m 'regular CSS change'
git push --set-upstream origin regular-pr

接下来,我们将发起一个不带任何标签的Pull Request。

创建第二个PR(紧急PR)

现在我们将为更改创建一个新分支urgent-pr

Shell

 

git checkout main
git branch -b urgent-pr

首先,我们将进行commit,在其中创建一个新组件Urgent.js

JavaScript

 

import React from "react";

export default function Urgent() {
  return <div>This is an Urgent Change</div>;
}

然后,我们将这个(urgent-pr)分支推送到我们的GitHub仓库。

Shell

 

git add .
git commit -m 'Create a component for Urgent change'
git push --set-upstream origin urgent-pr

接着,我们将前往仓库,从urgent-pr分支向main分支发起一个新的PR,并添加一个新的标签urgent

Mergify会自动将第二个PR放入urgent队列,然后运行CI检查并将其合并到main分支。

随后,它会自动合并第一个PR。

您可以在此GitHub仓库查看参考:github.com/hugoescafit/emergency-pr-demo

结论

这次就到这里!

在本教程中,我们探讨了如何借助Mergify设置两个不同的合并队列——默认队列和紧急队列,并利用CircleCI来配置CI检查。同时,我们还了解了如何优先处理紧急的PRs而非常规PRs。

针对紧急拉取请求的管理,存在多种解决方案,例如创建专门的热修复分支、指定专门的审查人员,甚至是手动覆盖检查。然而,合并队列是处理此类问题的最佳且易于实施的策略之一。

访问Mergify开始为您的应用程序添加合并队列吧!

Source:
https://dzone.com/articles/handling-emergency-pull-requests-using-merge-queue