游乐游手机版
首页/AI热点日报/热点详情

火种起源:从零到一搭建CI自动化流水线实战记录

类型:热点整理2026-07-17
高德运营同学半年内从零搭建CI自动化日报系统,借助AI自动完成在线数据解读、钉钉推送及站点部署等环节,实现从原始数据获取到阅读输出仅需十分钟,全程无需人工干预,极大提升日报生成效率。

高德运营同学半年内从零搭建自动化日报系统,用AI解放人力,实现数据到阅读仅需10分钟。

核心内容:

  1. 运营日报的痛点与AI化契机
  2. 从静态站点开始的CI初体验与踩坑历程
  3. 自动化流水线的完整搭建与实战效果

阿里妹导读

文章内容基于作者个人技术实践与独立思考,旨在分享经验,仅代表个人观点。

摘要

作为高德打车区域运营的一员,和所有运营同学一样,日常工作中最耗精力的就是盯数据、写日报、做分析。半年前,对“CI/CD”这个词一无所知,甚至觉得代码库、git这些东西都是开发同学才需要碰的。

但半年后,一套完整的日报自动化流水线已经独立上线:每天定时从ODPS取数,用Qwen大模型自动生成解读,钉钉群自动推送,在线站点自动部署。整个过程无需人工干预,从数据到阅读只需10分钟。

这篇文章不是技术教程,而是一线运营的真实实战记录——从零开始,一步步踩坑、一步步借力AI解决技术问题,最终把整套系统跑起来的故事。

一、背景:为什么运营要搞CI

1.1 日报的痛点

运营团队应该都需要有这样一份日报,要覆盖前一天的目标达成、大盘数据、商户异动、城市峰值、分时应答情况等诸多模块。以前,这份日报的制作流程是这样的:

  1. 打开ODPS进行SQL取数
  2. 把数据复制到Excel里整理
  3. 手动写分析解读
  4. 排版成文档,发到钉钉群
  5. 如果要留档,还得手动上传到某个地方

每天至少花1小时,而且依赖人工读数和业务经验,分析质量高度取决于处理人的经验和细心程度。

1.2 团队AI化的契机

2026年初,团队开始全面推进AI工具落地。Qwen Code、提示词工程、自动化流程……大家都在探索怎么用AI把重复性工作自动化。

团队leader提出了一个想法:日报能不能自动化?每天的数据结构是固定的,分析框架是固定的,唯一变化的是数字本身——这不就是最适合自动化的场景吗?

1.3 为什么选Aone CI

说实话,一开始根本不知道用什么工具。尝试过几个方案:

方案优点缺点
本地Python脚本简单直接每天要手动跑,电脑关了就无法运行
定时任务(crontab)能定时依赖某台机器,不透明
Aone CI流水线云端运行、有日志、能定时触发YAML语法,零基础有学习成本

最终选Aone CI的原因很简单:代码仓库就在Aone上,CI是现成的能力,不用额外搭环境。而且团队里已经有同学在用CI做静态站点托管,有现成的经验可以参考。

二、第一次接触CI:从静态站点开始

2.1 第一个任务:让HTML能被在线访问

CI之旅不是从日报开始的,而是从一个更简单的需求开始——把HTML文件放到在线站点上。

在Aone代码库里有一个静态站点(Aone Pages),可以把HTML文件托管成在线页面。团队里其他同学已经搭好了这个站点,需要做的是:把生成的HTML文件推送到仓库的public/目录下,它就能自动部署到在线地址。

听起来很简单对吧?但实际操作起来,坑一个接一个。

2.2 第一个坑:实战中理解代码库的分支隔离

在master分支的public/文件夹里放了一个HTML文件,然后发现——自己的分支能看到这个文件夹,但其他同学的分支看不到。

当时很困惑:明明在master里建了文件夹,为什么别人的分支没有?

后来问了AI才知道,这是Git分支隔离的正常现象。每个分支是独立的,public/文件夹只存在于创建或合并了它的那些分支上。要让别人的分支也有,需要每个人自己执行一次git pull origin master

2.3 第二个坑:master是保护分支

更头疼的问题来了。仓库的master分支是受保护分支,不能直接push。每次往public/目录合入新的HTML文件,都需要提MR(Merge Request)审核。

这意味着:

  • 每次上传HTML → 提MR → 等审核 → 合入master → 手动更新README(生成新的访问链接)
  • 流程繁琐,效率很低

2.4 用CI解决:自动更新README

