持续构建和敏捷与经常提交

发布于 2024-08-02 05:27:12 字数 1431 浏览 7 评论 0 原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

萝莉病 2024-08-09 05:27:12

还有什么比对出现问题的禁忌更不敏捷的呢?我认为禁忌是让构建被破坏,而不是根本破坏构建。偶尔的构建损坏是可以的。这正是您运行持续构建和测试的原因。 CI 构建/测试可以识别构建何时被破坏,以及理想情况下是谁破坏了它。这可以确保它得到快速修复。如果这种情况偶尔发生,那就没事了。如果这种情况一天发生二十次,团队可能就有麻烦了。

禁忌是干扰其他人完成工作。当您破坏构建时,他们会收到一封电子邮件,内容是“我们的源代码分支已损坏”。在收到完全清晰的电子邮件之前,他们将无法将其他人的更改或他们的更改与主线集成。

在这种持续集成的环境中工作的真正挑战是:
1)保持团队规模较小。一般来说,当团队中有大约 25 名开发人员后,我们就会开始遇到麻烦。事情开始变得脆弱。使用团队级分支、组件或多阶段 CI 和流可以帮助较大的团队分解为较小的团队。

2)选择小工作单元。一般来说,定期检查改进和不破坏一切之间不应该有冲突。当进行小的、有效的更改时应该进行提交。新功能可能尚未向用户公开,但如果进行了不破坏测试的连贯 API 更改,请检查。3

) 快速、准确的构建。在许多竞争条件下,当构建速度变得更快时,团队往往会更频繁地获胜。另外,可重复的构建将确保开发人员在自己的机器上执行的构建(她有时间这样做,因为速度很快)相当准确地预测提交的成功。

What could be less Agile than a taboo about something ever going wrong? I would argue that the taboo is to leave the build broken rather than to break the build at all. The occasional build breakage is ok. This is exactly why you are running continuous builds and tests. The CI build/test identifies when the build is broken, and ideally who broke it. This ensures that it's fixed quickly. If this happens occasionally, you're ok. If it happens twenty times a day, the team is probably in trouble.

The taboo is to interfere with other people getting their work done. When you break the build, they get an email saying, "our branch of source is busted". They won't be able to integrate other people's changes, or their changes with the mainline until they get the all clear email.

The real challenge in working in this sort of continuously integrating environments are:
1) Keeping the teams pretty small. Generally we start seeing trouble after about 25 developers are on the team. Things start getting fragile. Using team level branches, components or multi-stage CI with streams can help larger teams break into smaller teams.

2) Choosing small units of work. There generally shouldn't be a conflict between checking in improvements regularly and not breaking everything. Commits should be done when small, working changes are made. The new feature might not be exposed to the user yet, but if a coherent API change is made that doesn't break tests, check in.

3) Fast, accurate Builds. There are a lot of race conditions that the team tends to win more often when the build gets faster. Plus reproducible builds will ensure that the build the developer does on her own machine (which she had time to do because it was fast) reasonably accurately predicts success on commit.

染年凉城似染瑾 2024-08-09 05:27:12

在大多数源代码控制系统中,分支/标签解决了这个问题。

它们让您可以标记或只是“分支”(双关语)代码段/修订版,并将其作为“稳定版本”。然后,您可以将更改提交到主干、“补丁”分支或其他方法。

这两个概念一起发挥作用。

Branches/tags resolve this, in most source control systems.

They let you mark or just 'branch' (pun intended) a segment/revision of code and have that as the 'stable release'. You can then commit changes to the main trunk, or a 'patch' branch, or other approaches.

The two concepts work together.

眼中杀气 2024-08-09 05:27:12

实际上,一个常见的敏捷哲学(我实际上对此非常满意)是这样的:“如果你在回家之前无法提交,那么就恢复。

