2026年7月2日 周四晚上19:30,报名腾讯会议了解“如何构建自进化的动态知识库(Brain)”(限30人)
免费POC, 零成本试错
FDE知识库

FDE知识库

学习大模型的前沿技术与行业落地应用


我要投稿

火种&起源:一个运营从0到1搭建CI自动化流水线的实战记录

发布日期:2026-06-29 09:21:34 浏览次数: 1521
作者:阿里云开发者

微信搜一搜,关注“阿里云开发者”

推荐语

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

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

杨芳贤
53AI创始人/腾讯云(TVP)最具价值专家

阿里妹导读


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

摘要

作为一名高德打车的区域运营同学,和常规运营同学一样,日常工作中需要大量时间和精力在盯数据、写日报、做分析上。半年前,我对"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个步骤:

步骤

动作

工具/技术

1

FBI数据抓取

DataClaw API

2

ODPS SQL执行

MaxCompute(5个模块各配专属SQL)

3

AI生成日报

Qwen大模型(自然语言总结)

4

Markdown转HTML

Python脚本

5

推送钉钉

Webhook + 加签

6

HTML留档

git push到个人分支的public/目录

7

自动部署

触发deploy-pages流水线

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

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

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

我配置的变量包括:

变量名

类型

用途

ODPS_ACCESS_ID

Secret

MaxCompute AccessKey ID

ODPS_ACCESS_KEY

Secret

MaxCompute AccessKey Secret

DASHSCOPE_API_KEY

Secret

Qwen大模型API Key

DINGTALK_WEBHOOK

Secret

钉钉机器人Webhook URL

GIT_PUSH_TOKEN

Secret

PAT(用于HTML推送回仓库)

ODPS_PROJECT

Variable

ODPS项目名

这里有一个值得分享的经验: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=1ALL_BRANCHES=$(git branch -r | grep -v 'HEAD' | sed 's|origin/||' | tr -d ' ')
# 逐一拉取每个分支的public/内容for branch in$ALL_BRANCHESdo  git fetch origin $branch --depth=12>/dev/null || true  git checkout origin/$branch -- public/ 2>/dev/null || truedone
# 当前触发分支的内容最后覆盖(保证最新变更优先)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流水线过程中真实踩过的坑,涵盖语法陷阱、环境隔离和平台机制差异,按配置流程顺序排列:

#

坑点

现象

根因

正确做法

1

YAML触发器关键字写错

push后流水线列表无新任务

必须写 triggers:(复数),写成 trigger: 不报错但不生效

triggers: 固定复数,下面嵌套 push: / schedule:

2

Secrets/Variables语法混用

环境变量为空,脚本报"key not found"

两种类型引用语法不同,混用取空

Secrets用 ${{ secrets.X }},Variables用 ${{ vars.X }};Variables需在YAML中显式export

3

git push报403

fatal: The requested URL returned error: 403

阿里内网不支持 oauth2:TOKEN 格式

必须用 https://用户名:PAT@code.alibaba-inc.com/repo.git\ 格式

4

uses:组件看不到前面装的工具

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 切个人分支执行

7

cron时间差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

10

run:多行语法报错

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.py

ODPS SQL执行 + Qwen prompt组装 + Markdown生成

daily-report/md_to_html.py

Markdown → 自包含HTML转换

daily-report/notifier.py

钉钉Webhook推送(加签 + 精简格式)

daily-report/publish_html.py

HTML推送到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工具实践中的真实故事。

千问云-Agent而生,驱动AI生产力
扫描下方二维码,直达千问云体验

点击阅读原文即可体验!

53AI,企业落地大模型首选服务商

产品:场景落地咨询+大模型应用平台+行业解决方案

承诺:免费POC验证,效果达标后再合作。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

添加专属顾问

回到顶部

加载中...

扫码咨询