食谱TeamCity。 报告Yandex.Taxi

我叫Eduard Matsukov,我正在制作出租车计价器-Yandex.Taxi司机的应用程序。 我从事基础设施及其相关的所有工作。 前段时间我做了一个报告-我谈到了TeamCity与我们的项目以及与开发人员之间的友谊经历。 该报告的另一部分专门介绍Kotlin与之相关的内容。


-几乎每天他们都会向我本人以及开发人员提出问题。 在哪里得到组装? 在哪里获得这样的分支? 为什么有些东西掉下来了? 我的代码中的问题出在哪里? 为什么有些东西不能正常工作? 为此,我们在项目中拥有许多自写的基础结构,插件,使用的各种技巧和技巧。 一方面,使开发人员的生活更轻松,另一方面,实现特定的业务任务。





当然,在某些时候,我们也使用CI和TeamCity。 我们感到困惑-我们教导TeamCity与Kotlin成为朋友,可以说整个CI和整个程序集都达到了一个新的水平。

但是首先,要回顾一点历史,以了解我们是如何达到这个水平的,为什么要将此水平称为单独的标准。 TeamCity在Yandex中已经存在了很多年。 我们必须住在这台共享服务器中,其中托管了整个后端,整个前端以及最近的所有移动应用程序。 大约两年前,我们大家在一起。 每个开发人员都不会按照自己的意愿来设置每个项目,而是尽可能地或尽可能地理解他想要了解系统的程度。 而且没有人知道所有事情并且知道如何做。 很少有人想打扰,单独研究模板,TeamCity毫无用处。 因此,每个人都在锯,谁是多少。

我们住在同一台服务器上,去年我们在TeamCity发生了意外。 大约一个星期就完全停机了。 没有收集组件,测试一直在抱怨。 有人为之,在当地收集。



这是由于我们的TeamCity服务器大致来说是一个膝盖的解决方案,突然变成了一项出色的服务。 Yandex上有成千上万的开发人员使用它。 当然,存在某种容错能力,但它也拒绝了。 重新启动后下一次更新TeamCity时,结果发现几个硬盘驱动器完全崩溃了,我们无法再上升。 我必须下车。

我们需要从发生的一切中得出结论。 当然,我们得出以下结论:我们分析了为什么会发生这种情况,以及如何确保不会再次发生这种情况。

首先,很重要的一点是我们必须花费很长时间才能恢复服务。 对于服务,我指的是用于非法发布发布,组装请求池的技术流程,部分是业务流程。 由于测试无法正常工作,我们损失了很多工件,包括发行版,浪费了大量时间处理池请求。 当然,我们花了很多时间从头开始恢复项目,重新配置了整个结构,整个构建系统。 然后我们意识到是时候进行一些更改并设置我们自己的服务器了。

我们去了很长一段时间。 并不是说只有一次事故导致了这一结论。 总的来说,我们认为是时候该去山上了,自己做这件事。 我们开始了服务推广。 这非常快速地完成:几天之后,您就完成了。 当您自己部署所有这些功能时,您可以深入研究内部,进行一些管理,然后就会发现有趣的功能。 其中之一-新的TeamCity允许您配置版本控制。



版本控制非常原始,但同时又非常可靠,美观和凉爽。 与您或任何其他项目有关的所有存储在TeamCity中的内容都可以安全地上传到Git,您可以快乐地生活在它上。 但是有两个问题。

第一个问题是所有人都习惯于通过界面专门与TeamCity合作,而且这种习惯很难根除。 这里有一个小小的生活技巧:您可以简单地禁止对界面进行任何更改,并迫使所有人重新学习。 我们的团队有2,000名开发人员。 这不是一个好方法吗?

实际上,缺点就到此为止。 最重要的缺点是人们必须重新学习新的东西。 因此,需要给他们基础,以便就为何根本有必要得出一个个人结论。 然后有必要使TeamCity由于版本控制而不允许应用以某种方式破坏系统的更改。 TeamCity本身仍然使用最新的稳定版本。



在TeamCity中,您可以启动每个项目以进行版本控制,并灵活地进行配置。



一点教育计划。 TeamCity中的所有项目都排列在树中。 有某种共同的根源,更进一步的是这样一个简单的结构。 每个项目都是此图的顶部。 它可以充当构建某些东西的特定配置集,也可以充当其他项目的父项。



在Git中,您既可以一次发货,也可以一次发货。 例如,如果来自后端和前端的同事不想使用版本控制,请不要指望他们,而只能保护您的个人项目。



您可以建立一个相当复杂的层次结构系统,我们的团队最终来到了该系统。 我们有一个共同的大根和一些小根。 后端,移动开发,前端,Yandex.Food-它们都生活在各自独立的存储库中。 同时,有关所有这些项目的信息都存储在根目录下的大型共享存储库中。

在最终连接此版本后,请与所有同事,谁将在何处以及如何居住,谁将获得支持来安装它-毕竟,您必须做出艰难的选择。



TeamCity仅支持两种格式的配置。 使用XML,我怀疑没有人愿意工作,因此我们选择了第二种格式。 它允许您在Kotlin脚本上进行这些配置。



eamCity创建了一个maven项目,类似于任何普通项目。 您可以执行以下两项操作之一:上传到您的项目-Android,后端,没关系-或将其保留为独立项目。 然后,您将拥有一个具有独立项目的独立存储库。



这种方法的优点是什么? 就我个人而言,我和那些在后端和前端处理我们的基础结构的人立即受到了贿赂。 甚至那些不熟悉科特林的人,第一次听说它的人,都去教他。