起初这听起来很残酷,所以我通常首先在本地复制我的源代码树或者分支它,然后我回到开始的地方。它通常进行得很快,我比前一天所做的事情有所改进,而且我很少看副本(嗯,有时我会撤回一些我已经“完成”并确信的课程并重新集成它们,

我几乎不需要超过几个小时而不检查。我尝试使用重构(它们总是非常好)。简短且无害,或者它们不是重构),并且我以不会破坏的方式添加代码,这可能涉及添加经过测试的代码(新方法或对象)并在链接其余代码之前对其进行检查。 总体而言

,您的单元测试应该始终运行测试,频率为每分钟几次,很少超过每十分钟一次。

采取小步骤可能需要更长的时间,但您将避免那些无法运行任何测试或签入的 3-4 天代码重写会话,这些可能是残酷的并且是巨大的时间浪费!

Actually a common Agile philosophy (that I've actually been pretty happy with) is along the lines of "If you can't commit before going home, revert.

At first this sounds brutal, so I usually copy off my source tree locally first or branch it, and then I revert back to where I started. The next day I start the work over. It usually goes VERY FAST, I improve over what I did the previous day and I rarely if ever look at the copy (Well, sometimes I'll pull back some classes that I had "Completed" and felt sure of and re-integrate them.

I hardly ever have the need to go more than a few hours without checking in. I try using refactors (they are ALWAYS very short and harmless or they aren't refactors) and I add code in such a way that things don't break. This might involve adding tested code (a new method or object) and checking it in before linking in the rest of the code.

Overall, your unit tests should ALWAYS run. I tend to run tests as often as a few times a minute and rarely more than once every ten minutes.

Taking the small steps may take a little longer, but you will avoid those 3-4 day code rewriting sessions where you can't run any tests or check in, those can be brutal and a HUGE waste of time!

伊面 2024-08-09 05:27:12

我将添加另一个答案,因为对我来说,似乎没有提到一些最重要的点。

我对版本控制的理解
是经常承诺更好,
因为这样你就有了历史和
能够返回到之前的更改
以细粒度的方式。

我绝对同意这一点。

我对敏捷的理解
持续构建是为了
给开发商施压
始终有工作代码。

不是给开发人员施加压力 - 我宁愿将持续集成描述为一个友好的安全网,它可以帮助您在提交问题时立即发现问题,并在修复时它们通常很容易。 (查看 Martin Fowler 的开创性文章了解更多 CI 优势。) 始终拥有工作代码很重要,这就是版本控制分支的用武之地,如 丝滑指出。但与他描述的传统场景(以及福勒所说的:“每个人每天都致力于主线”)不同,我建议相反的做法:让你的主干保持稳定,最好始终处于可发布的状态,并在临时工作分支机构。

我已经在这里插入了稳定的主干方法< /a> 和 Version Control for Multiple Agile Teams亨里克·尼伯格 (Henrik Kniberg) 着。

破坏开发分支中的构建远非禁忌,尽管您仍然应该尝试保持所有内容都编译并通过所有测试。在这种情况下,破坏主干构建会更严重,但我仍然不会称其为禁忌 - 这些事情时常发生,而不是找人来指责,而是对于团队来说,修复它更为重要(并且很高兴问题现在就被发现,而不是很久以后,也许是由客户发现的)。

I'll add yet another answer, because to me it seems some of the most important points haven't been mentioned.

My understanding with version control
is that its better to commit often,
because then you have history and the
ability to go back to previous changes
in a fine grained way.

I absolutely agree about this.

My understanding with Agile and
continuous build is that its there to
put pressure on the developers to
always have working code.

It is not there to put pressure on developers — I'd rather describe continuous integration as a friendly safety net that helps you catch problems as soon as you commit them, when fixing them is usually easy. (Check Martin Fowler's seminal article for more CI benefits.) It is important to always have working code, and that's where version control branches come in, as silky pointed out. But unlike the traditional scenario he describes (and what Fowler talks about: "Everyone Commits To the Mainline Every Day"), I'd recommend the opposite: have your main trunk stable, preferably always in releaseable shape, and do all major development in temporary working branches.

I've plugged the stable trunk approach on SO here and here; see those posts for some justification and experiences of this model. Also, I warmly recommend this article which influenced my thinking a lot: Version Control for Multiple Agile Teams by Henrik Kniberg.

Breaking the build in a dev branch is far from a taboo, although you should still try to keep everything compiling and all tests passing. Breaking the trunk build, in this scenario, is somewhat more serious, but still I wouldn't call it a taboo — these things happen from time to time, and instead of finding someone to blame, it is infinitely more important for the team to just fix it (and be happy that the problem was found now, instead of much later, perhaps by a customer).

肤浅与狂妄 2024-08-09 05:27:12

使用 Git 轻松分支、合并和变基。

Use Git for easy branching, merging, and rebasing.

裸钻 2024-08-09 05:27:12

Silky 是正确的,分支/标记解决了这个问题(用于此功能的 svn 插件)。

我经常是提交的忠实粉丝,我个人发现它可以更轻松地防止破坏构建,因为我每次都对较少量的代码进行单元测试。

Silky is spot on, branching/tagging resolves this (svn plug for this functionality).

I am a big fan of commit often, and I personally find it makes it easier to prevent breaking the build, because i am unit testing a smaller amount of code each time.

辞别 2024-08-09 05:27:12

TDD 让您两者皆有

解决这一明显悖论的一个解决方案是测试驱动设计 (TDD)。如果练习得好,很容易提交代码,通常具有连续构建,很少被非工作代码破坏。

首先从存储库获取最新代码并运行所有测试。 (如果没有全部通过,则淘汰最后一个提交的人。)为一小部分功能编写测试(实现该功能之前),然后实现该功能,然后运行再次进行所有测试。从版本控制系统更新您的代码,以防您在工作时发生任何更改,再次运行所有测试,如果它们全部通过,您就可以立即提交。这就是敏捷概念“红-绿-重构”中的“红-绿”。之后,进行任何需要的重构并再次运行所有测试。如果你还是新手,你可以在那时再次提交。

大多数敏捷团队都有持续集成服务器它定期运行(通常每小时或更长时间),并有一个大的可见指示器(如交通灯),显示最近的构建是否已通过、失败或正在进行。

如果必须的话,拥有本地版本控制数据库如果

您绝对无法摆脱“大型代码更改”,那么请使用您自己的本地版本控制存储库,使用类似 git 正如 Gordon Potter 建议的那样,并在完成更改后提交。即使您的团队使用其他版本控制产品,您也可以执行此操作。

TDD Lets You Have Both

One resolution to this apparent paradox is the agile software development practice of Test Driven Design (TDD). Practiced well, it is easy to commit code often and have continuous builds that are rarely broken by non-working code.

First get the latest code from the repository and run all the tests. (If they don't all pass, bust the last person to commit.) Write a test for a small piece of functionality (before you've implemented the functionality), then implement the functionality, and run all the tests again. Update your code from the version control system in case anything has changed while you were working, run all the tests again, and if they all pass, you could commit right then. That much is "Red-Green" of the agile concept Red-Green-Refactor. After that, do any needed refactoring and run all the tests again. If you're still green, you could commit again at that point.

Most agile teams have a Continuous Integration server that runs on a regular schedule (often hourly or more) and has a large visible indicator (like a traffic light) that shows whether the most recent build has passed, failed or is in process.

Have a Local Version Control Database if You Have To

If you absolutely can't get away from having "largish code changes", then use your own local version control repository, using something like git as Gordon Potter suggests, and commit when you're done with your change. You can do this even if your team uses some other version control product.

素染倾城色 2024-08-09 05:27:12

对于可能破坏相关代码片段的重大或大型更改,分支将是合适的。当您想要集成此更改并检查到主干或您要将其升级到的任何集成分支时,解决损坏问题并使测试全部正常工作至关重要。
我认为这两件事不应该互相对抗。使用分支或分布式源代码控制将使管理变得更容易。

For a significant or large change that is likely to break dependent pieces of code a branch would be appropriate. At the point where you want to integrate this change and check into the trunk or whatever integration branch you are going to promote it to, having addressed the breakages and having the tests all working is essential.
I don't think the two things should be working against each other. Use of branches or distributed source control would make this easier to manage.

夜吻♂芭芘 2024-08-09 05:27:12

您必须检查合并期间什么样的历史记录才有意义。假设您有一个使用大量可加载模块的程序,可以是内核.. Web 服务器,等等。

在编写一个模块时,您会进行 200 次提交,当您与主项目合并时,您可能只需要一个(尽管很大)补丁,也许是两个:

  • 引入 foo 模块
  • 更新 Makefiles 来构建 foo

这就是 Git 变得如此的原因之一在 DVCS 领域占据主导地位。

您选择的提交频率实际上与您想要采用的软件开发方法无关。您可以提交 200 个经过良好测试的修订版,或者一个,只要拉动您推送的内容的人不会在他们的代码中引入由您自己造成的有毒修订版或回归(当然,除非您的代码暴露了他们的问题)。

出于与您给出的相同原因,我(个人)喜欢做出许多小承诺。事实上,如果每个人都在一个中央分支上工作,这通常是理想的。但是,如果您在某个子系统上工作了 6 个月,我真的更希望您向我发送一些大补丁,而不是继承您的整个历史记录..您始终在自己的工作存储库中拥有您的历史记录,并且它可能只对你 :)

You'll have to examine what kind of history makes sense during a merge. Lets say you have a program that uses lots of loadable modules, could be a kernel .. a web server, whatever.

In writing one module, you make 200 commits, when you merge with the main project, you probably want only one (albeit big) patch, perhaps two:

  • Introduce foo module
  • Update Makefiles to build foo

This is one of the reasons why Git has become such a dominate presence in the world of DVCS.

Your choice of commit frequency really has no bearing on what method of software development you want to employ. You can commit 200 well tested revisions, or one, as long as people pulling what you push don't ingest toxic revisions or regressions in their code caused by your own (unless, of course your code exposes a problem in theirs).

I (personally) like to make many small commits, for the same reasons that you gave. In fact, its usually ideal if everyone is working on one central branch. However, if your working on some sub system for 6 months, I really would prefer you send me a few large patches, rather than inherit your whole history .. you always have your history in your own working repo, and its probably only interesting for you :)

