Files
session-delete/.gitea/workflows/publish.yml
T
pyh c842cd0118 docs(ci): describe the job token honestly instead of promising it
The first run failed with E401 while using the built-in token and before the workflow declared permissions, so nothing here proves the job token cannot publish. The header now says a write:package token is what makes publishing reliable, that the job token depends on the instance's Actions token settings, and that permissions: packages: write is what keeps a restricted token from being read-only.
2026-09-30 14:14:55 +08:00

120 lines
5.4 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 把打了 v* 标签的版本发布到 Gitea 的 npm 包仓库。
#
# 触发方式:
# 1. 推送版本标签(推荐):git tag -a v1.0.1 -m "..." && git push origin v1.0.1
# 2. 仓库 → Actions → 选择本工作流 → Run workflow(手动,发布当前 ref 的版本)
#
# 本工作流刻意不使用任何 `uses:` 外部 action:runner 在中国大陆访问 github.com 往往超时
# (表现为所有步骤 cancelled,日志里是 dial tcp ...:443: i/o timeout),而 checkout 只是
# git fetch、Node 本来就在 runner 镜像里。这样工作流只依赖本实例的 git 与镜像自带的 node。
#
# 已发布的版本不会让工作流失败:注册表返回 409(version already exists)时这一步记为
# “已存在,本次跳过”,所以手动重跑同一个版本是安全的。
#
# 需要的凭据:
# 发包需要一个「对目标包命名空间有写权限」的令牌。工作流优先用 secret NPM_TOKEN
# (个人访问令牌,权限勾 write:package;仓库级或组织级 secret 均可),没配才退回
# 内置任务令牌 ${{ secrets.GITEA_TOKEN }}。
# 内置任务令牌能否发包,取决于实例/组织 Settings → Actions 的令牌权限(permissive 还是
# restricted,以及上限),以及该令牌是否覆盖目标的包命名空间;Gitea 文档只承诺它访问
# “本仓库”。因此**想稳定发布就配 NPM_TOKEN**,除非你实测过本实例的内置令牌可用。
# 工作流已声明 permissions: packages: write —— 没有这行时,restricted 模式下令牌是只读的。
#
# 依赖前提:
# - 实例启用了 Actions 并注册了 act_runner;runs-on 的标签要与 runner 一致。
# - runner 镜像里要有 node 与 npm(Gitea 官方 runner-images 自带)。
# - 包名、`cordis.patch.yml` 的 name、客户端模块 id 三处必须一致,改名时别漏。
name: publish
on:
push:
tags:
- 'v*'
workflow_dispatch:
# 读取代码用于检出,向本组织写包。
permissions:
contents: read
packages: write
jobs:
npm:
runs-on: ubuntu-latest
env:
REGISTRY: https://gitea.iwake.top/api/packages/dsh-plugin/npm/
steps:
- name: Check out the pushed ref
run: |
set -eu
url="${GITHUB_SERVER_URL:-https://gitea.iwake.top}/${GITHUB_REPOSITORY:-dsh-plugin/session-delete}.git"
echo "从 ${url} 检出 ${GITHUB_REF}"
git init -q .
git remote add origin "${url}"
git fetch -q --depth 1 origin "${GITHUB_REF}"
git checkout -q FETCH_HEAD
git log --oneline -1
- name: Show the toolchain
run: |
set -eu
node -v
npm -v
- name: Read and check the version
id: version
run: |
set -eu
version="$(node -p "require('./package.json').version")"
name="$(node -p "require('./package.json').name")"
case "${GITHUB_REF}" in
refs/tags/*)
tag="${GITHUB_REF_NAME#v}"
if [ "$tag" != "$version" ]; then
echo "标签 ${GITHUB_REF_NAME} 与 package.json 的版本 ${version} 不一致" >&2
exit 1
fi
;;
esac
echo "name=${name}" >> "${GITHUB_OUTPUT}"
echo "version=${version}" >> "${GITHUB_OUTPUT}"
echo "目标:${name}@${version}"
- name: Pack (preview the published contents)
run: npm pack --dry-run
- name: Publish
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
JOB_TOKEN: ${{ secrets.GITEA_TOKEN }}
run: |
set -eu
token="${NPM_TOKEN:-$JOB_TOKEN}"
if [ -z "$token" ]; then
echo "没有可用的发布令牌:请配置 NPM_TOKEN,或确认实例会注入 GITEA_TOKEN" >&2
exit 1
fi
# 作用域与默认注册表都指向本组织的 npm 仓库(默认注册表也要设,否则 npm 会拿
# registry.npmjs.org 的 packument 做“是否已发布”判断,甚至可能发错地方),
# 并把令牌写进本机 .npmrc。
# 注意:npm 不允许用 `npm config get` 读回 _authToken(会报 protected),所以不打印它。
npm config set registry "${REGISTRY}"
npm config set @dsh-plugin:registry "${REGISTRY}"
npm config set "//gitea.iwake.top/api/packages/dsh-plugin/npm/:_authToken" "${token}"
echo "registry = $(npm config get registry)"
# 已发布的版本由注册表自己判定:Gitea 对同版本返回 409(package version already
# exists),npm 客户端在本地也会用 "cannot publish over the previously published
# versions" 拦下来。两种都算“本次无需发布”而不是失败;其余错误(E401/E403 等)照旧失败。
set +e
output="$(npm publish --registry "${REGISTRY}" --access public 2>&1)"
status=$?
set -e
printf '%s\n' "${output}"
if [ "${status}" -eq 0 ]; then
echo "已发布 ${{ steps.version.outputs.name }}@${{ steps.version.outputs.version }}"
elif printf '%s' "${output}" | grep -Eqi 'E409|already exists|previously published|cannot publish over'; then
echo "${{ steps.version.outputs.name }}@${{ steps.version.outputs.version }} 已存在,本次跳过(不算失败)"
else
exit "${status}"
fi