这两行创建了整个项目。 这是TeamCity API的方言。 该API会更改每个主要版本。 有2018年2月,2018年1月,2017年等。不久,希望将发布2019年。

第二行只是声明项目。



这是项目本身。 这绝对是真实的代码。 这就是我们的根存储库现在的样子。 没什么多余的,没什么复杂的。 此处所需的唯一手动工作是自己手动创建UUID。 TeamCity要求每个对象,每个项目都有其自己的唯一标识符。 您可以在那里写任何东西。 我只是使用标准昵称uuidgen小组。

从这里开始Kotlin DSL的冒险。 我认为这是一种完全简单的掌握语言。 通过将其上传到IDEA,Eclipse或任何其他IDE,您可以获得所有文档,突出显示,自动完成和提示。 实际上,它们中的许多在界面中都丢失了。 因此,根据我的个人经验,使用代码会更加方便,简单和直观。 我们仍然是开发人员。



这样的事情看起来像一个真实的配置现在可以同时工作,支持TeamCity自己配置。 也就是说,TeamCity在自己的环境中构建自己的配置。 如果一切正常,并且一切都出了问题,他会冷静地将其发送到内存中,然后将更改复制到PostgreSQL。 该基地已经连接到服务本身。 如果不使用Kotlin的所有功能,这将是一个罪过。



在这种情况下,与XML不同,可以使用多态性,继承来描述这些配置-允许使用Kotlin语言的任何功能。 唯一重要的一点是,在我们引入Kotlin脚本的配置版本之前,所有这些最终都可能变成我们所存在的混乱。



但是,奇怪的是,这种混乱已经变得更少了。 因为在做我想要的事情,如何实现此功能或那个功能之前还不是很明显? 根据代码,在我的实践中,更容易理解如何实现任何功能。

最有趣的冒险从这里开始:我们如何实现某些事情,以及从原理上讲如何使项目与TeamCity的交互更容易?

此处以一种或另一种形式出现的每个人都在准备发行,并参与其发行。 我们在Google Play的各个渠道上发布发行版本。





我们有beta,有实验,有稳定的。 我们使用带有机器人的特殊插件,该插件会在发布票证中发布有关发布版本的报告以及评论。 所有这些都是通过如此漂亮的窗口进行的。 一旦您尝试构建发行版,它就会出现。 这些问题是无法避免的。



在TeamCity界面中,看起来像这样。 为了立即了解需要通读每个参数的内容,位置,地点和方式,您需要进行实验。 从文档中,除了屏幕上可见的内容外,没有其他内容。



在代码中,它看起来像这样。 至少到目前为止,半年还没有人问-我该如何做任何功能? 大多数情况下,从代码上可以直观地看出来。



同时,有些事情非常简单,但是隐藏在界面的几层后面。 我们必须走,来回走。



这是一个如何在TeamCity中实现安全性的示例。 在我的实践中,对于大多数人而言,TeamCity似乎是一个非常简单的冷系统,它不支持例如与安全服务的集成。 因此,与我们在一起的所有令牌,所有密钥,所有凭证最经常被公开使用。 为什么不呢

实际上,TeamCity是安全的。 他知道如何在服务器上创建自己的特殊文件,该文件称为-凭据json,如图所示。 并且他为每个令牌,每个凭证创建了这样的密钥,我们通过接口专门生成了该密钥。 您已经可以将其放入代码中,并确保该凭据永远不会出现在TeamCity日志或TeamCity界面中。 系统可以从任何地方实际切下这些密钥。 总体而言,整个界面是一种装饰。



好的,我们已经设置了一些参数,转发了所需的参数,例如,以构建发行版。 但是,如果我们想走得更远呢? 我们想走得更远。 在组装过程中,将启动许多不同的步骤。 我们运行了几个从完全不同的存储库构建的嵌套库。 我们只是想提出新的变化。 现在所有的一切。 不要打扰-例如,不要为池请求收集辅助库,不要将其上载到Maven存储库,不要向池请求中添加其他手势。



我们只是设置了链条组件。 我个人认为,从界面上看,这样做到底是多么不便和不便。 并且已经可以自己判断了。

这就是界面中链装配的外观。



在代码中看起来像这样。 我们仅确切地指出哪个配置是从属的,以及如果任何配置不起作用或用户从外部取消了该怎么办。 在这种情况下,我根本不希望程序集开始。 因为如果我们没有收集所有依赖库,那有什么意义呢?

本着同样的精神,所有其他事情都在做。 而TeamCity中的整个项目实际上需要500行代码。



事实证明,您可以通过所有依赖项转发一些有趣的参数。 我显示链接是有原因的。 链很方便,但是很难在界面中准备。 而且TeamCity没有记录诸如通过参数转发之类的重要功能。 这是为了什么 假设在Gradle或其他地方的构建中,我们希望绑定到某个特定字段,将相同的地址转发到发行凭单。 我们只想执行一次,而不是对每个嵌套程序集都执行一次。



TeamCity有一个不太明显且完全未记录的参数-reverse.dep(反向依赖性)。 它将星号之后的所有参数都放入所有嵌套的版本中。


在输出中,我们得到了这样一个简单的结构。 您可以使其复杂化,并使嵌套深度达到您的想象力或需求。 并且确保在所有这些依赖关系中,在所有这些配置中,将转发在组装的每个步骤中期望的所有参数。 准备回答您的问题。 谢谢大家!

Source: https://habr.com/ru/post/zh-CN466615/


All Articles