完美的未来在梦里 2024-08-09 05:27:12

如果较大的代码更改位于单独的分支中,则不一定会破坏构建。通过在其自身上建立一个分支,更改将被保留在代码之外,直到更改完成,然后整个事情可以合并回主干或主代码行。关键是,虽然持续构建正在发生,但它不一定会包含 “完成-完成。”

If the largish code change is in a separate branch this doesn't break the build necessarily. By having a branch onto itself, the changes are kept out of the code until the change is done and then the whole thing can be merged back into a trunk or main code line. The key is that while there is a continuous build happening, it isn't necessarily going to include things that aren't "done-done."

忆离笙 2024-08-09 05:27:12

在我看来,Git 解决了这个问题。保留本地存储库并尽早提交,经常提交,然后当代码达到未损坏的里程碑时推送到主共享存储库。如果整个团队都使用 Git,那么当他们拉取更改时,所有整个存储库历史记录都可以保留在其他人的存储库中。而且这一切都不一定会破坏构建。

通过变基,当您推出里程碑时,您甚至不必公开整个本地提交历史记录。

It seems to me that Git solves this problem. Keep a local repository and commit early, commit often and then when the code reaches a non broken milestone push out to the main shared repository. If the whole team uses Git then the all entire repository history can be maintained in everybody else's repository when then they pull changes. And all without necessarily breaking the build.

And with rebasing you don't even have to expose your entire local commit history when you push out milestones.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文