持续集成的典型情况

您是否学习过 Git 命令,但想想象一下持续集成 (CI) 在现实中是如何工作的? 或者也许您想优化您的日常活动? 本课程将为您提供使用 GitHub 存储库进行持续集成的实用技能。 本课程并非旨在成为您只需点击即可完成的向导;相反,您将执行人们在工作中实际执行的相同操作,并以与他们相同的方式执行。 当您完成所涉及的步骤时,我将解释该理论。

我们做什么?

随着我们的进步,我们将逐渐创建一个典型 CI 步骤的列表,这是记住这个列表的好方法。 换句话说,我们将创建开发人员在进行持续集成时采取的操作列表,进行持续集成。 我们还将使用一组简单的测试来使我们的 CI 流程更接近真实的流程。

此 GIF 示意性地显示了您学习课程时存储库中的提交。 正如您所看到的,这里没有什么复杂的,只有最必要的。

持续集成的典型情况

您将经历以下标准 CI 场景:

  • 致力于一项功能;
  • 应用自动化测试以确保质量;
  • 优先任务的落实;
  • 合并分支时的冲突解决(合并冲突);
  • 生产环境出现错误。

你会学到什么?

您将能够回答以下问题:

  • 什么是持续集成(CI)?
  • CI 中使用哪些类型的自动化测试,以及它们触发哪些操作?
  • 什么是拉取请求以及何时需要它们?
  • 什么是测试驱动开发 (TDD)?它与 CI 有何关系?
  • 我应该合并或重新调整更改吗?
  • 在下一个版本中回滚或修复?

起初我到处翻译“pull requests”之类的东西,但结果我决定在一些地方用英文返回短语,以减少文本中的疯狂程度。 我有时会使用“程序员surzhik”,就像人们在工作中实际使用它一样美妙的动词“commit”。

什么是持续集成?

持续集成CI,或 CI,是一种技术实践,其中每个团队成员每天至少一次将他们的代码集成到公共存储库中,并且生成的代码必须至少没有错误。

对于这个词有不同意见

争论的焦点是集成的频率。 一些人认为,每天仅合并代码一次不足以真正持续集成。 一个例子是一个团队,每个人都在早上获取新代码,并在晚上将其集成一次。 虽然这是一个合理的反对意见,但人们普遍认为每天一次的定义相当实用、具体,并且适合不同规模的团队。

另一个反对意见是,C++ 不再是开发中使用的唯一语言,仅仅要求无错误汇编作为验证方式是很弱的。 某些测试集(例如,本地执行的单元测试)也必须成功完成。 目前,社区正在努力将其作为一项要求,并且在未来“构建+单元测试”可能会成为常见的做法(如果还没有的话)。

持续集成 与...不同 持续交付 (持续交付,CD),因为它不需要在每个集成周期后发布候选版本。

我们将在整个课程中使用的步骤列表

  1. 拉取最新的代码。 从创建一个分支 master。 开始工作。
  2. 在新分支上创建提交。 本地构建和测试。 经过? 转到下一步。 失败? 修复错误或测试并重试。
  3. 推送到您的远程存储库或远程分支。
  4. 创建拉取请求。 讨论更改,随着讨论的继续添加更多提交。 使测试在功能分支上通过。
  5. 合并/变基来自 master 的提交。 使测试通过合并结果。
  6. 从功能分支部署到生产。
  7. 如果一段时间内生产环境一切正常,请将更改合并到主版本中。

持续集成的典型情况

️ 准备工作

确保您拥有正确的软件

要学习本课程,您需要 Node.js的 и Git客户端.

您可以使用任何 Git 客户端,但我只会提供命令行命令。

确保您安装了支持命令行的 Git 客户端

如果您还没有支持命令行的 Git 客户端,您可以找到安装说明 这里.

准备存储库

您需要创建一个个人副本(fork) 包含课程代码的模板存储库 在 GitHub 上。 我们同意将此称为个人副本 课程库.

完毕? 如果您没有更改默认设置,您的课程存储库很可能被称为 continuous-integration-team-scenarios-students,它位于您的 GitHub 帐户中,URL 如下所示

