Woodpecker CI 设计分析|一个 Go 编写的开源持续集成引擎
一、前言
大家好,这里是白泽。随着 Go 语言在云原生领域大放异彩,开发者逐渐将目光转移到了这门语言上,而容器则是云原生时代最核心的载体。
《Woodpecker CI 设计分析》系列文章将分析开源 CI 引擎 Woodpecker 的架构设计,探究 Go 协程是如何支持由 Workflow
定义的大量 Task
的频繁创建和调度。
而 Task
的一切活动都将在容器内进行。因此这个系列的文章也是帮助你开拓 Go 云原生领域编程的一柄利剑。
这是《Woodpecker CI 设计分析》系列的第一篇文章,主要讲解 Woodpecker 的整体架构设计和体验部署使用,后续文章将讲解核心组件源码设计,并从0开始仿写 Woodpecker 核心组件,欢迎追更~
公众号 「白泽talk」,白泽目前正在打造一个氛围良好的行业交流群,文章的更新也会提前预告,欢迎加入:622383022。
我也开源了一个 Go 学习仓库:包含 Go 各阶段学习文章、读书笔记、电子书、简历模板等,欢迎 star。
二、CI 配置前瞻
为了帮助理解,本文在讲述知识点时会对比 Woodpecker 和 GitHub Actions 两种持续集成方案,下文 Pipeline 和 Workflow 两个概念在不同的语境下有时可以当作相同语意,注意不要教条。
关于 CD 这里不展开论述,因为 CD 与 CI 的不同点是业务关注点不同,关注的是 Pipeline 的不同的阶段,对于一个 CI Engine 来说,其实都是可以完成的,换句话说:CI 的阶段能构建镜像,自然也能发布镜像。
接下来对 GitHub 自带的持续集成(GitHub Actions)和 Woodpecker CI 展开介绍与对比,让你对 CI 有一个大致概念。
2.1 GitHub Actions Workflow for CI
GitHub 本身也是支持持续集成(CI)的,可以通过在项目 .github/workflows/
路径下创建配置文件定制 Pipeline。
此 GitHub Actions Workflow 在每次推送到 main
分支时触发。它设置一个 Go 环境,构建应用程序,运行测试,最后部署。
# .github/workflows/main.yml
name: CI
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v2
- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.17
id: go
- name: Build
run: |
# 在这里执行构建命令
go build
- name: Unit Tests
run: |
# 在这里执行单元测试命令
go test ./...
- name: Deploy
run: |
# 在这里执行部署命令
echo "Deployment steps go here"
2.2 Woodpecker Pipeline for CI
Woodpecker 也是类似的,有一个 Woodpecker 管道配置文件,实现了与 GitHub Actions 相同的 CI 流程。
# .woodpecker.yml
pipelines:
main:
trigger:
branches:
- main
steps:
- name: Checkout Code
image: docker://alpine
commands:
- git clone $CI_REPOSITORY_URL $CI_WORKSPACE
- name: Set up Go
image: docker://golang:1.17
commands:
- cd $CI_WORKSPACE
- go build
- name: Unit Tests
image: docker://golang:1.17
commands:
- cd $CI_WORKSPACE
- go test ./...
- name: Deploy
image: docker://alpine
commands:
- echo "Deployment steps go here"
2.3 对比
GitHub Actions 提供有限的免费套餐,但对于较大或需要更多资源的项目,需要购买付费套餐。
Woodpecker 作为开源项目,通常可以在自己的服务器上自行部署和扩展,用户可以按照 Woodpecker 的文档或项目说明进行设置。
三、术语
看完第二节后,引入了不少 CI/CD 流程中的术语,这里以 Woodpecker 和 GitHub Actions 为例进行对比讲解。
CI: 持续集成是一种软件开发实践,旨在通过将代码集成到共享存储库中,然后自动构建和测试代码,来频繁地检测和解决集成问题。
CD: 是一种软件开发实践,旨在确保软件随时都能够通过自动化流程进行交付,但并不一定立即部署到生产环境。持续交付的目标是使软件交付的过程更加可靠和可重复,以便在需要时能够迅速进行部署。
Pipeline:
- Woodpecker: 一个 Pipeline 是一系列有序的操作步骤,这些步骤按照定义的顺序执行。Pipeline 可以包含一个或多个 Workflow。
- GitHub Actions: 一个 GitHub Actions Workflow 也可以看作是一个 Pipeline。在 GitHub Actions 中,Workflow 是 CI/CD 的基本单元。
Workflow:
- Woodpecker: Workflow 是一组相关的步骤,通常代表了一个完整的 CI/CD 流程。在 Workflow 中,可以定义触发条件、环境变量和步骤顺序。
- GitHub Actions: GitHub Actions Workflow 是 CI/CD 流程的定义,由一系列 jobs 和 steps 组成。Workflow 可以根据事件触发,例如 push、pull request 等。
Step:
- Woodpecker: Step 是 Workflow 或 Pipeline 中的一个单一操作单元。每个 Step 代表了一个执行的任务,例如构建、测试或部署。
- GitHub Actions: GitHub Actions 也使用 Step 的概念,每个 Step 包含一个或多个指令,用于执行特定的操作,例如运行脚本、调用 API 或使用预定义的 action。
语法和配置:
- Woodpecker: Woodpecker 使用 YAML 格式的配置文件定义 Pipeline 和 Workflow。配置文件包含了触发条件、步骤的定义以及其他设置。
- GitHub Actions: GitHub Actions 同样使用 YAML 格式的配置文件,其中定义了 Workflow、Job 和 Step 的结构。GitHub Actions 还支持通过 UI 可视化配置。
触发条件:
- Woodpecker: 您可以定义 Workflow 的触发条件,例如当代码推送到特定分支时触发 Workflow。
- GitHub Actions: 支持多种触发条件,例如 push、pull request、定时触发等。
四、Woodpecker 架构
在 Woodpecker 中,"Server"、"Forge" 和 "Agent" 是三个关键组件,它们各自承担不同的角色和功能:
Server:
含义: Woodpecker Server 是整个 CI/CD 系统的核心组件,负责协调和管理整个构建和部署流程。
功能:
- 处理用户请求和操作,提供 Web 界面和 API。
- 管理构建和部署的任务队列。
- 与 Forge 和 Agent 进行通信,协调任务的执行。
Forge:
含义: Forge 是与外部代码仓库集成的组件(GitHub、Gitea 等),负责从代码仓库拉取源代码、触发构建,并将构建结果反馈给 Woodpecker Server。
功能:
- 与代码仓库进行集成,监听代码变更并触发构建。
- 将构建任务推送到 Woodpecker Server 的任务队列。
- 向 Woodpecker Server 报告构建结果。
Agent:
含义: Agent 是运行在构建和部署节点上的代理程序,负责执行具体的构建和部署任务。
功能:
- 从 Woodpecker Server 获取任务并执行。
- 将任务执行的结果报告给 Woodpecker Server。
- 与构建环境进行交互,执行构建脚本、部署应用等操作。
这三个组件协同工作,构成了 Woodpecker CI/CD 系统的基础架构。用户通过 Woodpecker Server 进行配置和管理,Forge 负责与代码仓库集成,Agent 负责执行实际的构建和部署任务。这种分工让 Woodpecker 可以支持多种代码仓库和构建环境,实现灵活的 CI/CD 流程。
思考几个问题:
- Agent 是如何从 Server 获取需要执行的 Step 的?(Agent 通过 Grpc 注册到 Server,调用 RPC 方法获取下一个待执行任务)
- 运行 Step 的环境是什么(每个 Step 都将启动一个 Container)
- 一个有多个 Step 的 Workflow 在 Server 上如何存放 Step?(Work Queue)
- 同时有多个项目 Repo 的 Pipeline 同时被 Server 调度运行时,多个 Workflow 分属不同的 Pipeline,而每个 Workflow 又拥有多个 Step,这些 Step 在 Server 的工作队列中是如何被并发调度的?(多协程 )
这些问题会在后续分析 Woodpecker 核心组件设计实现的文章中一一解答,同时我们也会手写自己的 Woodpecker。
五、Woodpecker 部署
官方部署文档中提供了多种部署方式,这里使用 docker-compose
部署。docker 的前置知识这里不再赘述。
往期收藏过百的 Docker 学习文章
docker | jenkins 实现自动化部署项目,后端躺着把运维的钱挣了!(上)
docker | jenkins 自动化CI/CD,后端躺着把运维的钱挣了!(下)
5.1 配置文件
- 创建
docker-compose.yml
配置文件。
version: '3'
services:
woodpecker-server:
image: woodpeckerci/woodpecker-server:latest
ports:
- 8000:8000
volumes:
- woodpecker-server-data:/var/lib/woodpecker/
environment:
- WOODPECKER_OPEN=true
- WOODPECKER_HOST=${WOODPECKER_HOST}
- WOODPECKER_GITHUB=true
- WOODPECKER_GITHUB_CLIENT=${WOODPECKER_GITHUB_CLIENT}
- WOODPECKER_GITHUB_SECRET=${WOODPECKER_GITHUB_SECRET}
- WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET}
woodpecker-agent:
image: woodpeckerci/woodpecker-agent:latest
command: agent
restart: always
depends_on:
- woodpecker-server
volumes:
- woodpecker-agent-config:/etc/woodpecker
- /var/run/docker.sock:/var/run/docker.sock
environment:
- WOODPECKER_SERVER=woodpecker-server:9000
- WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET}
volumes:
woodpecker-server-data:
woodpecker-agent-config:
- 创建同目录下创建
.env
环境变量文件。
WOODPECKER_HOST=http://localhost:8000
WOODPECKER_AGENT_SECRET=e61a65af26d998aa303a7b4ce4015ecde83d3caaa3354a91a1120a09e961269e
WOODPECKER_GITHUB_CLIENT=在GitHub生成
WOODPECKER_GITHUB_SECRET=在GitHub生成
5.2 OAuth App
OAuth App 是什么:
在 GitHub 的上下文中,OAuth App 是一种允许开发者使用 GitHub 用户帐户进行身份验证和访问的应用程序。开发者可以创建自己的 OAuth App,并通过 GitHub 的 OAuth 流程获得对用户帐户的有限访问权限。
OAuth App 在 GitHub 上注册后,会获得一个客户端 ID 和一个客户端密钥(Client Secret)。这些凭据用于在用户授权后获取访问令牌,以便应用程序可以代表用户执行某些操作。
在当前场景中,Woodpecker 为了获得访问 GitHub 的能力(监听仓库变动等),需要在 GitHub 开发者配置中心注册为一个 Oauth App。
创建 OAuth App:
获取 WOODPECKER_GITHUB_CLIENT
和 WOODPECKER_GITHUB_SECRET
的值通常涉及在 GitHub 上创建 OAuth App。以下是如何获取这两个值的步骤:
登录到您的 GitHub 帐户。
单击右上角的 "New OAuth App"。
在 "Application name" 中输入应用程序的名称。
在 "Homepage URL" 中输入应用程序的主页 URL。这可以是任何有效的 URL,因为我是本地部署,因此填入
http://localhost:8000
作为占位符。在 "Authorization callback URL" 中输入授权回调 URL。这是 GitHub 在用户授权后将用户重定向回您的应用程序的 URL。如果在本地测试,可以使用
http://localhost:8000/authorize
作为占位符。
单击 "Register application"。
您将在页面上看到生成的 "Client ID" 和 "Client Secret"。将它们分别赋值给
.env
文件的WOODPECKER_GITHUB_CLIENT
和WOODPECKER_GITHUB_SECRET
:
# .env
WOODPECKER_GITHUB_CLIENT=<Your Client ID>
WOODPECKER_GITHUB_SECRET=<Your Client Secret>
5.3 部署与登录
运行 docker-compose up -d
命令后将于本机 docker 上成功部署 woodpecker。
- 访问
http://localhost:8000/
点击 Login。
- 跳转至 OAuth 授权页面完成授权登录。
- 自动跳转至 Repo 管理页面。
5.4 体验持续集成(CI)
- 点击页面上
Add repository
可以看到 OAuth 关联账号拥有的仓库列表,查找一个事先准备好的 test-repo。
- 点击 Enable 提示报错。
查看 docker 日志分析原因,提示创建 webhook 需要一个公共可访问的 Host 地址,“localhost” 不满足。
docker logs woodpecker_woodpecker-server_1
代替方案
将上述部署行为放到一台可以被公共访问的服务器上进行。
将 GitHub 替换为 Gitea,同样部署在 localhost 进行测试。(这里选择这种方案)
5.5 本地部署 Gitea 代替 GitHub
Gitea 是一个轻量级的、自助的 Git 服务。它是一个开源的、基于 Go 语言的项目,提供了类似于 GitHub、GitLab 等平台的版本控制仓库管理功能。Gitea 允许您在自己的服务器上架设一个 Git 服务,以便团队或个人能够方便地进行代码托管、协作和版本控制。(GitHub Star 40k+)
白泽曾经在 Gitea 有过一段时间的实习,后续可以给大家分享一下~
在本地部署 Gitea 之后,白泽在继续这个 CI 体验流程时遇到了 Woodpecker 和 Gitea 本地通信时一个访问授权 BUG,事后,我发现整个流程也十分值得记录分享。
所以下一篇文章白泽将讲解解决 BUG 的流程,过程中会配合阅读 Gitea & Woodpecker 的代码。为大家梳理使用开源软件遇到问题时的解决思路和步骤。
六、小结
未完待续,欢迎追更。
公众号 「白泽talk」,白泽目前正在打造一个氛围良好的行业交流群,文章的更新也会提前预告,欢迎加入:622383022。
我也开源了一个 Go 学习仓库:包含 Go 各阶段学习文章、读书笔记、电子书、简历模板等,欢迎 star。
Woodpecker CI 设计分析|一个 Go 编写的开源持续集成引擎的更多相关文章
- 使用Gradle构建构建一个Java Web工程及持续集成环境Jenkins配置
安装Eclipse插件——Buildship 什么是Buildship? Buildship能方便我们通过Eclipse IDE创建和导入Gradle工程,同时还能执行Gradle任务. Eclips ...
- 新一代 CI 持续集成工具 flow.ci 正式开源
很高兴地宣布 flow.ci 在 Apache-2.0 协议下正式开源了.flow.ci 是国内首套开源持续集成(CI) 解决方案,帮助企业团队实现开发流程(build-test-deploy)自动化 ...
- CI/CD持续集成/持续部署 敏捷开发
敏捷软件开发(英语:Agile software development),又称敏捷开发,是一种从1990年代开始逐渐引起广泛关注的一些新型软件开发方法,是一种应对快速变化的需求的一种软件开发能力.它 ...
- CI持续集成理论知识
(1)什么是CI What is CI? CI就是持续集成,持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成.每次集成都通过 ...
- Travis CI用来持续集成你的项目
这里持续集成基于GitHub搭建的博客为项目 工具: zqz@ubuntu:~$ node --version v4.2.6 zqz@ubuntu:~$ git --version git versi ...
- 劈荆斩棘:Gitlab 部署 CI 持续集成
阅读目录: install configue gitlab-ci-multi-runner restore nuget packages bulid .sln run unit tests confi ...
- 使用 flow.ci 实现 Android 自动化测试与持续集成
在上篇文章--如何实现 Android 应用的持续部署中,我们使用的是 flow.ci + Github + fir.im 实现 Android 应用的持续部署.对于 Android 开发者,他们可能 ...
- flow.ci + Github + Slack 一步步搭建 Python 自动化持续集成
理想的程序员必须懒惰,永远追随自动化法则.Automating shapes smarter future. 在一个 Python 项目的开发过程中可能会做的事情:编译.手动或自动化测试.部署环境配置 ...
- 基于 flow.ci 实现 PHP 项目自动化持续集成
高效程序员的习惯之一--让开发流程自动化.Automating shapes smarter future. 这是一个关于如何快速实现 PHP 项目自动化持续集成的快速指导.无论你是否使用过持续集成, ...
- GitLab CI/CD 进行持续集成
简介 从 GitLab 8.0 开始,GitLab CI 就已经集成在 GitLab 中,我们只要在项目中添加一个 .gitlab-ci.yml 文件,然后添加一个 Runner,即可进行持续集成. ...
随机推荐
- java笔记——面向对象
1.概述:面向对象是基于面向过程的编程思想 举例:把大象装进冰箱 2.开发:不断的创建对象,使用对象,指挥对象做事情 3.面向对象特征:封装 , 继承 , 多态 4.类和对象的关系: 类是一组相关的属 ...
- mac中删除本地maven库中下载失败的.lastUpdated文件
在 macOS 中,要删除本地 Maven 仓库中所有的 .lastUpdated 文件,您可以使用 find 命令结合 rm 命令来执行这个操作.这可以在终端(Terminal)中完成. 打开您的终 ...
- Why Microservices ?
微服务(Microservices)是一种软件架构设计风格,其中应用程序由一组小型.独立.自治的服务组成,这些服务共同工作以构建整体应用.每个服务都专注于一个特定的业务功能,可以独立部署.扩展和维护. ...
- Django学习(二) 之 模板的使用
写在前面 昨晚应该是睡的最好一天吧,最近一个月睡眠好差,睡不着不说,而且半夜总醒,搞的第二天就会超没精神. 昨天下午去姐姐家,小外甥直接进屋就问我说: 老舅,你都很长时间没来啦,**(前女友)怎么哪去 ...
- [USACO2007OPEN S] Catch That Cow S
题目描述 FJ丢失了他的一头牛,他决定追回他的牛.已知FJ和牛在一条直线上,初始位置分别为x和y,假定牛在原地不动.FJ的行走方式很特别:他每一次可以前进一步.后退一步或者直接走到2*x的位置.计算他 ...
- 关于C#反射概念,附带案例!
反射 C#中的反射是一种使程序在运行时能够动态地获取类型信息并调用其成员的技术.通过反射,程序可以在运行时进行类型的动态加载.创建对象.调用方法和属性,以及访问和修改字段等.反射可以使程序更加灵活,但 ...
- 火眼金睛破局ES伪慢查询
一.问题现象 服务现象 服务接口的TP99性能降低 ES现象 YGC:耗时极其不正常, 峰值200+次,耗时7s+ FULL GC:不正常,次数为1但是频繁,STW 5s 慢查询:存在慢查询5+ 二 ...
- Find a Number (记忆化+BFS)
题目来自"2018-2019 ICPC, NEERC, Southern Subregional Contest",codeforces上放置了此题:Find a Number 题 ...
- 决策树(ID3、C4.5、CART算法numpy实现)
什么是决策树? 决策树(decision tree)是一个树结构(可以是二叉树或非二叉树). 其每个非叶节点表示一个特征属性上的测试,每个分支代表这个特征属性在某个值域上的输出,而每个叶节点存放一个类 ...
- RV1126 分区教程
一.前言 期初我是想弄一个分区存放自己的 APP 程序,如果需要更改应用的时候,只需要烧写独立的分区即可,就不需要重新烧写 rootfs.这是一个简单的操作,为啥还需要记录了,因为我在里面遇到了一些坑 ...