DevOps【免费下载链接】concourseConcourse is a container-based automation system written in Go. Its mostly used for CI/CD.项目地址https://gitcode.com/gh_mirrors/con/concourse点击查看免费下载Concourse 是一个用 Go 编写的、基于容器的自动化系统主要用于 CI/CD持续集成与持续交付。这份贡献指南面向想要为 Concourse 提交代码、参与社区治理或希望在本地完整跑通源码构建—运行调试—编写测试—提交 PR全流程的开发者。读完本文你将掌握 Concourse 的仓库结构、本地开发环境的搭建方法、web/worker容器与flyCLI 的构建调试手段以及单元测试、testflight、Elm 测试、Kubernetes 端到端测试等多层测试体系的运行方式。一、贡献流程与社区治理Concourse 项目采用开放治理模型open governance model项目职责被划分给多个自组织团队每个团队在仓库的teams/目录下描述自己的职责governance 仓库不在本代码库内。其中maintainers维护者团队负责 issue 与 PR 积压事项以及本仓库内的全部代码core核心团队与 maintainers 协作通过RFC 流程确保 Concourse 产品与其设计原则保持一致。参与贡献的第一步可选是注册成为 individual contributor注册后可以获得三项便利在 Discord 中获得contributors角色可在#dev频道交流获得 Concourse 仓库 issue 与 PR 的 triage分流整理权限获得为你的 PR 重新触发构建的能力。如果你打算实现新功能建议先提交 RFC 征求反馈——并非每个改动都需要但提前征询意见能节省大量返工时间。除了写代码还有很多其他贡献方式在 Discussions 和 Discord 中帮助他人、对 RFC 提供反馈、triage Issues、改进文档等。所有社区互动都必须遵守 CODE_OF_CONDUCT.md并且所有贡献者都必须在 Linux Foundation 的 EasyCLA 完成注册后才能合并代码。二、开发环境依赖要在本地构建、测试和运行 Concourse需要先安装以下工具依赖最低版本原文档要求gov1.16gitv2.11yarnv4docker compose需支持 compose v2 语法postgresql用于本地数据库操作几点基于当前仓库的补充说明原文档要求 Go v1.16但当前仓库 go.mod 头部声明了go 1.27.1模块名为github.com/concourse/concourse/v8实际构建时请使用足够新的 Go 工具链仓库使用 yarn 4 管理前端依赖package.json 中声明了packageManager: yarn4.14.1安装依赖前请确保 yarn 版本为 4.x注意Concourse 使用 Go module 系统因此不要把仓库 clone 到$GOPATH目录下否则模块解析会出问题。三、从源码构建并本地运行 Concourse在仓库根目录依次执行以下命令即可完成构建并启动本地集群$ yarn install $ yarn build $ docker build -t concourse/concourse:local . $ docker compose up -d说明yarn build会构建 web UI 静态资源其内部依次调用build-less、build-elm、build-js见 package.json 的scripts字段docker build -t concourse/concourse:local .使用仓库根目录的 Dockerfile 构建本地镜像。该 Dockerfile 明确标注仅用于本地开发并非官方concourse/concourse镜像的构建方式它基于concourse/dev基础镜像先单独下载 Go module避免每次改动都重下再编译./cmd/init/init.ccontainerd 用的 init 可执行文件与concourse主二进制并设置了CONCOURSE_WEB_PUBLIC_DIR/src/web/public让本地构建的 web 资源能自动生效启动后 Concourse 运行在 http://localhost:8080。docker-compose.yml 定义了三个服务dbPostgreSQL 数据库宿主机端口映射为6543:5432库名concourse、用户dev、密码devPOSTGRES_HOST_AUTH_METHOD默认trust并带有健康检查web以command: web启动 ATC 与 TSA暴露8080:8080挂载./hack/keys作为签名密钥目录并注入CONCOURSE_ADD_LOCAL_USER: test:test,guest:guest与CONCOURSE_MAIN_TEAM_LOCAL_USER: test等本地用户配置worker以command: worker启动privileged: true使用CONCOURSE_RUNTIME: containerd运行时通过 TSA 密钥CONCOURSE_TSA_PUBLIC_KEY、CONCOURSE_TSA_WORKER_PRIVATE_KEY向web:2222注册。密钥文件由 hack/keys/setup 脚本生成其核心逻辑是调用concourse generate-key生成三类密钥concourse generate-key -t rsa -b 1024 -f session_signing_key concourse generate-key -t ssh -b 1024 -f tsa_host_key concourse generate-key -t ssh -b 1024 -f worker_key cp worker_key.pub authorized_worker_keys构建flyCLI 并接入本地实例$ go install ./fly该命令会把fly可执行文件安装到$GOPATH/bin请确保该目录在$PATH中。接着可以跑通一个完整的示例流水线1. 登录本地 Concoursetarget 命名为dev$ fly -t dev login -c http://localhost:8080 -u test -p testtest用户正是由docker-compose.yml中的CONCOURSE_ADD_LOCAL_USER创建的本地用户。2. 创建每分钟触发一次 hello world 任务的示例流水线$ git clone gitgithub.com:concourse/examples.git $ fly -t dev set-pipeline -p example -c examples/pipelines/time-triggered.ymlconcourse/examples仓库提供了一系列示例流水线time-triggered.yml是一个按时间触发器执行的 hello world 示例。3. 取消暂停该流水线$ fly -t dev unpause-pipeline -p example四、仓库结构与模块划分Concourse 的源码以monorepo形式组织服务端组件是 Go 代码web UI 是 Elm 与 Less 代码。顶层目录沿用了早期各组件独立成仓时的航空管制风格命名目录职责说明atcConcourse 的大脑流水线调度、构建跟踪、资源检查、web UI/API 服务端是concourse web的一半flyflyCLI 的全部命令实现webweb UI 的 Elm 源码与资源构建后被嵌入concourse可执行文件并由 ATC 的 web 服务提供go-concourse访问 ATC API 的 Go 客户端库fly内部使用。原文档明确警告不要在外部项目里使用它否则会与你的go.mod纠缠不清skymarshal把 Dex 适配为 ATC 可嵌入的认证组件同时包含fly与concourse web的认证 flag 定义tsa自研 SSH 服务器负责安全认证与注册 worker是concourse web的另一半workerconcourse worker的库代码向 TSA 注册、周期性回收容器/卷等cmd胶水代码把 ATC、TSA、Garden 组装成单个concourseCLI。入口见 cmd/concourse/main.go其中通过CONCOURSE_前缀把环境变量映射为命令行 flagtestflight验收测试套件覆盖流水线与fly功能针对单个 Concourse 部署运行可在本地开发机执行topgun覆盖运维级功能与 Concourse 运行时的技术细节使用 BOSH 与 K8s 部署自己的集群测试后销毁只能在 CI 中运行integration与topgun类似但用docker compose拉起 Concourse 集群可在本地运行五、改动后如何重新构建验证每次改动后可以用下面的命令重建并重建web与worker容器$ docker compose up --build -d该命令可以在原docker compose up仍在运行的情况下于另一个终端中执行。如果改动涉及底层开发镜像本身例如 Go 版本升级需要先拉取最新的concourse/dev镜像让本地容器基于新镜像构建$ docker pull concourse/dev $ docker compose up --build -d修改仓库外依赖以dex为例如果修改的依赖不在本仓库内如dex需要先在go.mod中通过replace指令指向你的 fork# 推送到你 dex fork 的 sample 分支后拉取该模块修订版并得到版本号 $ go mod download -json github.com/your-user/dexsample | jq .Version go: finding github.com/your-user/dex sample v0.0.0-20210401171635-fe97ad5e1a6d # 用该版本更新 go.mod加入 replace 指令 $ echo replace github.com/concourse/dex github.com/your-user/dex v0.0.0-20210401171635-fe97ad5e1a6d \ ./go.mod # 执行常规构建 $ docker compose up --build -d注意原文档中的示例是把echo ... ./go.mod直接覆盖文件实际开发中请用编辑器把 replace 指令追加到 go.mod 的require块之后避免误删原有内容。六、Web UI 开发Concourse 后端是 Goweb UI 则是Elm Less。改动 web 目录后执行以下命令重建 web 资源$ yarn install $ yarn build本地构建的新资源会自动同步到web容器无需重启容器——这是因为 Dockerfile 把/src设为 VOLUME并将CONCOURSE_WEB_PUBLIC_DIR指向挂载目录/src/web/public。针对 Elm 代码仓库还提供了几个便捷脚本见 package.json静态分析yarn analyse由elm-analyse驱动报告未使用的 import、变量与潜在优化点加-s会在localhost:3000起一个便于浏览的服务器甚至支持部分自动修复格式化yarn format按官方 Elm Style Guide 用elm-format统一代码风格基准测试yarn benchmark在web/elm下编译并运行 benchmarks测试yarn test在web/elm下运行elm-test。七、本地调试用dlv附加运行中的实例Concourse 正在本地运行时可以附加dlv脚本封装整个流程# 跟踪正在运行的 web 实例 $ ./hack/trace web # 跟踪正在运行的 worker 实例 $ ./hack/trace worker脚本的底层原理见 hack/trace 源码先用docker exec $container_name pidof concourse拿到容器内进程 PID再用 hack/dlv/Dockerfile 构建一个内含 dlv 的镜像最后以--pidcontainer:$container_name方式运行容器并执行dlv attach $trace_pid。若想附加 IDE 调试器可用--listen指定端口dlv 将以 headless 模式监听该端口$ ./hack/trace web --listen 2345 $ ./hack/trace worker --listen 2345随后在 IDE 中配置远程调试参数hostlocalhostport2345以 GoLand 为例进入Run | Edit Configurations… | | Go Remote填入上述参数即可。八、本地基础设施Jaeger、Vault、Prometheus 与 Postgres1. 分布式追踪Jaeger仓库在 hack/overrides/jaeger.yml 提供了 docker-compose override 文件除 Jaeger 外还一并带上了 Elasticsearch存储 span与 Kibana可视化。它同时为web/worker注入CONCOURSE_TRACING_SERVICE_NAME与CONCOURSE_TRACING_OTLP_ADDRESS: jaeger:4317环境变量把 Concourse 的 OTLP 追踪数据导向 Jaeger。启动方式$ docker compose \ -f ./docker-compose.yml \ -f ./hack/overrides/jaeger.yml \ up -d运行后可访问 Jaeger UIlocalhost:25000映射到容器 16686 端口查看 trace。追踪相关的后端实现见 tracing 目录支持 noop、jaeger、otlp、stackdriver、honeycomb 等。2. 本地 VaultVault 的本地环境准备分两步确保安装了certstrap运行./hack/vault/setup并按其输出逐步操作。hack/vault/setup 脚本会依次用 certstrap 生成 CA 与双向证书vault-ca、vault、concourse三套、打印三个后续步骤的提示用 vault override 启动 compose、导出VAULT_CACERT、运行./hack/vault/init。hack/vault/init 脚本则完成初始化与认证配置执行vault operator init生成 unseal keys 与 root token、unseal 三次、写入concourse策略hack/vault/config/concourse-policy.hcl、启用 cert 认证后端并把concourse证书绑定到该策略最后生成 token 文件。Vault 服务本身通过 hack/overrides/vault.yml 注入它给web挂载证书目录并配置CONCOURSE_VAULT_URL、CONCOURSE_VAULT_AUTH_BACKEND: cert、CONCOURSE_VAULT_CA_CERT等环境变量同时拉起hashicorp/vault容器端口8200:8200。更完整的用法可参考 Vault 凭据管理器文档 下的实现。3. 本地 Prometheus与 Jaeger 类似hack/overrides/prometheus.yml 在基础栈上叠加 Prometheus为web开启CONCOURSE_PROMETHEUS_BIND_IP/CONCOURSE_PROMETHEUS_BIND_PORT9100 端口暴露指标端点并配置 Prometheus 以 5s 间隔抓取web:9100$ docker compose \ -f ./docker-compose.yml \ -f ./hack/overrides/prometheus.yml \ up -d之后打开 http://localhost:9090 即可查询并绘制concourse_前缀的 Prometheus 指标。小贴士仓库还提供了 hack/dc 脚本它会自动把vault、prometheus、jaeger三个 override 与基础docker-compose.yml合并后透传参数方便一次性带上全部基础设施。4. 连接本地 Postgres以docker compose up启动后可用如下参数连接db节点hostlocalhostport6543usernamedevpassword空trust认证databaseconcourse仓库提供了 hack/db 工具脚本优先使用pgcli否则回退到psql$ ./hack/db重置数据库则需要先停掉所有服务删除db容器再启动$ docker compose stop $ docker compose rm db $ docker compose start九、数据库迁移MigrationsConcourse 的数据库迁移文件位于 atc/db/migration/migrations使用 Concourse 自研迁移库生成。文件名格式固定为migration_version_migration_name.(up|down).(sql|go)其中迁移版本号是文件创建时刻的 Unix 时间戳以保证迁移始终按时间顺序执行。打开该目录可以看到真实样例例如最早的1510262030_initial_schema.up.sql、Go 类型迁移1516643303_update_auth_providers.up.go等。快捷方式create-migration脚本$ ./atc/scripts/create-migration my_migration_name # 或生成 Go 迁移 $ ./atc/scripts/create-migration my_migration_name go该脚本见 atc/scripts/create-migration实际执行的是用go build -tags postgres编译./db/migration/cli为migrate可执行文件然后调用migrate generate -d ./db/migration/migrations/ -n$1 -t ${2-sql}默认 SQL 类型。手动方式使用迁移 CLI构建 CLI$ cd atc/db/migration $ go build -o mig ./cli运行generate子命令参数为迁移名称、文件类型SQL 或 Go以及可选的输出目录默认./migrations$ ./mig generate -n my_migration_name -t sql该命令会生成两个文件1510262030_my_migration_name.down.sql 1510262030_my_migration_name.up.sqlCLI 的底层实现见 atc/db/migration/cli/command/command.goGenerateCommand提供-d/--directory默认migrations、-n/--name、-t/--type三个 flag类型仅支持sql与goSQL 迁移生成两个空文件Go 迁移则基于模板生成含Up_timestamp()/Down_timestamp()空函数骨架的文件。生成好 up/down 迁移文件后在其中填充具体的数据库变更语句。concourse web启动时会扫描atc/db/migration/migrations目录并按顺序执行新迁移。十、测试你的改动任何新功能或 bug 修复都应有测试覆盖。没有测试的 PR 几乎不可能被合并尤其是较大的功能改动。Concourse 的测试体系分为多个层次测试套件位置/命令说明单元测试foo_test.go与foo.go同目录任何贡献都应尽量编写testflighttestflight核心 Concourse验收测试覆盖流水线逻辑与fly execute大多数通过流水线或fly暴露的功能都应在其中加测试Elm 测试web/elm/tests隔离测试 web UI 的 Elm 函数web/elm/src/module.elm对应web/elm/tests/moduleTests.elm推荐对update与view做较彻底的覆盖web/watsweb/wats针对 web UI 的验收测试像testflight一样跑在真实 Concourse 集群上仍处于早期阶段topguntopgun更重量级覆盖对运维更可见的行为通常不要求 PR 新增该套件安装测试工具链Concourse 的 Go 测试使用Ginkgo作为框架与套件运行器。按原文档安装 ginkgo CLI$ go get github.com/onsi/ginkgo/ginkgo若使用 v2则对应go install github.com/onsi/ginkgo/v2/ginkgo。单元测试的 fake 由Counterfeiter生成。如果你新增或修改了接口需要在接口所在目录重新生成 fake$ go generate ./...运行单元测试Concourse 代码量很大建议只运行你正在改动的组件的测试。在目标包目录内执行$ ginkgo -r -p-r递归运行当前工作目录下所有包-p包内所有用例并行执行。也可以直接把包路径作为参数传入而无需cd。注意直接运行go test ./...会失败——测试目前假设同一时刻只有一个包在跑这是ginkgo的默认行为而go test默认并行执行每个包为测试服务器分配端口之类的用例会互相冲突。想跑全代码库的单元测试可执行如下命令跳过所有集成测试与 linux 专属测试ginkgo -r -p -race -flake-attempts3 \ -skip-package ./integration,testflight,topgun,./worker/integration,./worker/runtime/integration,./worker/baggageclaim如果你在非 Linux 平台部分测试必须在 Linux 上才能通过推荐改用 Docker 方式运行也顺便覆盖 linux 专属测试docker run --privileged -v .:/src -it --entrypoint /bin/bash concourse/unit进入容器后代码挂载在/srccd /src go install github.com/onsi/ginkgo/v2/ginkgo ginkgo -r -p -race -flake-attempts3 \ -skip-package ./integration,testflight,topgunElm 测试、分析与格式化测试在仓库根目录执行yarn test或在web/elm目录执行elm-test整套跑起来很快可以每次改动都跑一遍静态分析yarn analyse格式化yarn format。运行testflight验收测试testflight针对真实运行的 Concourse。默认目标就是localhost:8080即docker compose up起来的实例。已经起好集群后按单元测试同样的方式运行$ ginkgo -r -p testflight因为testflight会实际执行真实负载如果机器核心数超过 8 个建议限制并行度$ ginkgo -r --nodes4 testflight运行web/watsweb 验收测试在web/wats目录下执行yarn test它用 puppeteer 驱动 headless Chromium。一个实用技巧是测试失败时失败瞬间的截图会保存在web/wats/failure.png。已知这些测试在默认的并行模式下存在问题源于上游依赖可改用yarn test --serial串行执行规避。运行 Kubernetes 端到端测试Kubernetes 相关测试都是端到端的位于topgun/k8s需要可访问的真实 Kubernetes 集群通过配置好的~/.kube/config授权。本地起集群推荐用kind——只需要docker和kindCLI。若希望高并发运行测试建议配置多个节点例如kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes: - role: control-plane - role: worker - role: worker - role: worker - role: worker集群起来后还需要配置 Tiller这些测试仍使用 Helm 2kubectl create serviceaccount \ --namespace kube-system \ tiller kubectl create clusterrolebinding \ tiller-cluster-rule \ --clusterrolecluster-admin \ --serviceaccountkube-system:tiller helm init \ --service-account tiller \ --upgrade测试依赖以下环境变量CONCOURSE_IMAGE_TAG或CONCOURSE_IMAGE_DIGEST部署到 k8s 集群时使用的 Concourse 镜像 tag 或 digestCONCOURSE_IMAGE_NAME部署使用的镜像名HELM_CHARTS_DIRhelm/charts 仓库 clone 的路径用于定义 Concourse 依赖的 postgres chartCONCOURSE_CHART_DIRConcourse Helm chart 副本所在路径。设置完毕后进入topgun/k8s运行 Ginkgo# 串行运行 ginkgo . # 以 16 并发运行 ginkgo -nodes16 .关于topgun的说明topgun套件相当重量级目前不期望大多数贡献者运行或修改它外部贡献者跑起来也比较困难。要运行topgun需要有一个正在运行的BOSH director唯一要求是能访问它创建的实例。本地搭建可借助 concourse-bosh-release 仓库的 dev 脚本# clone concourse-bosh-release 仓库 git clone https://github.com/concourse/concourse-bosh-release cbr cd $_ # 运行 setup 脚本需先安装 BOSH CLI ./dev/vbox/setupsetup会创建 BOSH director别名为vbox、上传测试所需的 releases 以及 BOSH Lite stemcell。之后进入对应套件运行测试# 获取 concourse 仓库并进入 git clone https://github.com/concourse/concourse concourse cd $_ # 进入要工作的 topgun 套件目录 cd ./topgun/$SUITE # 运行该套件测试 BOSH_ENVIRONMENTvbox ginkgo -v .十一、提交代码commit 规范与 PR 要求一次理想 commit 的结构原文档给出了一个示例 commit 的解剖i ii iii | | | web: structure: add var declarations Since scripts are run in module mode, they follow the strict mode semantics. Variables must be declared prior to being assigned (e.g. - iv cannot have x 1 without declaring x (using var, let, or const) concourse/concourse#5131 -------------------------------------------- v Signed-off-by: Aidan Oldershaw aoldershawpivotal.io -------------- vi各部分含义component changed被改动的组件名对应上文Developing Concourse中的目录划分如web、atc、flystructure vs behaviour标注本次改动属于结构变更还是行为变更简短、祈使语气的变更描述如add var declarations讲述一个完整故事的消息正文——解释为什么做这个改动而不只是改了什么关联的 issue 编号本示例为concourse/concourse#5131sign-off 行见下文签署你的工作。结构与行为分离Structure and Behaviour理想情况下每个 PR 都应该很小但代码库庞大复杂的改动有时无法避免。为了减轻评审负担社区总结了几个实用做法聚焦 commit使每次提交只改动单一组件把结构变更与行为变更隔离开并在 commit 标题中明确标注类型——更好的是把同类型 commit 连续成块提交在 commit 消息中给出清晰的文字论证。改动的动机往往需要翻查大量资料才能弄清如果不在 commit 消息里写明白diff 会显得非常晦涩。提交前的准备工作在 fork 上开发并推送分支后提交前请确保运行goimports保证代码符合代码风格规范可选参考 Go style guide所有改动都有充分的测试覆盖详见Testing your changes一节所有贡献者都已在 Linux Foundation 的 EasyCLA 注册相关文档应在另一个关联 PR 中更新——如果你对技术写作没有信心可以跳过这一步。完成后就可以提交 pull request。结语把贡献落到行动从安装 Go、yarn、docker compose 等开发依赖到yarn build docker compose up拉起一套本地 Concourse从用hack/trace附加 dlv 断点调试web/worker到用迁移 CLI 生成数据库迁移再到用ginkgo运行单元测试、testflight验收测试与 Elm 测试——这条完整的开发链路都沉淀在仓库的 CONTRIBUTING.md 与配套脚本中。无论你想提交一个 bug 修复、一个新功能记得先考虑 RFC还是只想改善文档都可以按本文的路径快速进入状态并用规范的单组件 commit 与充分的测试覆盖让 PR 更容易被维护者接受。赞分享DevOps【免费下载链接】concourseConcourse is a container-based automation system written in Go. Its mostly used for CI/CD.项目地址https://gitcode.com/gh_mirrors/con/concourse点击查看免费下载相关推荐PouchDB 贡献指南从本地构建、测试、提交 PR 到版本发布的完整开发流程PouchDB 贡献指南从本地构建、测试、提交 PR 到版本发布的完整开发流程 本指南以仓库根目录的 CONTRIBUTING.md https://link数据库数据同步IPython 贡献指南实战从提 Issue、发 PR 到本地测试与文档构建的完整工作流IPython 贡献指南实战从提 Issue、发 PR 到本地测试与文档构建的完整工作流 本指南以 IPython 官方仓库的 CONTRIBUTING.md开发工具CLIVoid 开源贡献实战指南从开发者模式调试到本地构建与提交 PRVoid 开源贡献实战指南从开发者模式调试到本地构建与提交 PR Void 是一款开源的 AI 代码编辑器其大部分业务代码集中在 src/vs/workbe代码编辑器开发工具AI Agent人工智能上一篇Agent Skills文档管线揭秘llms.txt每日自动更新如何让AI永远掌握最新SDK知识下一篇Quill 会议录音状态机单元测试实战如何确定性地测试捕获健康、恢复与停止竞态创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考