https://github.com/<ваше имя ползователя на GitHub>/continuous-integration-team-scenarios-students

我会简单地调用这个地址 <URL репозитория>.

尖括号如 <тут> 意味着您必须用适当的值替换这样的表达式。

确保 GitHub 操作 包含在本课程存储库中。 如果未启用,请单击页面中间的大按钮来启用它们,您可以通过单击 GitHub 界面中的“操作”来访问该按钮。

如果未启用 GitHub Actions,您将无法按照我的说明完成课程。

持续集成的典型情况

您始终可以使用 GitHub 渲染 Markdown 的功能来查看我们在此处编写的列表的当前状态

https://github.com/<your GitHub user name>/continuous-integration-team-scenarios-students/blob/master/ci.md

关于答案

虽然完成本课程的最佳方法是自己完成,但您可能会遇到一些困难。

如果你觉得不明白该怎么办,无法继续,可以查看帖子 solution,它位于您的启动存储库中。
请不要合并 solution в master 在过程中。 您可以使用此分支来弄清楚要做什么,或者使用 Git 提供给我们的所有功能将您的代码与作者的代码进行比较。 如果你完全迷失了,你可以完全更换你的分支 master 在树枝上 solution 然后将您的工作目录重置为您需要的课程步骤。

仅当您确实需要时才使用它

提交您的代码

git add .
git commit -m "Backing up my work"

这些命令

  • 改名 master в master-backup;
  • 改名 solution в master;
  • 结帐到新分行 master 并重写工作目录的内容;
  • 从“master”(曾经是“解决方案”)创建一个“解决方案”分支,以防将来需要“解决方案”分支。

git branch -m master master-backup
git branch -m solution master
git checkout master -f
git branch solution

完成这些步骤后,您可以使用 git log master 找出您需要哪个提交。
您可以将工作目录重置为此提交,如下所示:

git reset --hard <the SHA you need>

如果您对结果感到满意,在某些时候您将需要将存储库版本发布到远程存储库。 执行此操作时,不要忘记显式指定远程分支。

git push --force origin master

请注意,我们使用 git push --force。 您不太可能经常这样做,但我们这里有一个非常具体的场景,其中有一个存储库用户,此外,他还了解自己在做什么。

开始工作

持续集成的典型情况

让我们开始编译 CI 步骤列表。 通常,您会通过从远程存储库检查最新版本的代码来开始此步骤,但我们还没有本地存储库,因此我们从远程存储库克隆它。

️ 任务:更新本地存储库,从中创建分支 master, 开始工作

  1. 从克隆课程存储库 <URL репозитория>.
  2. npm install 在课程存储库目录中; 我们需要它来安装 Jest,我们用它来运行测试。
  3. 创建一个分支并命名 feature。 切换到这个线程。
  4. 添加测试代码到 ci.test.js 在要求我这样做的评论之间。

    it('1. pull latest code', () => {
      expect(/.*pull.*/ig.test(fileContents)).toBe(true);
    });
    
    it('2. add commits', () => {
      expect(/.*commit.*/ig.test(fileContents)).toBe(true);
    });
    
    it('3. push to the remote branch with the same name', () => {
      expect(/.*push.*/ig.test(fileContents)).toBe(true);
    });
    
    it('4. create a pull request and continue working', () => {
      expect(/.*pulls+request.*/ig.test(fileContents)).toBe(true);
    });

  5. 将包含前 4 个步骤的文本添加到文件中 ci.md.
    1. Pull in the latest code. Create a branch from `master`. Start working.    
    2. Create commits on your new branch. Build and test locally.  
    Pass? Go to the next step. Fail? Fix errors or tests and try again.  
    3. Push to your remote repository or remote branch.  
    4. Create a pull request. Discuss the changes, add more commits  
    as discussion continues. Make tests pass on the feature branch.  

    Команды

# Клонируйте репозиторий курса
git clone <repository URL>
cd <repository name>

# Выполните npm install в каталоге репозитория курса; он установит Jest, который мы используем для запуска тестов.
npm install

# Создайте ветку и назовите ее feature. Переключитесь на эту в ветку.
git checkout -b feature

