CI/CD 是一种行之有效的软件开发教条。互联网上充满了谈论 CI/CD 的文章和页面。它们始终具有相同的CI/CD映像。我打赌你知道我正在谈论的图像。
我阅读了数十篇有关该主题的文章,并体验了端到端 CI/CD 管道的实施。现实情况是,实施CI/CD 管道远比阅读文章、了解 CI/CD 整体情况和使用理论复杂得多。 CI/CD 管道开发需要跨学科且经验丰富的团队。
本文介绍如何构建 Python 应用程序的最小可行 CI 管道。您可以调整文章内容以适应其他语言和要求。该示例使用 FastAPI 和 GitHub Actions。
GitHub 示例: https ://github.com/joan-mido-qa/continuous-integration-example
让我在现有的持续集成描述中添加我的两点意见。持续集成代表定期将自动测试、批准和可交付的代码更改合并到项目存储库中。
此示例使用GitHub Actions自动对每个“拉取请求”或“推送到主”事件执行所需的检查,以确保代码符合存储库质量标准。市场提供了各种各样的 CI/CD 工具: Jenkins 、 Travis 、 CircleCI 、GitLab 等。选择最适合您的管道要求的一个。
示例工作流程检查新代码是否遵循运行预提交的格式规则。然后,它使用Pytest执行小型测试,最后在Kin D 集群上安装应用程序Helm Chart执行中型测试。
您的持续集成工作流程将取决于您的团队规模、成熟度、应用程序要求和分支策略。
分析代码更改而不执行它们。静态分析工具检查您的代码是否遵守格式规则,不使用已弃用或损坏的依赖项,并且足够可读且简单。他们还建议根据编程语言编写反模式和错误。
我们将解释如何安装、配置和运行预提交。您可以将预提交与其他分析工具(例如Sonar或Synk)结合起来。
Pre-commit是一个用Python编写的工具。要在存储库中配置它,就像创建 YAML 文件并添加要在每次提交之前运行的版本化挂钩一样简单。预提交会自动管理钩子所需的依赖项并自动修复发现的错误。它支持多种文件类型:JSON、YAML、tf、py、ts 等。
在推送代码之前,通过在本地运行代码检查来节省基础设施成本。您可以在 CI 上运行预提交来检查推送代码的格式。
安装、配置和运行预提交工具:
repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v2.3.0 hooks: - id: check-yaml - id: end-of-file-fixer - id: trailing-whitespace
$ pip install pre-commit $ pre-commit install $ pre-commit run --all-files
Python 钩子建议:
单元、集成和端到端测试的定义和范围有时是分散的。正如我对持续集成描述所做的那样,我将在 Google 测试类型的软件工程中添加我的两分钱:
小:快速测试。测试小段代码。使用测试替身或模拟环境(例如 SQLite)。不需要构建任何工件。时间:~ 60 秒。
Medium :测试多段代码之间的交互。它们可能包括构建工件、使用第三方工件(例如数据库)以及连接到本地主机网络。使用伪造的环境(例如 docker-compose、Kind、Minikube 等)或外部服务(例如 Azure Blob Storage 或 AWS S3)。时间:~ 300 秒。
大型:他们使用类似生产的环境(例如性能测试)。时间:+ 900 秒。
对持续集成管道进行或不进行中型/大型测试取决于您的要求。
该示例使用 Pytest 运行测试,并使用 FastAPI 测试客户端来模拟环境。没有秘密;您的编程语言测试工具应该为您提供测试应用程序所需的所有依赖项。
此外,您可以添加最低测试覆盖率检查并将其作为结果的一部分上传。测试覆盖率是一个棘手的指标。高测试覆盖率并不意味着拥有经过良好测试的代码,但 50% 的测试覆盖率比 0% 的测试代码要好。
Kin D 是一个 docker-in-docker 轻量级 Kubernetes 集群,用于本地开发或 CI。我们使用 Kind 来设置测试环境并对其运行测试:
Kind 将无法下载您的图像,因为它无法从注册表下载。 Kind 要求在使用之前加载图像。
MetalLB是一个裸机 Kubernetes 负载均衡器。在MetalLB网页上阅读有关为什么需要负载均衡器的更多信息。
使用 Helm Chart 安装后,我们可以创建所需的 CRD:
--- apiVersion: metallb.io/v1beta1 kind: L2Advertisement metadata: name: kind-advertisement --- apiVersion: metallb.io/v1beta1 kind: IPAddressPool metadata: name: kind-address-pool spec: addresses: - "172.26.255.0/24"
Docker 为 Kind 集群创建一个子网(例如 172.26.0.0/16)。检查 Kind 网络接口以了解分配的 IP 地址范围并将该地址用作 IPAddressPool 资源的值。有关 MetalLB 配置的更多信息位于KinD网页上。
安装 Ingress-Nginx Helm Chart。然后,安装应用程序 Helm Chart,定义 Ingress 对象。将 ingressClassName 属性设置为 nginx 并定义一个主机(例如 api.local)。最后,修改/etc/host以添加以下行:
192.168.1.10 api.local
您可以根据需要定义任意数量的主机,指向同一地址。 Nginx 将完成剩下的工作。
使用 Kind 开发一个工具来启动、更新和删除本地环境。开发人员可以使用它轻松调试应用程序、在本地重现报告的错误或在 CI 上运行测试。
此示例适用于基于 Linux 的发行版。对于 Windows/MacOS 可能无法按原样运行,可能需要进行更改。
在交付所需的工件之前,工作流会执行 linting 和测试步骤。
我们使用Commitizen来管理工件的发布。 Commtizen 自动更新工件版本并推送更改。它使用配置的标签格式创建一个新的 git 标签。您还可以配置 Commtizen 以使用最新更改更新您的变更日志。
[tool.commitizen] tag_format = "v$major.$minor.$patch" version_scheme = "semver" version_provider = "pep621" major_version_zero = true update_changelog_on_bump = true version_files = [ "charts/ci-example/Chart.yaml:version", "charts/ci-example/Chart.yaml:appVersion" ]
该工作流程使用 Commitizen 输出版本来设置 Docker Image 和 Helm Chart 标签。
您可以为每个工件(图像和图表)拥有不同的版本。但是您的图表和图像更改必须向后兼容。它将增加开发和发布过程的复杂性。为了避免这种情况,我们对两个工件使用相同的版本。
本文概述了一个简单但实用的持续集成工作流程。它可能需要更改才能适用于其他编程语言或满足您的要求,但某些步骤应该易于导出并按原样工作。
CI/CD 实践:持续部署 [第 2 部分] 即将推出......