用 AI 把一个纯前端作品发布到华为云开发者作品展览馆:完整流程与三个坑
上周把一个自己写的小工具发布到了华为云「开发者作品展览馆」,从生成作品到看到作品详情页上线,前后大概四十分钟,中间踩了三个坑。这篇把流程和坑一起记下来,给准备走同样流程的人省点时间。
一、这个流程到底在做什么
展览馆的提交指南写得很清楚,只有三步:
- 生成并验收作品
- 发布作品(安装发布 Skill,然后在对话里发出发布口令)
- 分享到朋友圈
看起来像点几个按钮,实际第二步是最重的:它要求作品有一个公开的 Git 仓库,发布时还要上传封面和一份详情包。也就是说,作品不能只是本地一个文件夹。
我做的作品叫 Dev Workbench,是一个开发者每日工作台,把待办、打卡、学习进度、记账和灵感笔记放在同一页,纯 HTML/CSS/JS,没有框架也没有构建步骤,数据存在浏览器 localStorage。选它是因为它天生适合发布:静态页面,任何静态服务器都能跑,截图也好看。
二、第一步:发布 Skill 装好之后先别急着跑
提交指南会给一条安装命令,大意是用 npx skills add 从 GitCode 仓库拉一个叫 huawei-cloud-publish-work-to-gallery 的 Skill。这条命令本身没问题,装完会在项目里生成 .agents/skills/ 目录。
坑一:脚本带 CRLF 换行。
装完直接执行脚本,报错是这样的:
/usr/bin/env: 'node\r': No such file or directory
原因很简单:从仓库拉下来的 .mjs、.sh、.py 文件是 CRLF 换行,shebang 那一行结尾多了个 \r,Linux 就把它当成解释器名字的一部分去找,自然找不到。
修法不复杂,把脚本目录下的文件统一转成 LF 就行,或者显式用 node xxx.mjs 调用。我选择了批量转换,因为后面几十个脚本都会用到。
装 Skill 的时候还有一个细节值得提醒:这类 Skill 会以完整 agent 权限运行,装完最好扫一眼它到底调了哪些接口、传了哪些凭证,再决定要不要用。
三、第二步:凭证从哪来
发布接口走的是华为云 STS 临时凭证,通过三个请求头传:X-Tmp-Ak、X-Tmp-Sk、X-Security-Token。网关会用这三个值解析调用方身份,再注入账号 ID 给服务端记录作者。
整套机制是「自委托」:先创建一条指向自己账号的委托 SELF_VERIFY,再通过 AssumeAgency 拿到 900 秒有效的最小权限临时凭证。永久 AK/SK 始终留在本地,不上传。
坑二:凭证会过期,而完整流程可能超过 900 秒。
第一次跑的时候我没注意时效。字体安装、Chromium 下载、多页截图、封面合成、详情包打包,这一串下来很容易超过十五分钟。等真正调发布接口时,临时凭证已经失效。
好在凭证文件里可以带 _refresh 元数据,接口返回 401 时脚本能自动重新 AssumeAgency 刷新一次。但要让它工作,本地的 hcloud 配置必须仍然有效——如果刷新时用的凭证也过期了,自动刷新同样会失败。
所以稳妥的做法是:在调发布接口之前,重新生成一次 STS,把有效窗口压到最后几分钟。
四、第三步:封面和详情包,两个硬门禁
发布前有两道门禁,任何一道不过都不让发。
封面必须是 16:9 的 PNG,而且要做字形校验。校验方式比较特别:不是看图片能不能打开,而是读 PNG 里内嵌的文字边界元数据,判断有没有出现「豆腐块」(字体缺失导致的方框乱码)。我一开始觉得这道门禁有点多余,直到看到有人用没装中文字体的容器截图,封面标题全是方块。
详情包是 zip,结构固定:根目录一个 README.md,加一个 resources/ 放图。内容要求 500 到 1500 字,至少要有一张系统架构图。打包脚本会顺手做一次服务端同源校验,避免上传后才发现结构不对。
坑三:预检脚本把「下载慢」误判成「下载卡死」。
预检要装 Chromium 和中文字体。脚本会依次探测几个镜像源,每个源给 20 秒,20 秒没看到进度就换下一个。我这边网络到镜像源其实不慢,单线程 curl 五秒多就能把整个包拉完,但脚本的进度检测方式没识别出来,四个源全被判成卡死,预检直接失败。
绕过办法是手动下载 Chromium 包,解压到 Playwright 期望的缓存目录,补上 INSTALLATION_COMPLETE 标记,再重跑预检。重跑之后一切正常,两分钟就过了。
五、第四步:仓库和发布
作品放在一个公开 GitCode 仓库里,分支 master。发布时填的参数一共十来个:仓库地址、分支、作品名、简介(15 到 50 字符)、封面路径、详情包路径、活动 ID,加上三个 STS 凭证字段。
有一个幂等键值得提一下:格式是 gallery-publish-<账号ID>-<时间戳>。重复提交同样的内容会返回 409,这时要么放弃,要么改名重发——注意改名之后封面也得重新生成,因为封面标题是画在图上的,旧封面配新名字会很尴尬。
发布成功后接口返回 201,带三个关键值:作品 ID、作品地址、积分结果。我这次的积分结果是 success、200。这里有个容易误会的点:发布作品积分每月只能领一次,当月重复发布接口依然返回成功,但不会实际加分。所以看到 success 不能直接断定积分到账,得去成长中心看明细。
六、最后一步不是技术活
流程的第三步是把作品分享到朋友圈。这一步没法自动化,得本人在作品详情页点「分享作品」,电脑端出二维码扫码,手机端复制链接粘贴到微信。
我一开始以为这一步也和发布一样能交给工具做,结果发现整个流程里只有这一步必须是人来做,而且它恰好是最容易被忽略的一步——作品已经上线了,但任务清单里还差这一项。
七、复盘
整条链路的技术含量其实不高,难的是每个环节都有前置条件,而且报错信息未必指向真实原因。三个坑里,CRLF 和预检误判都属于「环境准备」问题,凭证过期属于「时序」问题,它们共同的特点是:单看报错完全想不到原因,得对着脚本读一遍逻辑。
如果让我给一个建议,那就是把发布时间窗口压缩到最小:作品、仓库、封面、详情包全部准备好,最后再一次性生成凭证、调接口。中间每一步都可以提前验证,只有凭证这一步必须卡在最后。
- 点赞
- 收藏
- 关注作者
评论(0)