# Отредактируйте ci.test.js как описано выше.
# Отредактируйте ci.md как описано выше

在新分支上创建提交,在本地构建和测试

我们将在提交之前设置要运行的测试,然后提交代码。

自动运行测试时的典型场景

  • 本地:
    • 持续或响应适当的代码更改;
    • 保存时(对于解释型或 JIT 编译型语言);
    • 汇编期间(需要编译时);
    • 提交时;
    • 发布到共享存储库时。

  • 在构建服务器或构建环境上:
    • 当代码发布到个人分支/存储库时。
    • 该线程中的代码正在测试中。
    • 测试合并的潜在结果(通常用 master).
    • 作为持续集成阶段/持续交付管道

通常,测试套件运行得越快,您就可以更频繁地运行它。 典型的阶段分布可能如下所示。

  • 快速单元测试 - 在构建期间、在 CI 管道中
  • 缓慢的单元测试,快速的组件和集成测试 - 提交时,在 CI 管道中
  • 缓慢的组件和集成测试 - 在 CI 管道中
  • 安全测试、负载测试和其他耗时或昂贵的测试 - 在 CI/CD 管道中,但仅限于构建的某些模式/阶段/管道,例如,在准备候选版本或手动运行时。

️任务

我建议首先使用命令手动运行测试 npm test。 之后,让我们添加一个 git hook 来在提交时运行我们的测试。 有一个问题:Git 挂钩不被视为存储库的一部分,因此无法与课程材料的其余部分一起从 GitHub 克隆。 要安装钩子,您需要运行 install_hook.sh 或复制文件 repo/hooks/pre-commit 到本地目录 .git/hooks/.
当您提交时,您将看到测试正在运行,并且它们会检查列表中是否存在某些关键字。

  1. 通过运行命令手动运行测试 npm test 在您的课程存储库文件夹中。 验证测试是否已完成。
  2. 通过运行设置提交挂钩(预提交挂钩) install_hook.sh.
  3. 将您的更改提交到本地存储库。
  4. 确保在提交之前运行测试。

执行以下步骤后,您的存储库应如下所示。
持续集成的典型情况

Команды

# Установите pre-commit hook выполнив install_hook.sh.  

# Закоммитьте изменения в локальный репозиторий. Используйте "Add first CI steps" в качестве сообщения при коммите.
git add ci.md ci.test.js
git commit -m "Add first CI steps"

# Убедитесь, что тесты запускаются перед коммитом.  

将代码发布到远程存储库或远程分支

