ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Woodpecker 开发者指南:数据库迁移(Xorm ORM)、官方镜像常量与本地镜像构建实战

Woodpecker 开发者指南:数据库迁移(Xorm ORM)、官方镜像常量与本地镜像构建实战 CI/CDDevOps【免费下载链接】woodpeckerWoodpecker is a simple, yet powerful CI/CD engine with great extensibility.项目地址https://gitcode.com/gh_mirrors/wo/woodpecker点击查看免费下载本篇指南面向希望深度参与 Woodpecker CI/CD 引擎开发的贡献者完整梳理 docs/versioned_docs/version-3.16/92-development/07-guides.md 中三大核心主题基于 Xorm 的数据库迁移机制、官方镜像常量的管理规范以及 Server / Agent / CLI 三种组件的本地镜像构建流程。读完本篇你将掌握如何为 Woodpecker 添加一条可自动执行、可回滚、可测试的数据库迁移理解模型变更与表结构同步的底层原理并能从源码编译出可运行、可推送的官方容器镜像。一、ORM 选型Xorm 与 xormigrateWoodpecker 服务端的数据库访问统一基于 Xorm 这一 Go 语言 ORM 实现。围绕 Xorm项目还引入了src.techknowlogick.com/xormigrate作为数据库迁移管理库两者共同构成了服务端数据层的基石。从 migration.go 的导入可以看出迁移任务本身就是一个xormigrate.Migration结构体的切片其中MigrateSession回调接收一个*xorm.Session开发者在这个回调里直接编写针对该数据库方言的 SQL 或 Xorm 操作。Xorm 的另一大职责是模型到表结构的自动同步当模型结构体字段发生变化如新增一个 struct tag 属性时底层 ORM 会基于结构体字段标签自动处理列的新增与调整无需手写 DDL。二、添加一条新的数据库迁移2.1 放置位置与命名规范所有迁移任务都放在server/store/datastore/migration/目录下文件名遵循NNN_描述.go的编号前缀约定。截至当前仓库版本迁移编号已推进到030例如000_legacy_to_xormigrate.go历史遗留迁移记录转换负责把旧版migrations表内容导入 xormigrate 体系后删除旧表001_add_org_id.go为 users 表新增user_org_id列并为每个用户创建对应的 org 记录030_deduplicate_log_entries.go按(step_id, line)去重 log_entries为唯一索引腾出空间。新文件需要自行定义包级变量典型结构如下以001_add_org_id.go为模板package migration import ( fmt src.techknowlogick.com/xormigrate xorm.io/xorm ) var addOrgID xormigrate.Migration{ ID: add-org-id, MigrateSession: func(sess *xorm.Session) error { // 1. 同步涉及的新模型 // 2. 查询旧数据 // 3. 逐条转换并更新 return nil }, }其中ID字段是迁移的唯一标识一旦执行成功会被持久化到迁移记录表中后续启动不会再重复执行。2.2 两条硬性规则原文档明确强调了两条必须遵守的约束不要自行管理事务在MigrateSession内部禁止调用sess.Begin()、sess.Commit()或sess.Close()。会话与事务的生命周期由底层的 xormigrate 迁移管理器统一接管——如果某条迁移失败管理器会尝试回滚该条迁移并终止后续执行见 migration.go 顶部注释。新增模型必须注册如果给数据库添加的是全新模型而非在现有模型上加字段必须将该模型加入 migration.go 中的allBeans变量才能保证新表被创建。例如目前allBeans中注册了Agent、Pipeline、Config、Repo、Secret、Cron、Forge、Org等 18 个模型。2.3 注册到迁移队列编写完迁移文件后需要把新定义的迁移变量追加到migrationTasks切片的末尾位于 migration.go保证它们按顺序执行。该切片头部注释写着「APPEND NEW MIGRATIONS / They are executed in order and if one fails Xormigrate will try to rollback that specific one and quits」即迁移按声明顺序依次执行单条失败会尝试回滚该条并中止。2.4 执行流程与自动记录服务端启动时会调用Migrate(ctx, engine, allowLong)见 migration.go完整流程如下通过xormigrate.New(e, migrationTasks)构建迁移管理器检查旧版migrations表是否存在且为空若是则执行InitSchema初始化初始化回调为空操作因为模型同步随后统一进行调用m.Migrate()依次执行尚未执行过的迁移迁移全部成功后调用syncAll(e)遍历allBeans逐个执行sess.Sync(bean)将最新模型结构同步到真实数据库表见 syncAll。每成功执行一条迁移xormigrate 就会把该迁移的ID写入迁移记录表因此下次启动时它会被自动跳过。这也是「服务端启动自动执行迁移、且不会重复执行」的机制来源。2.5 常用迁移辅助函数迁移目录中的 common.go 提供了一批跨数据库方言的辅助函数避免每个迁移重复编写方言判断函数作用支持方言renameTable(sess, old, new)重命名整张表MySQL / PostgreSQL / SQLitedropTableColumns(sess, table, cols...)删除若干列自动先清理相关索引MySQL / PostgreSQL / SQLitealterColumnDefault(sess, table, column, def)修改列的默认值MySQL / PostgreSQLSQLite 为 no-opalterColumnNull(sess, table, column, null)修改列的空值约束MySQL / PostgreSQLSQLite 为 no-oprenameColumn(sess, table, column, newName)重命名列MySQL / PostgreSQL / SQLite注意dropTableColumns的函数头注释明确要求「YOU MUST COMMIT THE SESSION AT THE END」但如上文所述会话提交应由迁移管理器负责因此该函数注释更多是对历史实现该段代码源自 Gitea的保留说明。由于 SQLite 不支持直接删列common.go中还提供了removeColumnFromSQLITETableSchema与normalizeSQLiteTableSchema通过重写建表 SQL 的方式模拟删列二者都有对应的单元测试验证见 common_test.go。2.6 方言差异处理范例030_deduplicate_log_entries.go 是展示方言差异处理的绝佳范例它先为log_entries创建临时索引以加速删除再针对三种数据库给出不同语法MySQLDELETE a FROM log_entries a JOIN log_entries b ON ...PostgreSQLDELETE FROM log_entries a USING log_entries b WHERE ...SQLiteDELETE FROM log_entries AS a WHERE EXISTS (SELECT 1 ...)。该迁移的注释还揭示了一个重要经验去重类迁移不能标记为 Long因为UNIQUE(step_id, line)索引会在每次启动时由模型同步创建跳过清理会导致同步失败。2.7 迁移测试迁移目录提供了一套完整的测试设施migration_test.go 中的TestMigrate会分别针对「全新数据库」和「旧数据库转储」两种场景执行完整迁移链SQLite 使用内存库与预置转储./test-files/sqlite.dbPostgreSQL 使用pg_dump --inserts生成的./test-files/postgres.sql还原现场测试驱动通过环境变量选择WOODPECKER_DATABASE_DRIVER指定方言默认sqlite3WOODPECKER_DATABASE_DATASOURCE指定 MySQL/PostgreSQL 连接串见 migration_test.go。因此新增迁移后建议在提交前至少本地跑一遍TestMigrate并尽量在 MySQL 与 PostgreSQL 上各验证一次方言 SQL 的正确性。三、官方镜像常量统一管理、必须锁定精确 tagWoodpecker 所有官方默认镜像都集中定义在 shared/constant/constant.go例如const ( // DefaultClonePlugin can be changed by WOODPECKER_DEFAULT_CLONE_PLUGIN at runtime. // renovate: datasourcedocker depNamewoodpeckerci/plugin-git DefaultClonePlugin docker.io/woodpeckerci/plugin-git:2.10.1 ) // TrustedClonePlugins can be changed by WOODPECKER_PLUGINS_TRUSTED_CLONE at runtime. var TrustedClonePlugins []string{...} // TaskTimeout is the time till a running task is counted as dead. var TaskTimeout time.Minute管理规范可以总结为三点集中存放任何官方默认镜像地址必须写入该常量文件不得散落在业务代码里精确锁定镜像必须使用精确 tag如:2.10.1不允许浮动 tag可运行时覆盖部分常量预留了环境变量覆盖入口例如克隆插件可通过WOODPECKER_DEFAULT_CLONE_PLUGIN修改受信任克隆插件列表可通过WOODPECKER_PLUGINS_TRUSTED_CLONE调整常量上方renovate: datasourcedocker depNamewoodpeckerci/plugin-git注释则是依赖机器人自动升级版本的配置标记。四、本地构建镜像以下构建命令均以仓库根目录为工作目录执行。构建产物输出到dist/目录由 Makefile 中DIST_DIR ? dist决定make vendor、make build-*等目标定义均可直接查看仓库根目录 Makefile。4.1 构建 Server 镜像Server 组件体积最大、依赖最重构建分为三步### build web component make vendor cd web/ pnpm install --frozen-lockfile pnpm build cd .. ### define the platforms to build for (e.g. linux/amd64) # (the | is not a typo here) export PLATFORMSlinux|amd64 make cross-compile-server ### build the image docker buildx build --platform linux/amd64 -t username/repo:tag -f docker/Dockerfile.server.multiarch.rootless --push .几点说明make vendor对应 Makefile 中的vendor目标内部执行go mod tidy go mod vendor前端先行cross-compile-server依赖build-ui而build-ui会在web/下执行pnpm install --frozen-lockfile; pnpm build随后build-server还会触发generate-openapi见 Makefile因此在干净环境下首次构建耗时会较长PLATFORMS中的竖线不是笔误Makefile 的cross-compile-server目标会按;分隔多个平台再按|切分 os/arch 对如linux|amd64并分别生成TARGETOS、TARGETARCH_XGO与TARGETARCH_BUILDX供 xgo 与 buildx 使用见 Makefilexgo 平台限制cross-compile-server依赖xgo这个 Go 跨编译工具而 xgo 镜像只提供amd64版本所以必须在 amd64 主机上执行该目标check-xgo目标会在缺 xgo 时自动执行go install src.techknowlogick.com/xgolatest见 Makefile若确实无法使用 xgo可尝试build-server目标直接在本机构建但它在部分操作系统如 macOS上会失败最终docker buildx build使用 docker/Dockerfile.server.multiarch.rootless 构建并--push推送多架构镜像。4.2 构建 Agent 镜像Agent 组件不包含 Web UI构建更轻量### build the agent make build-agent ### build the image docker buildx build --platform linux/amd64 -t username/repo:tag -f docker/Dockerfile.agent.multiarch --push .build-agent使用CGO_ENABLED0静态编译见 Makefile产出dist/woodpecker-agent二进制镜像构建基于 docker/Dockerfile.agent.multiarch。你也可以通过TARGETOS、TARGETARCH环境变量覆盖目标平台Makefile 默认取go env GOOS/go env GOARCH。4.3 构建 CLI 镜像CLI 组件同样不含 UI构建方式与 Agent 类似### build the CLI make build-cli ### build the image docker buildx build --platform linux/amd64 -t username/repo:tag -f docker/Dockerfile.cli.multiarch.rootless --push .build-cli同样以CGO_ENABLED0静态编译见 Makefile产出dist/woodpecker-cli镜像构建基于 docker/Dockerfile.cli.multiarch.rootless。若只需一键产出三个组件的本地二进制可直接执行make build它依次调用build-agent、build-server、build-cli见 Makefile。五、小结本篇围绕 Woodpecker 开发指南的核心内容展开在数据层理解了「Xorm 模型同步 xormigrate 迁移任务」的双轨机制掌握了新迁移的编写位置、注册方式、事务禁忌与方言差异处理并梳理了迁移执行的完整调用链与测试方法在配置与构建层明确了官方镜像常量必须集中存放、锁定精确 tag 的规范以及 Server / Agent / CLI 三个组件从 Makefile 目标到docker buildx build --push的完整本地镜像构建流程。无论是新增数据库字段、添加新模型还是为自定义版本打镜像以上内容都能直接作为可复用的实战参考。赞分享CI/CDDevOps【免费下载链接】woodpeckerWoodpecker is a simple, yet powerful CI/CD engine with great extensibility.项目地址https://gitcode.com/gh_mirrors/wo/woodpecker点击查看免费下载相关推荐Woodpecker 开发指南数据库迁移、官方镜像常量与本地镜像构建实战Woodpecker 开发指南数据库迁移、官方镜像常量与本地镜像构建实战 本篇指南面向希望深入 Woodpecker 源码或为其贡献代码的开发者聚焦开发文档CI/CDDevOpsWoodpecker 容器镜像仓库Registry配置完全指南私有镜像拉取、全局仓库与本地镜像构建Woodpecker 容器镜像仓库Registry配置完全指南私有镜像拉取、全局仓库与本地镜像构建 本篇指南以 Woodpecker CI/CD 引擎 vCI/CDDevOpsCoze Studio 项目实体适配层coze-studio/project-entity-adapter使用指南基于 React Hooks 的项目 CRUD 弹窗封装Coze Studio 项目实体适配层coze studio/project entity adapter使用指南基于 React Hooks 的项目CI/CDDevOps上一篇终极代码美化工具JS Beautifier 完全指南下一篇Vue Konva实战指南打造精美Canvas图形应用创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表