如果能配置一条流水线,在每次push HTML文件后自动生成README索引并推送回去,不就不用手动更新了吗?

这是第一次真正动手配置CI流水线。整个过程是在AI的辅助下一步步完成的,大致分为以下几步:

第一步:申请PAT(个人访问令牌)

CI容器里要往仓库push代码,需要一个“通行证”——PAT(Personal Access Token)。CI自带的Token是只读的,不能push。

操作路径:打开 code.alibaba-inc.com → 右上角头像 → 设置 → Private Token → 重置并复制。

第二步:配置Secrets

PAT不能明文写在YAML里(会泄露到日志中),需要通过仓库的变量管理配置为Secrets类型。

类型引用语法适用场景
Secrets${{ secrets.X }}敏感信息(Token、密码、API Key)
Variables${{vars.X}}非敏感配置(项目名、端点地址)

千万别混用——用secrets语法引用Variables类型的变量,值会是空字符串。

第三步:写YAML流水线

这是写的第一条YAML流水线(.aoneci/update-readme.yaml),核心逻辑是:

  1. 检测本次push是否涉及public/*.html文件变更
  2. 如果有,执行scripts/update-readme.sh脚本重新生成README
  3. 用PAT把更新后的README推回当前分支

写YAML的过程充满了挫折感——语法错误不会报错,只是流水线不触发。比如trigger要写成triggers(复数),run: |要写成数组格式,checkout要写成- uses: checkout而不是- checkout。这些调试过程全部依赖AI读取运行日志,一步一步和AI共创问题的解决方案。在这个过程中,不禁想起网上那个梗——“和AI对话的时候,就像绝望的李鸿章,不管他端上来什么,只能无能地点【接受并运行】”......

由此总结出一个经验:不要从零写YAML,先复制仓库里已经跑通的流水线,再改。

2.5 跑通的那一刻

当第一次看到流水线执行成功、README被自动推回分支的时候,那种成就感是真实的。

[INFO] 当前分支: qioyue_370902
[INFO] Token 长度: 20
[INFO] 检测到 HTML 变更: public/test_ci.html
[INFO] 推送到 origin/qioyue_370902(用户: judy.qy)
[OK] README 已自动推回 qioyue_370902

虽然只是一个简单的README自动更新,但它让人理解了CI的基本工作原理:触发条件 → 执行步骤 → 产出结果。这为后面搭建日报流水线打下了基础。

三、搭建日报自动化流水线

3.1 整体架构设计

有了CI的基础认知后,开始设计日报自动化流水线。整体思路是:

定时触发 → 取数 → 生成日报 → 转HTML → 推钉钉 → 推仓库 → 自动部署

具体来说,分为7个步骤:

步骤动作工具/技术
1FBI数据抓取DataClaw API
2ODPS SQL执行MaxCompute(5个模块各配专属SQL)
3AI生成日报Qwen大模型(自然语言总结)
4Markdown转HTMLPython脚本
5推送钉钉Webhook + 加签
6HTML留档git push到个人分支的public/目录
7自动部署触发deploy-pages流水线

3.2 变量配置:一次配好,全仓库共享

日报流水线需要很多配置:ODPS的AccessKey、Qwen的API Key、钉钉Webhook地址等等。

好消息是:代码库的变量配置是仓库级别共享的。只要在Aone CI的变量管理中配置一次,同仓库的所有YAML流水线都可以通过相同语法调用。

配置的变量包括:

变量名类型用途
ODPS_ACCESS_IDSecretMaxCompute AccessKey ID
ODPS_ACCESS_KEYSecretMaxCompute AccessKey Secret
DASHSCOPE_API_KEYSecretQwen大模型API Key
DINGTALK_WEBHOOKSecret钉钉机器人Webhook URL
GIT_PUSH_TOKENSecretPAT(用于HTML推送回仓库)
ODPS_PROJECTVariableODPS项目名

这里有一个值得分享的经验:ODPS权限建议用团队公共账号。申请一个公共AccessKey,授权所需的数据表,然后统一配置到仓库Secrets中。这样:

  • 避免个人AK泄露风险
  • 人员变动无需更换凭证
  • 新人上手零配置

3.3 两条流水线的分离设计

最终搭建了两条独立的流水线:

流水线一:daily-report-auto(日报生成)

  • 镜像:python:3.11
  • 触发:工作日10:30定时 + 个人分支push
  • 职责:取数 → 生成日报 → 推钉钉 → 推HTML到public/

流水线二:deploy-pages(站点部署)

  • 镜像:alios-8u(自带jq + git)
  • 触发:push到public/时实时触发 + 每天17:00定时兜底
  • 职责:合并所有分支的public/内容 → 部署到生产站点

为什么要拆成两条?因为Aone CI的uses:组件运行在隔离容器中,python:3.11镜像缺少deploy-pages需要的jq工具,而且无法在流水线中补装。所以把“生成”和“发布”拆开,各用各的镜像,互不干扰。

四、并发问题:多人协作的终极挑战

日报流水线跑通后,以为大功告成了。但很快遇到了一个更棘手的问题——多人协作时HTML互相覆盖。

4.1 问题是怎么发生的

团队只有一个Aone Pages静态站点,deploy-pages每次部署是全量替换(不是增量追加)。

场景还原:

  1. 在个人分支生成了日报HTML → 推到public/daily-report/ → 触发部署 → 站点上有了日报 ✅
  2. 其他同学往master分支合入了一个活动页面 → 触发master的deploy-pages → 用master的public/全量替换站点
  3. 日报消失了 ❌(因为master的public/里没有daily-report/)

核心矛盾:所有人都在各自分支生成HTML,但站点只有一份,每次部署都是全量替换。

4.2 解决方案:每次部署前合并所有分支

思路很明确:每次部署前,先把所有远程分支的public/**内容合并到一起,再部署完整集合。

具体实现是在deploy-pages.yaml的部署步骤前加一个“合并”环节:

# 动态发现所有远程分支
git fetch origin --depth=1
ALL_BRANCHES=$(git branch -r | grep -v 'HEAD' | sed 's|origin/||' | tr -d ' ')

# 逐一拉取每个分支的public/内容
for branch in $ALL_BRANCHES; do
  git fetch origin $branch --depth=1 2>/dev/null || true
  git checkout origin/$branch -- public/ 2>/dev/null || true
done

# 当前触发分支的内容最后覆盖(保证最新变更优先)
git checkout HEAD -- public/ 2>/dev/null || true

这样无论谁触发部署,所有人的HTML都会先合并进来,再一起部署。

4.3 为什么每个分支都要有deploy-pages.yaml

Aone CI读取的是被推送分支上的YAML。如果分支上没有deploy-pages.yaml,推public/时不会触发任何部署。

好消息是:所有分支的YAML内容完全一样,不用各自定制。如果你是从master新建的分支,这个文件已经自动继承了。

4.4 防护机制

设计了几层防护,确保系统健壮:

异常场景防护措施
新分支没放yaml不会触发部署,不会覆盖别人(无害)
新分支放了正确yaml自动合并所有分支内容后部署(安全)
新分支放了错误yaml下次正确分支部署时自动恢复
站点被意外覆盖每天17:00定时部署自动恢复完整内容

17:00的定时任务是一个兜底机制,应对极端情况。正常情况下,每次push触发的实时部署就已经包含了所有分支的内容。

4.5 为什么不用[skip ci]防循环

最初想用[skip ci]标记来防止部署流水线重复触发,但后来发现[skip ci]会杀死所有流水线(包括日报生成流水线)。

更好的方案是用paths过滤:只在public/**有变更时才触发deploy-pages。这样不该跑的流水线不会被误杀。

五、经验总结与可复用模板

5.1 新人接入最容易踩的坑(实战总结)

以下是搭建CI流水线过程中真实踩过的坑,涵盖语法陷阱、环境隔离和平台机制差异,按配置流程顺序排列:

#坑点现象根因正确做法
1YAML触发器关键字写错push后流水线列表无新任务必须写 triggers:(复数),写成 trigger: 不报错但不生效triggers: 固定复数,下面嵌套 push: / schedule:
2Secrets/Variables语法混用环境变量为空,脚本报"key not found"两种类型引用语法不同,混用取空Secrets用 ${{ secrets.X }},Variables用 ${{ vars.X }};Variables需在YAML中显式export
3git push报403fatal: The requested URL returned error: 403阿里内网不支持 oauth2:TOKEN 格式必须用 https://用户名:PAT@code.alibaba-inc.com/repo.git 格式
4uses:组件看不到前面装的工具apt install jq 成功但 uses: deploy-pages 报 "jq: command not found"uses: 运行在完全隔离的容器,不继承run步骤的环境拆成两条流水线,各用各的镜像
5$CI_COMMIT_BRANCH不存在fatal: invalid refspec 'HEAD:'Aone CI没有此内置变量(不是GitLab CI)git rev-parse --abbrev-ref HEAD 动态获取分支名
6定时任务写在个人分支不触发cron配了但到点无反应schedule调度器只从master分支读取配置YAML必须push到master;job内 git fetch + checkout 切个人分支执行
7cron时间差8小时想10:30触发,凌晨2:30跑了Aone CI cron按北京时间CST解释,不是UTC直接写北京时间,如 "30 10 * * 1-5"
8[skip ci]杀全局循环解决了但日报流水线也不跑了[skip ci] 全局生效,所有流水线都不触发paths 过滤精确控制触发范围,如 daily-report/** / public/**
9手动重跑用旧配置改了YAML但重跑还是旧逻辑重跑加载的是所选commit对应的YAML改完YAML先push新commit(不含[skip ci]),再触发新commit
10run:多行语法报错YAML解析通过但执行报语法错误Aone CI的 run: 要求数组格式写成 run: 下接 - | 数组元素,不能用 run: |

总结心法:遇到CI问题别自己死磕。把完整的报错日志复制给AI,让它帮你分析定位。配置CI的效率不取决于记住了多少语法,而是能不能快速定位问题。

5.2 调试CI的正确姿势

善用调试三板斧:查官方手册 → 对比已跑通的YAML → 加诊断输出。

遇到报错不要慌,把完整的日志信息复制给AI,让它帮你分析。这是整个CI搭建过程中最高效的调试方式。

5.3 关键设计决策回顾

决策为什么这么做
全部部署在个人分支master有保护,无法直接push;个人分支无限制,PAT即可跑全流程
用独立流水线做部署日报流水线的环境缺少发布所需的工具且无法补装,拆开后互不干扰
用paths而不是[skip ci]防循环[skip ci]会杀死所有流水线;paths只拦不该跑的
用团队公共ODPS账号避免个人AK泄露风险,人员变动无需换凭证,新人零配置
SQL取数+AI总结数据准确性由SQL保证(0幻觉),AI只负责自然语言解读

5.4 关键代码文件清单

如果你想搭建类似的日报自动化流水线,以下是需要关注的文件:

文件职责
.aoneci/daily-report-auto.yaml主流水线:触发器 + 环境变量注入 + 日报生成全流程
.aoneci/deploy-pages.yaml部署流水线:push public/实时触发 + 定时兜底
daily-report/config.py统一配置:路径、URL、开关、仓库信息
daily-report/generator.pyODPS SQL执行 + Qwen prompt组装 + Markdown生成
daily-report/md_to_html.pyMarkdown → 自包含HTML转换
daily-report/notifier.py钉钉Webhook推送(加签 + 精简格式)
daily-report/publish_html.pyHTML推送到public/ + 触发Pages部署
daily-report/sql/各模块专属SQL文件
daily-report/prompts/各模块Qwen prompt模板

写在最后

回头看这半年的经历,从一个连YAML是什么都不知道的运营,到能独立搭建和维护CI自动化流水线,最大的感触是:

AI不会替代运营,但会用AI的运营会替代不会用的。

搭建CI的过程中,遇到的每一个技术问题——YAML语法、Git认证、ODPS权限、多分支并发——都是在AI的辅助下解决的。不需要记住每一个技术细节,只需要知道要实现什么效果,然后把报错信息告诉AI,让它帮忙找到解决方案。

当然,有些东西是需要自己理解的:

  • 业务逻辑:哪些数据重要、怎么分析、怎么呈现——这是运营的核心能力
  • 系统设计:为什么要拆两条流水线、为什么要合并分支——这些决策需要理解业务场景
  • 质量把控:AI生成的内容需要人工校验,数据准确性需要机制保障

技术工具在变,但运营的核心价值没变:用数据驱动决策,用效率创造价值。CI只是帮你把重复性工作自动化了,让你有更多时间去做真正需要人判断的事情。

如果你也是一个想用技术提效的运营同学,建议是:不要怕,从最简单的开始,一步步来,遇到问题就问AI,与AI协同找到解决方案。你会发现,那些看起来很“技术”的东西,其实并没有那么难。

本文是「火种&起源」系列的一部分,记录一线运营同学在AI工具实践中的真实故事。

来源:https://www.53ai.com/news/shuziyuangong/2026062989432.html

相关热点

继续查看同栏目近期热点。

延伸阅读

补充最近整理过的热点入口。