一旦完成本地工作,开发人员通常会将他们的代码公开,以便最终可以与公众集成。 对于 GitHub,这通常是通过将工作发布到存储库的个人副本(个人分支)或个人分支来实现的。

  • 通过分叉,开发人员可以克隆远程共享存储库,创建其个人远程副本,也称为分叉。 然后它会克隆这个个人存储库以在本地使用。 当工作完成并提交后,他将它们推送到他的分支中,其他人可以使用它们,并且可以将它们集成到公共存储库中。 这种方法常用于 GitHub 上的开源项目。 我的高级课程 [Team Work and CI with Git] 中也使用了它(http://devops.redpill.solutions/).
  • 另一种方法是仅使用一个远程存储库并仅计算分支 master 共享存储库“受保护”。 在这种情况下,个别开发人员将他们的代码发布到远程存储库的分支,以便其他人可以查看此代码,如果一切正常,请将其与 master 共享存储库。

在本课程中,我们将使用使用分支的工作流程。

让我们发布我们的代码。

️任务

  • 将更改发布到与您的工作分支同名的远程分支

Команды

git push --set-upstream origin feature

创建拉取请求

创建带有标题的拉取请求 步骤回顾... 安装 feature 像“头分支”和 master 就像“基础分支”。

确保您已经安装 master分叉存储库 作为“基地分支”,我不会回应更改课程材料存储库的请求。

在 GitHub 术语中,“基础分支”是您工作所基于的分支,“头分支”是包含建议更改的分支。

讨论更改,随着讨论的继续添加新的提交

拉取请求(PR)

拉取请求(PR) 是讨论和记录代码以及进行代码审查的一种方式。 拉取请求以将单个更改集成到整体代码中的一般方式命名。 通常,一个人克隆项目的远程官方存储库并在本地处理代码。 之后,他将代码放在他的个人远程存储库中,并要求官方存储库的负责人来领取()将其代码放入本地存储库,在那里他们进行审查并可能集成(合并) 他的。 这个概念还有其他名称,例如, 合并请求.

您实际上不必使用 GitHub 或类似平台的拉取请求功能。 开发团队可能会使用其他沟通方式,包括面对面沟通、语音通话或电子邮件,但仍然有很多理由使用论坛式的拉取请求。 这里是其中的一些:

  • 组织与特定代码更改相关的讨论;
  • 作为查看自动测试人员和同行对正在进行的工作的反馈的地方;
  • 代码审查的形式化;
  • 以便稍后您可以找出这段或那段代码背后的原因和考虑因素。

通常,当您需要讨论某件事或获得反馈时,您会创建拉取请求。 例如,如果您正在开发可以通过多种方式实现的功能,则可以在编写第一行代码之前创建拉取请求,以与协作者分享您的想法并讨论您的计划。 如果工作更简单,当某些事情已经完成、提交并可以讨论时,就会打开拉取请求。 在某些情况下,您可能只想出于质量控制原因打开 PR:运行自动化测试或启动代码审查。 无论您决定如何,都不要忘记在拉取请求中@提及您希望获得其批准的人员。

通常,在创建 PR 时,您需要执行以下操作。

  • 指出您建议更改的内容和位置。
  • 撰写说明,解释更改的目的。 您可能想要:
    • 添加代码中不明显的任何重要内容,或者对理解上下文有用的内容,例如相关的 #bug 和提交编号;
    • @提及您想开始合作的任何人,或者您可以稍后在评论中@提及他们;
    • 请同事帮忙做某事或检查某件事。

打开 PR 后,就会执行配置为在此类情况下运行的测试。 在我们的例子中,这将是我们在本地运行的同一组测试,但在实际项目中可能会有额外的测试和检查。

测试完成后请稍候。 您可以在 GitHub 界面中 PR 讨论的底部看到测试的状态。 测试完成后继续。

️ 添加关于 CI 步骤列表的随机性的注释

本课程中使用的列表是任意且主观的,我们应该对此添加注释。

️ 任务:为此评论创建拉取请求

  1. 切换到分支 master.
  2. 创建一个名为 bugfix.
  3. 将注释文本添加到文件末尾 ci.md.
    > **GitHub flow** is sometimes used as a nickname to refer to a flavor of trunk-based development  
    when code is deployed straight from feature branches. This list is just an interpretation  
    that I use in my [DevOps courses](http://redpill.solutions).  
    The official tutorial is [here](https://guides.github.com/introduction/flow/).
  4. 提交更改。
  5. 发布主题 bugfix 到远程存储库。
  6. 创建一个名为的拉取请求 添加备注 有头枝 bugfix 和基础分支master.

确保您已经安装 master分叉存储库 作为“基地分支”,我不会回应更改课程材料存储库的请求。

这就是您的存储库应该的样子。
持续集成的典型情况

Команды

# Переключитесь на ветку master. Создайте ветку bugfix.
git checkout master

# Создайте ветку bugfix-remark.
git checkout -b bugfix

# Добавьте текст примечания внизу ci.md.

# Закоммитьте изменения
git add ci.md
git commit -m "Add a remark about the list being opinionated"

# Опубликуйте ветку bugfix в удалённый репозиторий.
git push --set-upstream origin bugfix

# Создайте pull request при помощи интерфейса GitHub как описано выше

批准拉取请求“添加备注”

️任务

  1. 创建拉取请求。
  2. 单击“合并拉取请求”。
  3. 单击“确认合并”。
  4. 点击“删除分支”,我们不再需要它了。

这是合并后提交的图表。
持续集成的典型情况

️ 继续工作并添加测试

协作处理拉取请求通常会导致额外的工作。 这通常是代码审查或讨论的结果,但在我们的课程中,我们将通过向 CI 步骤列表添加新项目来对此进行建模。

持续集成通常涉及一些测试覆盖率。 测试覆盖率要求各不相同,通常可以在名为“贡献指南”之类的文档中找到。 我们将保持简单并为清单中的每一行添加一个测试。

运行作业时,请尝试先提交测试。 如果你安装正确 pre-commit 较早挂钩,新添加的测试将运行,将失败,并且不会提交任何内容。 请注意,这就是我们知道我们的测试实际上正在测试某些内容的方式。 有趣的是,如果我们在测试之前开始编写代码,那么通过测试可能意味着代码按预期工作,或者测试实际上没有测试任何内容。 另外,如果我们一开始就没有编写测试,我们可能会完全忘记它们,因为没有任何东西会提醒我们它。

测试驱动开发 (TDD)

TDD 建议在代码之前编写测试。 使用 TDD 的典型工作流程如下所示。

  1. 添加测试。
  2. 运行所有测试并确保新测试失败。
  3. 编写代码。
  4. 运行测试,确保所有测试都通过。
  5. 重构你的代码。
  6. 重复。

由于失败的测试结果通常显示为红色,而通过的测试结果通常显示为绿色,因此该循环也称为红绿重构。

️任务

首先,尝试提交测试并让它们失败,然后添加并提交 CI 步骤列表本身的文本。 您将看到测试正在通过(“绿色”)。
然后将新代码发布到远程存储库,并在拉取请求讨论和 PR 状态更新底部的 GitHub 界面中观看测试运行情况。

  1. 切换到分支 feature.
  2. 将这些测试添加到 ci.test.js 最后一次通话后 it (...);.

    it('5. Merge/rebase commits from master. Make tests pass on the merge result.', () => {
      expect(/.*merge.*commits.*testss+pass.*/ig.test(fileContents)).toBe(true);
    });
    
    it('6. Deploy from the feature branch to production.', () => {
      expect(/.*Deploy.*tos+production.*/ig.test(fileContents)).toBe(true);
    });
    
    it('7. If everything is good in production for some period of time, merge changes to master.', () => {
      expect(/.*merge.*tos+master.*/ig.test(fileContents)).toBe(true);
    });

  3. 尝试提交测试。 如果 pre-commit 安装钩子后,提交尝试将失败。
  4. 然后将此文本添加到 ci.md.
    5. Merge/rebase commits from master. Make tests pass on the merge result.  
    6. Deploy from the feature branch with a sneaky bug to production.
    7. If everything is good in production for some period of time, merge changes to master. 
  5. 在本地进行并提交更改。
  6. 将更改发布到分支 feature.

你现在应该有这样的东西
持续集成的典型情况

Команды


# Переключительна ветку feature
git checkout feature

# Добавить тесты в ci.test.js как описано выше

# Добавьте в индекс ci.test.js чтобы позже закоммитить
git add ci.test.js

# Попытайтесь закоммитить тесты. Если pre-commit hook установлены, коммит не произойдёт.
git commit

# Теперь добавьте текст в ci.md как описано выше

# Внесите изменения и закоммитьте их
git add ci.md
git commit -m "Add the remaining CI steps"

# Опубликуйте изменения в ветку feature
git push

合并冲突

转到更改请求 步骤回顾.

即使我们没有做错任何事情并且代码测试通过了,我们仍然无法合并分支 feature и master。 这是因为另一个线程 bugfix 被合并于 master 当我们在做这个公关的时候。
这会造成远程分支的情况 master 有一个比我们分支所基于的版本更新的版本 feature。 因此我们不能只是倒带 HEAD master 到线程的末尾 feature。 在这种情况下,我们需要合并或应用提交 feature 变基 master。 如果没有冲突,GitHub 实际上可以执行自动合并。 唉,在我们的情况下,两个分支在文件中都有竞争性的更改 ci.md。 这种情况称为合并冲突,我们需要手动解决。

合并或变基

合并

  • 创建额外的合并提交并保存工作历史记录。
    • 保留分支的原始提交及其原始时间戳和作者。
    • 保存提交的 SHA 并在更改请求讨论中链接到它们。
  • 需要一次性解决冲突。
  • 使故事变得非线性。
    • 由于存在大量分支(让人想起 IDE 电缆),该故事可能难以阅读。
    • 使自动调试变得更加困难,例如 git bisect 不太有用 - 它只会找到合并提交。

变基

  • 在基本分支之上逐一重播当前分支的提交。
    • 生成具有新 SHA 的新提交,导致 GitHub 中的提交与原始拉取请求匹配,但与相应的注释不匹配。
    • 提交可以在此过程中重新组合和修改,甚至合并为一个。
  • 可能需要解决多个冲突。
  • 允许您保持线性故事。
    • 只要不是无缘由地太长,故事可能会更容易阅读。
    • 自动调试和故障排除变得更容易:使其成为可能 git bisect,可以使自动回滚更清晰、更可预测。
  • 需要发布带有标记的已迁移提交的分支 --force 与拉取请求一起使用时。

通常,团队同意在需要合并变更时始终使用相同的策略。 这可能是“纯”合并或顶部“纯”提交,或者介于两者之间,例如交互式地在顶部进行提交(git rebase -i) 本地用于未发布到公共存储库的分支,但合并“公共”分支。

这里我们将使用合并。

️任务

  1. 确保代码位于本地分支中 master 从远程存储库更新。
  2. 切换到分支 feature.
  3. 启动与分支的合并 master。 由于竞争性更改而导致合并冲突 ci.md.
  4. 解决冲突,以便我们的 CI 步骤列表和相关注释保留在文本中。
  5. 将合并提交发布到远程分支 feature.
  6. 在 GitHub UI 中检查拉取请求的状态并等待合并解决。

Команды

# Убедитесь, что код в локальное ветке `master` обновлён из удалённого репозитория.
git checkout master
git pull

# Переключитесь на ветку feature
git checkout feature

# Инициируйте слияние с веткой master 
git merge master

# A merge conflict related to concurrent changes to ci.md will be reported
# => Auto-merging ci.md
#    CONFLICT (content): Merge conflict in ci.md
#    Automatic merge failed; fix conflicts and then commit the result.

# Разрешите конфликт так, чтобы и наш список шагов CI, и замечание о нем остались в тексте.
# отредактируйте ci.md чтоб он не содержал маркеров конфликта слияния
git add ci.md
git merge --continue
# при коммите можете оставить сообщение по умолчанию

# Опубликуйте коммит слияния в удаленную ветку feature.
git push

# Проверьте статус запроса на изменения в пользовательском интерфейсе GitHub, дождитесь пока слияние не будет разрешено.

做得好!

您已完成列表,现在您需要批准拉取请求 master.

️ 任务:批准拉取请求“步骤审核”

  1. 打开拉取请求。
  2. 单击“合并拉取请求”。
  3. 单击“确认合并”。
  4. 单击“删除分支”,因为我们不再需要它。

这是您目前的存储库
持续集成的典型情况

产品错误

据说“测试可以用来显示错误的存在,但永远不能显示错误的不存在”。 尽管我们进行了测试并且没有显示任何错误,但一个阴险的错误却悄悄进入了生产环境。

在这样的场景中,我们需要注意:

  • 生产中部署了什么;
  • 线程中的代码 master 出现错误,开发人员可以从中开始新的工作。

我应该在下一个版本中回滚或修复它吗?

回滚是将已知良好的早期版本部署到生产并恢复包含错误的提交的过程。 “向前修复”是在 master 并尽快部署新版本。 由于 API 和数据库架构会随着代码部署到生产环境而发生变化,并且具有持续交付和良好的测试覆盖率,因此回滚通常比在下一版本中修复它更加困难和风险更大。

由于回滚在我们的案例中不会带来任何风险,因此我们将走这条路,因为它允许我们

  • 尽快修复产品上的错误;
  • 编写代码 master 立即适合开始新工作。

️任务

  1. 切换到分支 master 当地。
  2. 从远程存储库更新本地存储库。
  3. 恢复 PR 合并提交 步骤回顾 в master.
  4. 将更改发布到远程存储库。

这是已恢复合并提交的存储库的历史记录
持续集成的典型情况

Команды

# Переключитесь на ветку master.
git checkout master

# Обновите локальный репозиторий из удалённого репозитория.
git pull

# Отмените коммит слияния PR Steps review в master.
# Мы отменяем коммит слияния, поэтому нам нужно выбрать ветку истории, которую мы захотим оставить
git show HEAD

# предположим, что коммит, который был последним в ветке master до слияния, был отображён предыдущей командой первым
git revert HEAD -m 1
# можете не менять сообщения коммитов

# Опубликуйте изменения в удалённый репозиторий
git push

️ 自测

确保 ci.md 恢复合并提交后不再包含文本“sneaky bug”。

修复 CI 步骤列表并将其返回给 master

我们已经完全恢复了分支的合并提交。 feature。 好消息是我们现在没有错误 master。 坏消息是,我们宝贵的持续集成步骤列表也消失了。 因此,理想情况下,我们需要将修复应用于来自 feature 并将它们返回到 master 以及修复。

我们可以通过不同的方式来解决这个问题:

  • 恢复撤消合并的提交 feature с master;
  • 从前者移动提交 feature.

在这种情况下,不同的开发团队使用不同的方法,但我们会将有用的提交移至单独的分支,并为这个新分支创建单独的拉取请求。

️任务

  1. 创建一个名为 feature-fix 并切换到它。
  2. 迁移前一个分支的所有提交 feature 到一个新线程。 解决迁移过程中发生的合并冲突。

    持续集成的典型情况

  3. 添加回归测试 ci.test.js:

    it('does not contain the sneaky bug', () => {
    expect( /.*sneakys+bug.*/gi.test(fileContents)).toBe(false);
    });

  4. 在本地运行测试以确保它们不会失败。
  5. 删除文本“有一个偷偷摸摸的错误” ci.md.
  6. 将测试更改和步骤列表更改添加到索引并提交。
  7. 将分支发布到远程存储库。

你最终应该得到类似这样的结果:
持续集成的典型情况

Команды

# Создайте ветку под названием feature-fix и переключитесь на нее.
git checkout -b feature-fix

# Перенесите все коммиты из бывшей ветки feature в новую ветку. Разрешите конфликты слияния, которые возникли при переносе.
# используйте историю чтобы узнать хэши коммитов:
# - предшествующего коммиту с первой частью списка: C0
# - добавляющего последние элементы списка: C2
git log --oneline --graph
git cherry-pick C0..C2
# разрешите конфликты слияния
# - отредактируйте ci.md и/или ci.test.js
# - добавьте файлы в индекс
# - выполните "git cherry-pick --continue", можете не менять сообщение коммита

# Добавьте регрессионный тест в ci.test.js
# Запустите тесты локально, чтобы убедиться, что они не завершаются успешно.

# Удалите текст " with a sneaky bug" в ci.md.

# Добавьте в индекс изменения тестов и в списке шагов и закоммитьте их.
git add ci.md ci.test.js
git commit -m "Fix the bug in steps list"

# Опубликуйте ветку в удалённый репозиторий.
git push --set-upstream origin feature-fix

创建拉取请求。

创建带有标题的拉取请求 修复该功能... 安装 feature-fix 像“头分支”和 master 就像“基础分支”。
测试完成后请稍候。 您可以在 PR 讨论的底部查看测试的状态。

确保您已经安装 master分叉存储库 作为“基地分支”,我不会回应更改课程材料存储库的请求。

批准拉取请求“修复功能”

感谢指正! 请批准更改 master 来自拉取请求。

️任务

  1. 单击“合并拉取请求”。
  2. 单击“确认合并”。
  3. 单击“删除分支”,因为我们不再需要它。

这就是你现在应该拥有的。
持续集成的典型情况

恭喜!

您已经完成了人们在持续集成过程中通常采取的所有步骤。

如果您发现课程有任何问题或知道如何改进,请在 包含课程材料的存储库。 本课程还有 互动版 使用 GitHub 学习实验室作为平台。

来源: habr.com

添加评论