The registry check through npm view did not see the existing version, so publish ran into E409. The registry itself is the authority here: a 409 now reports 'already exists, skipping' and exits zero, while every other error still fails the step.
103 lines
4.1 KiB
YAML
103 lines
4.1 KiB
YAML
# 把打了 v* 标签的版本发布到 Gitea 的 npm 包仓库。
|
||
#
|
||
# 触发方式:
|
||
# 1. 推送版本标签(推荐):git tag -a v1.0.1 -m "..." && git push origin v1.0.1
|
||
# 2. 仓库 → Actions → 选择本工作流 → Run workflow(手动,发布当前 ref 的版本)
|
||
#
|
||
# 已发布的版本不会让工作流失败:注册表返回 409(version already exists)时这一步记为
|
||
# “已存在,本次跳过”,所以手动重跑同一个版本是安全的。
|
||
#
|
||
# 需要的权限:
|
||
# 默认使用 Gitea 内置的任务令牌 ${{ secrets.GITEA_TOKEN }} 发布。
|
||
# 若实例/组织把 Actions 的令牌上限设为只读,或任务令牌对包命名空间没有写权限,
|
||
# 就配置一个带 write:package 权限的个人访问令牌:
|
||
# 仓库(或组织)Settings → Actions → Secrets → NPM_TOKEN。工作流会自动优先使用它。
|
||
#
|
||
# 依赖前提:
|
||
# - 实例启用了 Actions 并注册了 act_runner;runs-on 的标签要与 runner 一致。
|
||
# - runner 需要能拉取 actions/checkout 与 actions/setup-node(默认从 github.com 取)。
|
||
# - 包名、`cordis.patch.yml` 的 name、客户端模块 id 三处必须一致,改名时别漏。
|
||
name: publish
|
||
|
||
on:
|
||
push:
|
||
tags:
|
||
- 'v*'
|
||
workflow_dispatch:
|
||
|
||
# 读取代码用于 checkout,向本组织写包。
|
||
permissions:
|
||
contents: read
|
||
packages: write
|
||
|
||
jobs:
|
||
npm:
|
||
runs-on: ubuntu-latest
|
||
env:
|
||
REGISTRY: https://gitea.iwake.top/api/packages/dsh-plugin/npm/
|
||
steps:
|
||
- name: Checkout
|
||
uses: actions/checkout@v4
|
||
|
||
- name: Set up Node.js
|
||
uses: actions/setup-node@v4
|
||
with:
|
||
node-version: '22'
|
||
registry-url: https://gitea.iwake.top/api/packages/dsh-plugin/npm/
|
||
|
||
- 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 仓库,并把令牌写进本机 .npmrc。
|
||
# 注意:npm 不允许用 `npm config get` 读回 _authToken(会报 protected),所以不打印它。
|
||
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)。把它当成"本次无需发布"而不是失败,手动重跑因此是安全的;
|
||
# 其他错误(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 -Eq 'E409|already exists'; then
|
||
echo "${{ steps.version.outputs.name }}@${{ steps.version.outputs.version }} 已存在,本次跳过(不算失败)"
|
||
else
|
||
exit "${status}"
|
||
fi
|
||
|