21 Commits

Author SHA1 Message Date
windychen 35e0152815 chore: 版本 1.1.13 更新
Node.js Build / build (push) Successful in 8s
2026-08-06 14:08:21 +08:00
windychen 53ea848582 fix(ci): Gitea npm 发布改用 _auth(兼容 npm 10+)
Node.js Build / build (push) Has been skipped
2026-08-06 14:08:18 +08:00
windychen a9b04b6960 chore: 版本 1.1.13 更新
Node.js Build / build (push) Failing after 46s
2026-08-06 14:06:20 +08:00
windychen 67a8c79dbd fix(ci): checkout 私有仓库添加 Basic Auth 认证
Node.js Build / build (push) Has been skipped
2026-08-06 14:06:08 +08:00
windychen 1a720443db chore: 版本 1.1.13 更新
Node.js Build / build (push) Failing after 18m26s
2026-08-06 13:58:41 +08:00
windychen 3686f1d03f docs: 添加 runner 自主维护 docker-compose 配置指南
Node.js Build / build (push) Has been skipped
2026-08-06 11:25:57 +08:00
windychen f003c4367e fix(ci): 修正 healthz grep 匹配 + Verdaccio 降级为 warn
Node.js Build / build (push) Has been skipped
2026-08-06 11:25:50 +08:00
windychen d3945d7234 fix(ci): runner 维护直接硬编码 HTTPS URL
Node.js Build / build (push) Has been skipped
2026-08-06 11:24:15 +08:00
windychen 52e9dd5561 fix(ci): runner 维护 workflow 硬编码外网/内网服务地址
Node.js Build / build (push) Has been skipped
2026-08-06 11:23:54 +08:00
windychen e20d8e47ce fix(ci): runner 维护使用外网 URL + 内网 IP 回退
Node.js Build / build (push) Has been skipped
2026-08-06 11:23:19 +08:00
windychen 468cf69d60 fix(ci): runner 维护 workflow 使用默认镜像并动态安装 curl
Node.js Build / build (push) Has been skipped
2026-08-06 11:22:01 +08:00
windychen b895d62260 fix(ci): runner 维护 workflow 使用 alpine 镜像并安装 curl
Node.js Build / build (push) Has been skipped
2026-08-06 11:21:09 +08:00
windychen 8aa417989e feat(ci): 添加 runner 自主维护 workflow(每6小时健康检查)
Node.js Build / build (push) Has been skipped
2026-08-06 11:20:41 +08:00
windychen 3d8bee740c fix: 仓库重命名后更新 workflow 引用 + runner 自主维护
Node.js Build / build (push) Has been skipped
2026-08-06 11:20:30 +08:00
windychen fc7dc5ff4d fix(ci): 修正仓库名与 Gitea 认证方式,适配 runner
Node.js Build / build (push) Has been skipped
2026-08-06 11:20:26 +08:00
windychen f3d2b3ff7e chore: workflow 版本 fix pipefail + step outputs 更新 2026-07-21 00:19:34 +08:00
windychen 9b4a9ea97d chore: fix grep pipefail 版本 更新 2026-07-21 00:16:40 +08:00
windychen 9223f3c5ff chore: bump 版本 to 1.1.10 更新 2026-07-21 00:13:31 +08:00
windychen 3be193f8c4 chore: bump 版本 to 1.1.9 更新 2026-07-21 00:10:41 +08:00
windychen d6d06e90a6 fix: Gitea 版本检查改用 packages API,Release 增加去重 2026-07-16 14:30:54 +08:00
windychen ed4f144e26 chore: 更新小版本发布流程,CI 新增自动创建 Gitea Release 2026-07-16 14:29:36 +08:00
5 changed files with 225 additions and 55 deletions
+62
View File
@@ -0,0 +1,62 @@
# Gitea Runner 自主维护配置指南
## 当前状态
- Runner 名称: gitea-runner (online, label: docker)
- 维护 workflow: `.gitea/workflows/runner-maintenance.yaml` (每 6 小时 + 手动触发)
## 宿主机 docker-compose 推荐配置
在 fnOS 上找到 gitea-runner 的 compose 文件,确保包含以下配置:
```yaml
services:
gitea:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/api/healthz"]
interval: 10s
retries: 3
start_period: 30s
timeout: 10s
gitea-runner:
image: gitea/act_runner:latest
container_name: gitea-runner
restart: unless-stopped
depends_on:
gitea:
condition: service_healthy
restart: true
volumes:
- ./runner-data:/data
- /var/run/docker.sock:/var/run/docker.sock
environment:
- GITEA_INSTANCE_URL=https://gitea.windychen00n.work
- GITEA_RUNNER_JOB_CONTAINER_NETWORK=<gitea所在docker网络名>
# 首次注册时需要,之后可删除
# - GITEA_RUNNER_REGISTRATION_TOKEN=<token>
networks:
- <gitea所在docker网络名>
networks:
<gitea所在docker网络名>:
external: true
```
## 查找 docker 网络名
在 fnOS SSH 执行:
```bash
docker inspect gitea --format "{{range $k,$v := .NetworkSettings.Networks}}{{$k}}{{end}}"
docker inspect gitea-runner --format "{{range $k,$v := .NetworkSettings.Networks}}{{$k}}{{end}}"
```
将 `GITEA_RUNNER_JOB_CONTAINER_NETWORK` 设为 gitea 容器所在的网络名,
这样 CI job 容器才能通过 `http://gitea:3000` 和 `http://verdaccio:4873` 访问内网服务。
## 应用后验证
```bash
docker compose up -d gitea-runner
```
然后在 Gitea 页面手动触发 "Runner Self-Maintenance" workflow,应全部通过。
+61 -27
View File
@@ -10,10 +10,13 @@ jobs:
runs-on: docker
steps:
- name: Checkout code
env:
GIT_AUTH: ${{ secrets.CI_USER }}:${{ secrets.CI_PASSWORD }}
run: |
git init
git remote add origin http://gitea:3000/windychen/windyChenUtils.git
git fetch --depth 1 origin ${{ github.sha }}
git remote add origin http://gitea:3000/windychen/windychen-utils.git
AUTH_B64=$(printf '%s' "$GIT_AUTH" | base64 | tr -d '\n')
git -c http.extraHeader="Authorization: Basic ${AUTH_B64}" fetch --depth 1 origin ${{ github.sha }}
git checkout ${{ github.sha }}
- name: Setup npm for Verdaccio
@@ -34,61 +37,92 @@ jobs:
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://verdaccio:4873/windychen-utils/$VERSION)
if [ "$HTTP_CODE" = "200" ]; then
echo "Verdaccio: version $VERSION already exists, skipping."
echo "Verdaccio|skipped|版本 ${VERSION} 已存在" > /tmp/publish_result.txt
echo "verdaccio_result=skipped|版本 ${VERSION} 已存在" >> $GITHUB_OUTPUT
else
if npm publish 2>&1; then
echo "Verdaccio|published|已发布 v${VERSION}" > /tmp/publish_result.txt
echo "verdaccio_result=published|已发布 v${VERSION}" >> $GITHUB_OUTPUT
else
echo "Verdaccio|failed|发布失败" > /tmp/publish_result.txt
echo "verdaccio_result=failed|发布失败" >> $GITHUB_OUTPUT
exit 1
fi
fi
- name: Publish to Gitea
id: publish-gitea
env:
GITEA_NPM_AUTH: ${{ secrets.CI_USER }}:${{ secrets.NPM_GITEA_TOKEN }}
run: |
npm config set //gitea:3000/api/packages/windychen/npm/:_authToken ${{ secrets.NPM_GITEA_TOKEN }}
AUTH_B64=$(printf '%s' "$GITEA_NPM_AUTH" | base64 | tr -d '\n')
npm config set //gitea:3000/api/packages/windychen/npm/:_auth "$AUTH_B64"
VERSION=$(node -p "require('./package.json').version")
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://gitea:3000/api/packages/windychen/npm/windychen-utils/$VERSION)
if [ "$HTTP_CODE" = "200" ]; then
EXISTS=$(curl -s "http://gitea:3000/api/v1/packages/windychen?q=windychen-utils" -u "${{ secrets.CI_USER }}:${{ secrets.CI_PASSWORD }}" | grep -c "\"version\":\"$VERSION\"" || true)
if [ "$EXISTS" -gt 0 ]; then
echo "Gitea: version $VERSION already exists, skipping."
echo "Gitea|skipped|版本 ${VERSION} 已存在" >> /tmp/publish_result.txt
echo "gitea_result=skipped|版本 ${VERSION} 已存在" >> $GITHUB_OUTPUT
else
if npm publish --registry http://gitea:3000/api/packages/windychen/npm/ 2>&1; then
echo "Gitea|published|已发布 v${VERSION}" >> /tmp/publish_result.txt
echo "gitea_result=published|已发布 v${VERSION}" >> $GITHUB_OUTPUT
else
echo "Gitea|failed|发布失败" >> /tmp/publish_result.txt
echo "gitea_result=failed|发布失败" >> $GITHUB_OUTPUT
exit 1
fi
fi
- name: Create Gitea Release
if: always() && steps.publish-gitea.outcome == 'success'
run: |
VERSION=$(node -p "require('./package.json').version")
EXISTS=$(curl -s "http://gitea:3000/api/v1/repos/windychen/windychen-utils/releases/tags/v${VERSION}" -u "${{ secrets.CI_USER }}:${{ secrets.CI_PASSWORD }}" | grep -c "\"tag_name\"" || true)
if [ "$EXISTS" = "0" ]; then
curl -s -X POST \
"http://gitea:3000/api/v1/repos/windychen/windychen-utils/releases" \
-u "${{ secrets.CI_USER }}:${{ secrets.CI_PASSWORD }}" \
-H "Content-Type: application/json" \
-d "{\"tag_name\":\"v${VERSION}\",\"name\":\"v${VERSION}\",\"body\":\"## windychen-utils v${VERSION}\n\n- 发布到 Verdaccio\n- 发布到 Gitea Packages\",\"target_commitish\":\"main\"}"
else
echo "Release v${VERSION} already exists, skipping."
fi
- name: Notify DingTalk
if: always()
run: |
STATUS="${{ job.status }}"
VERSION=$(node -p "require('./package.json').version")
parse_result() {
local raw="$1"
local target="$2"
local icon="${raw%%|*}"
local detail="${raw#*|}"
case "$icon" in
published) echo "📦 ${target}: ${detail}" ;;
skipped) echo "⏭️ ${target}: ${detail}" ;;
failed) echo "❌ ${target}: ${detail}" ;;
*) echo "⚠️ ${target}: ${detail}" ;;
esac
}
VERD_RESULT="${{ steps.publish-verdaccio.outputs.verdaccio_result }}"
GITEA_RESULT="${{ steps.publish-gitea.outputs.gitea_result }}"
if [ -n "$VERD_RESULT" ]; then
VERD_LINE=$(parse_result "$VERD_RESULT" "Verdaccio")
else
VERD_LINE="⚠️ Verdaccio: 未执行"
GITEA_LINE="⚠️ Gitea: 未执行"
if [ -f /tmp/publish_result.txt ]; then
while IFS='|' read -r TARGET ICON DETAIL; do
case "$ICON" in
published) EMOJI="📦" ;;
skipped) EMOJI="⏭️" ;;
failed) EMOJI="❌" ;;
*) EMOJI="⚠️" ;;
esac
LINE="${EMOJI} ${TARGET}: ${DETAIL}"
case "$TARGET" in
Verdaccio) VERD_LINE="$LINE" ;;
Gitea) GITEA_LINE="$LINE" ;;
esac
done < /tmp/publish_result.txt
fi
if [ -n "$GITEA_RESULT" ]; then
GITEA_LINE=$(parse_result "$GITEA_RESULT" "Gitea")
else
GITEA_LINE="⚠️ Gitea: 未执行"
fi
if [ "$STATUS" = "success" ]; then
TITLE="✅ windychen-utils v${VERSION} 构建完成 chen-fnos"
else
TITLE="❌ windychen-utils v${VERSION} 构建失败 chen-fnos"
fi
curl -s -X POST "https://oapi.dingtalk.com/robot/send?access_token=${{ secrets.DINGDING_TOKEN }}" \
-H "Content-Type: application/json" \
-d "{\"msgtype\":\"markdown\",\"markdown\":{\"title\":\"${TITLE}\",\"text\":\"## ${TITLE}\n\n${VERD_LINE}\n${GITEA_LINE}\n\n- 仓库: windychen/windyChenUtils\n- 分支: ${{ github.ref_name }}\n- 提交: ${{ github.sha }}\"}}"
-d "{\"msgtype\":\"markdown\",\"markdown\":{\"title\":\"${TITLE}\",\"text\":\"## ${TITLE}\n\n${VERD_LINE}\n${GITEA_LINE}\n\n- 仓库: windychen/windychen-utils\n- 分支: ${{ github.ref_name }}\n- 提交: ${{ github.sha }}\"}}"
+72
View File
@@ -0,0 +1,72 @@
name: Runner Self-Maintenance
on:
schedule:
- cron: "0 */6 * * *"
workflow_dispatch:
jobs:
health-check:
runs-on: docker
steps:
- name: Install tools
run: |
if command -v apk >/dev/null 2>&1; then
apk add --no-cache curl grep
elif command -v apt-get >/dev/null 2>&1; then
apt-get update -qq && apt-get install -y -qq curl grep
else
echo "No supported package manager"; exit 1
fi
- name: Check Gitea health
id: gitea
run: |
BODY=$(curl -sf --connect-timeout 15 "https://gitea.windychen00n.work/api/healthz")
if echo "$BODY" | grep -qE '"status"[[:space:]]*:[[:space:]]*"pass"'; then
echo "result=ok|Gitea 健康检查通过" >> $GITHUB_OUTPUT
else
echo "result=fail|Gitea 健康检查失败" >> $GITHUB_OUTPUT
echo "$BODY" | head -3
exit 1
fi
- name: Check Verdaccio health
id: verdaccio
continue-on-error: true
run: |
if curl -sf --connect-timeout 5 "http://172.172.2.4:4873/-/ping" >/dev/null 2>&1; then
echo "result=ok|Verdaccio 内网可达" >> $GITHUB_OUTPUT
elif curl -sf --connect-timeout 5 "http://verdaccio:4873/-/ping" >/dev/null 2>&1; then
echo "result=ok|Verdaccio DNS 可达" >> $GITHUB_OUTPUT
else
echo "result=warn|Verdaccio 内网不可达(需配置 runner job 网络)" >> $GITHUB_OUTPUT
fi
- name: Check runner registration
id: runner
run: |
RESP=$(curl -sf --connect-timeout 15 -u "${{ secrets.CI_USER }}:${{ secrets.CI_PASSWORD }}" \
"https://gitea.windychen00n.work/api/v1/admin/actions/runners")
ONLINE=$(echo "$RESP" | grep -c '"status":"online"' || true)
if [ "${ONLINE:-0}" -ge 1 ]; then
NAME=$(echo "$RESP" | grep -o '"name":"[^"]*"' | head -1 | cut -d'"' -f4)
echo "result=ok|Runner ${NAME} 在线 (${ONLINE} 个)" >> $GITHUB_OUTPUT
else
echo "result=fail|无在线 Runner" >> $GITHUB_OUTPUT
exit 1
fi
- name: Notify DingTalk on failure
if: failure()
run: |
curl -s -X POST "https://oapi.dingtalk.com/robot/send?access_token=${{ secrets.DINGDING_TOKEN }}" \
-H "Content-Type: application/json" \
-d '{"msgtype":"markdown","markdown":{"title":"❌ Gitea Runner 自主维护告警 chen-fnos","text":"## ❌ Gitea Runner 自主维护告警 chen-fnos\n\n- Gitea: ${{ steps.gitea.outputs.result }}\n- Verdaccio: ${{ steps.verdaccio.outputs.result }}\n- Runner: ${{ steps.runner.outputs.result }}\n\n请检查 gitea-runner 容器"}}'
- name: Notify DingTalk on success
if: success()
run: |
curl -s -X POST "https://oapi.dingtalk.com/robot/send?access_token=${{ secrets.DINGDING_TOKEN }}" \
-H "Content-Type: application/json" \
-d '{"msgtype":"markdown","markdown":{"title":"✅ Gitea Runner 自主维护正常 chen-fnos","text":"## ✅ Gitea Runner 自主维护正常 chen-fnos\n\n- Gitea: ${{ steps.gitea.outputs.result }}\n- Verdaccio: ${{ steps.verdaccio.outputs.result }}\n- Runner: ${{ steps.runner.outputs.result }}"}}'
+2
View File
@@ -99,3 +99,5 @@ npm test # 运行测试
## License
ISC
<!-- ci-test-marker -->
<!-- ci-test-marker-3 -->
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "windychen-utils",
"version": "1.1.8",
"version": "1.1.13",
"main": "dist/windychen-utils.cjs.js",
"module": "dist/windychen-utils.esm.js",
"browser": "dist/windychen-utils.js",