everkm-publish 0.16.15 → 0.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/publish-npm.yaml +154 -0
- package/Makefile +6 -0
- package/README-MAINTAINERS.md +61 -0
- package/README.md +13 -7
- package/install.js +151 -287
- package/package.json +7 -6
- package/requirements.txt +3 -0
- package/scripts/publish-npm-package.py +373 -0
- package/stuff/km/260613-Plan-everkm-publish-npm-/345/210/206/345/217/221/344/270/216/345/217/221/345/270/203.md +494 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
name: Publish NPM Package
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
inputs:
|
|
9
|
+
version:
|
|
10
|
+
description: "Semver,如 0.16.15"
|
|
11
|
+
required: true
|
|
12
|
+
type: string
|
|
13
|
+
skip_npm:
|
|
14
|
+
description: "仅上传 CDN,不 npm publish"
|
|
15
|
+
type: boolean
|
|
16
|
+
default: false
|
|
17
|
+
force_cdn:
|
|
18
|
+
description: "强制重传 CDN(忽略已存在)"
|
|
19
|
+
type: boolean
|
|
20
|
+
default: false
|
|
21
|
+
|
|
22
|
+
jobs:
|
|
23
|
+
publish:
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
outputs:
|
|
26
|
+
run_started_at: ${{ steps.record-start.outputs.run_started_at }}
|
|
27
|
+
skipped: ${{ steps.publish-run.outputs.skipped }}
|
|
28
|
+
version: ${{ steps.publish-run.outputs.version }}
|
|
29
|
+
|
|
30
|
+
steps:
|
|
31
|
+
- name: Checkout
|
|
32
|
+
uses: actions/checkout@v4
|
|
33
|
+
|
|
34
|
+
- id: record-start
|
|
35
|
+
run: echo "run_started_at=$(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "$GITHUB_OUTPUT"
|
|
36
|
+
|
|
37
|
+
- name: Setup Python
|
|
38
|
+
uses: actions/setup-python@v5
|
|
39
|
+
with:
|
|
40
|
+
python-version: "3.12"
|
|
41
|
+
|
|
42
|
+
- name: Install Python dependencies
|
|
43
|
+
run: pip install -r requirements.txt
|
|
44
|
+
|
|
45
|
+
- name: Setup qshell
|
|
46
|
+
uses: foxundermoon/setup-qshell@v5
|
|
47
|
+
with:
|
|
48
|
+
version: "2.16.0"
|
|
49
|
+
|
|
50
|
+
- id: ver
|
|
51
|
+
name: Resolve version
|
|
52
|
+
run: |
|
|
53
|
+
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
|
54
|
+
echo "version=${{ inputs.version }}" >> "$GITHUB_OUTPUT"
|
|
55
|
+
else
|
|
56
|
+
echo "version=${GITHUB_REF#refs/tags/v}" >> "$GITHUB_OUTPUT"
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
- id: publish-run
|
|
60
|
+
name: Mirror everkm/publish Release to CDN
|
|
61
|
+
env:
|
|
62
|
+
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
|
63
|
+
CF_S3_AK: ${{ secrets.CF_S3_AK }}
|
|
64
|
+
CF_S3_SK: ${{ secrets.CF_S3_SK }}
|
|
65
|
+
QINIU_ACCESS_KEY: ${{ secrets.QINIU_ACCESS_KEY }}
|
|
66
|
+
QINIU_SECRET_KEY: ${{ secrets.QINIU_SECRET_KEY }}
|
|
67
|
+
run: |
|
|
68
|
+
args=(--version "${{ steps.ver.outputs.version }}")
|
|
69
|
+
if [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ "${{ inputs.force_cdn }}" = "true" ]; then
|
|
70
|
+
args+=(--force-cdn)
|
|
71
|
+
fi
|
|
72
|
+
python scripts/publish-npm-package.py "${args[@]}"
|
|
73
|
+
code=$?
|
|
74
|
+
echo "version=${{ steps.ver.outputs.version }}" >> "$GITHUB_OUTPUT"
|
|
75
|
+
if [ "$code" -eq 2 ]; then
|
|
76
|
+
echo "skipped=true" >> "$GITHUB_OUTPUT"
|
|
77
|
+
exit 0
|
|
78
|
+
fi
|
|
79
|
+
exit "$code"
|
|
80
|
+
|
|
81
|
+
- name: Setup Node
|
|
82
|
+
if: steps.publish-run.outputs.skipped != 'true'
|
|
83
|
+
uses: actions/setup-node@v4
|
|
84
|
+
with:
|
|
85
|
+
node-version: "20"
|
|
86
|
+
registry-url: https://registry.npmjs.org
|
|
87
|
+
|
|
88
|
+
- name: Bump package.json version
|
|
89
|
+
if: steps.publish-run.outputs.skipped != 'true'
|
|
90
|
+
run: npm version "${{ steps.ver.outputs.version }}" --no-git-tag-version
|
|
91
|
+
|
|
92
|
+
- name: Publish to npm
|
|
93
|
+
if: |
|
|
94
|
+
steps.publish-run.outputs.skipped != 'true' &&
|
|
95
|
+
(github.event_name != 'workflow_dispatch' || inputs.skip_npm != true)
|
|
96
|
+
env:
|
|
97
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
98
|
+
run: npm publish --access public
|
|
99
|
+
|
|
100
|
+
notify:
|
|
101
|
+
runs-on: ubuntu-latest
|
|
102
|
+
needs: [publish]
|
|
103
|
+
if: always()
|
|
104
|
+
steps:
|
|
105
|
+
- name: Notify workflow run
|
|
106
|
+
env:
|
|
107
|
+
NOTIFY_DAYU_ENDPOINT: ${{ secrets.NOTIFY_DAYU_ENDPOINT }}
|
|
108
|
+
PUBLISH_RESULT: ${{ needs.publish.result }}
|
|
109
|
+
PUBLISH_SKIPPED: ${{ needs.publish.outputs.skipped }}
|
|
110
|
+
PUBLISH_VERSION: ${{ needs.publish.outputs.version }}
|
|
111
|
+
PUBLISH_TRIGGER: ${{ github.event_name }}
|
|
112
|
+
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
|
113
|
+
RUN_STARTED_AT: ${{ needs.publish.outputs.run_started_at }}
|
|
114
|
+
PYTHONIOENCODING: utf-8
|
|
115
|
+
run: |
|
|
116
|
+
if [ -z "$NOTIFY_DAYU_ENDPOINT" ]; then
|
|
117
|
+
echo "NOTIFY_DAYU_ENDPOINT secret not set, skip notify"
|
|
118
|
+
exit 0
|
|
119
|
+
fi
|
|
120
|
+
NOTIFY_URL="${NOTIFY_DAYU_ENDPOINT%/}/api/notify/tg"
|
|
121
|
+
python3 <<'PY' > /tmp/notify-payload.json
|
|
122
|
+
import json, os
|
|
123
|
+
from datetime import datetime, timezone
|
|
124
|
+
|
|
125
|
+
started_at = os.environ.get("RUN_STARTED_AT", "").strip()
|
|
126
|
+
if started_at:
|
|
127
|
+
start = datetime.fromisoformat(started_at.replace("Z", "+00:00"))
|
|
128
|
+
duration = "%.1f 分钟" % (
|
|
129
|
+
(datetime.now(timezone.utc) - start).total_seconds() / 60)
|
|
130
|
+
else:
|
|
131
|
+
duration = "未知"
|
|
132
|
+
|
|
133
|
+
ver = os.environ.get("PUBLISH_VERSION") or "未知"
|
|
134
|
+
trigger = os.environ.get("PUBLISH_TRIGGER", "")
|
|
135
|
+
result = os.environ["PUBLISH_RESULT"]
|
|
136
|
+
if os.environ.get("PUBLISH_SKIPPED") == "true":
|
|
137
|
+
result = "skipped(npm 与 CDN 均已就绪)"
|
|
138
|
+
|
|
139
|
+
b = (
|
|
140
|
+
"everkm-publish npm 发布工作流已完成。\n"
|
|
141
|
+
"总耗时:%s。\n"
|
|
142
|
+
"触发:%s\n"
|
|
143
|
+
"版本:%s\n"
|
|
144
|
+
"结果:%s\n"
|
|
145
|
+
"Action:%s"
|
|
146
|
+
) % (duration, trigger, ver, result, os.environ["RUN_URL"])
|
|
147
|
+
print(json.dumps({
|
|
148
|
+
"subject": "everkm-publish-npm Publish(%s)" % result,
|
|
149
|
+
"body": b,
|
|
150
|
+
}, ensure_ascii=False))
|
|
151
|
+
PY
|
|
152
|
+
curl --location "$NOTIFY_URL" \
|
|
153
|
+
-H 'Content-Type: application/json' \
|
|
154
|
+
--data-binary @/tmp/notify-payload.json
|
package/Makefile
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Maintainers
|
|
2
|
+
|
|
3
|
+
本仓库即 [`everkm/publish`](https://github.com/everkm/publish)(`everkm-publish-npm` 仅为本地/历史别名)。
|
|
4
|
+
|
|
5
|
+
## Release
|
|
6
|
+
|
|
7
|
+
1. **Binary Release** — tag 触发构建并发布 GitHub Release(含 notes):
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
git tag everkm-publish@v0.17.0
|
|
11
|
+
git push origin everkm-publish@v0.17.0
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
等待构建完成,确认 Release 资产与 notes。
|
|
15
|
+
|
|
16
|
+
2. **CDN + npm** — semver tag 触发 CDN 镜像与 npm publish:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
git tag v0.17.0
|
|
20
|
+
git push origin v0.17.0
|
|
21
|
+
|
|
22
|
+
# or via Makefile
|
|
23
|
+
make tag TAG=v0.17.0
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
3. Verify:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
curl -s https://ekmp-assets.everkm.com/pkgs/latest.json
|
|
30
|
+
npm view everkm-publish version
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Manual re-run: GitHub Actions → **Publish NPM Package** → `workflow_dispatch`.
|
|
34
|
+
|
|
35
|
+
## GitHub Secrets
|
|
36
|
+
|
|
37
|
+
| Secret | 用途 |
|
|
38
|
+
|--------|------|
|
|
39
|
+
| `CF_S3_AK` / `CF_S3_SK` | Cloudflare R2 上传 |
|
|
40
|
+
| `QINIU_ACCESS_KEY` / `QINIU_SECRET_KEY` | 七牛上传与 CDN 刷新 |
|
|
41
|
+
| `GH_TOKEN` | 读取同仓 GitHub Release(未设置时回退 `GITHUB_TOKEN`) |
|
|
42
|
+
| `NPM_TOKEN` | npm publish(见下) |
|
|
43
|
+
| `NOTIFY_DAYU_ENDPOINT` | workflow 结束 Telegram 通知(可选) |
|
|
44
|
+
|
|
45
|
+
### `NPM_TOKEN` 配置
|
|
46
|
+
|
|
47
|
+
CI 无法输入 authenticator 验证码;若账号启用了 2FA,token **必须**支持自动化发布,否则 `npm publish` 会报 `EOTP`。
|
|
48
|
+
|
|
49
|
+
在 [npmjs.com](https://www.npmjs.com) → **Access Tokens** 创建 **Granular Access Token**(或 Classic **Automation** token):
|
|
50
|
+
|
|
51
|
+
1. **Packages and scopes**:对 `everkm-publish` 授予 **Read and write**(或 all packages)
|
|
52
|
+
2. **Security settings**:勾选 **Bypass two-factor authentication (2FA)**
|
|
53
|
+
3. 若包归属 npm organization,还需在 **Organizations** 中授权对应 org
|
|
54
|
+
|
|
55
|
+
将 token 写入仓库 **Settings → Secrets → Actions → `NPM_TOKEN`**。更新后重新跑 workflow 即可。
|
|
56
|
+
|
|
57
|
+
本地验证 token:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npm whoami --registry=https://registry.npmjs.org/ --//registry.npmjs.org/:_authToken=YOUR_TOKEN
|
|
61
|
+
```
|
package/README.md
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
## Usage
|
|
2
2
|
|
|
3
|
-
Static Content Generator. Pure
|
|
4
|
-
HTML template engine base on markdown files, syntax from Jinja2. Built for
|
|
5
|
-
official website, Blog and WIKI, and so on.
|
|
6
|
-
Please to visit [Everkm Publish](https://publish.everkm.com) for more details。
|
|
3
|
+
Static Content Generator. Pure HTML template engine based on markdown files, syntax from Jinja2. Built for official website, Blog and WIKI, and so on.
|
|
7
4
|
|
|
8
|
-
|
|
5
|
+
Please visit [Everkm Publish](https://publish.everkm.com) for more details.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
9
8
|
|
|
10
9
|
```bash
|
|
11
|
-
|
|
10
|
+
npm add everkm-publish
|
|
11
|
+
# or
|
|
12
|
+
pnpm add everkm-publish
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
`postinstall` downloads the platform binary from CDN (`.com` → GitHub → `.cn`), with a 5s timeout per source.
|
|
16
|
+
|
|
17
|
+
---
|
|
12
18
|
|
|
13
|
-
|
|
19
|
+
Maintainers: see [README-MAINTAINERS.md](./README-MAINTAINERS.md).
|