55 branches :
66 - main
77 - beta
8+ tags :
9+ - " v*.*.*"
810 workflow_dispatch :
911 inputs :
1012 ref :
@@ -29,49 +31,47 @@ jobs:
2931
3032 - name : Python Semantic Release
3133 id : semantic
32- if : github.event_name == 'push'
34+ if : github.event_name == 'push' && !startsWith(github.ref, 'refs/tags/')
3335 uses : python-semantic-release/python-semantic-release@master
3436 with :
3537 github_token : ${{ secrets.GITHUB_TOKEN }}
3638
37- publish-npm :
38- needs : release
39- runs-on : ubuntu-latest
40- if : ((github.event_name == 'push' && needs.release.outputs.released == 'true') || github.event_name == 'workflow_dispatch') && hashFiles('package.json') != ''
41- steps :
42- - uses : actions/checkout@v4
43- with :
44- ref : ${{ inputs.ref || needs.release.outputs.tag || github.sha }}
45-
46- - name : Setup Node.js
47- uses : actions/setup-node@v4
48- with :
49- node-version : " 20"
50- registry-url : " https://registry.npmjs.org"
51-
52- - name : Publish to npm
53- env :
54- NODE_AUTH_TOKEN : ${{ secrets.NPM_TOKEN }}
55- run : npm publish --access public
56-
5739 publish-pypi :
5840 needs : release
5941 runs-on : ubuntu-latest
60- if : (github.event_name == 'push' && needs.release.outputs.released == 'true') || github.event_name == 'workflow_dispatch'
42+ if : >-
43+ (github.event_name == 'push' && (needs.release.outputs.released == 'true' || startsWith(github.ref, 'refs/tags/')))
44+ || github.event_name == 'workflow_dispatch'
6145 steps :
6246 - uses : actions/checkout@v4
6347 with :
64- ref : ${{ inputs.ref || needs.release.outputs.tag || github.sha }}
48+ ref : ${{ inputs.ref || needs.release.outputs.tag || github.ref }}
6549
6650 - name : Set up Python
6751 uses : actions/setup-python@v5
6852 with :
6953 python-version : " 3.11"
7054
71- # 按 CHANGELOG 刷新 docs/releases/ 下的版本说明(与仓库 scripts/、secbot_agent/ 结构无关,在仓库根目录执行即可)
55+ - name : Validate tag matches pyproject.toml version
56+ if : startsWith(github.ref, 'refs/tags/')
57+ run : |
58+ TAG_VERSION="${GITHUB_REF#refs/tags/v}"
59+ PKG_VERSION=$(python -c "
60+ import re
61+ with open('pyproject.toml') as f:
62+ m = re.search(r'version\s*=\s*\"([^\"]+)\"', f.read())
63+ print(m.group(1) if m else '')
64+ ")
65+ echo "Tag version: $TAG_VERSION"
66+ echo "Package version: $PKG_VERSION"
67+ if [ "$TAG_VERSION" != "$PKG_VERSION" ]; then
68+ echo "::error::Tag version ($TAG_VERSION) does not match pyproject.toml version ($PKG_VERSION)"
69+ exit 1
70+ fi
71+
7272 - name : Refresh versioned release docs
7373 run : |
74- python -m utils.release_docs version-docs --changelog CHANGELOG.md --output-dir docs/releases
74+ python -m utils.release_docs version-docs --changelog CHANGELOG.md --output-dir docs/releases || true
7575
7676 - name : Build package
7777 run : |
@@ -80,10 +80,57 @@ jobs:
8080 python -m build
8181 python -m twine check dist/*
8282
83- # 仓库 Settings → Secrets:PYPI_PASSWORD = PyPI 上创建的 API token 字符串(勿用 .pypirc)
8483 - name : Upload to PyPI
8584 env :
8685 TWINE_USERNAME : __token__
8786 TWINE_PASSWORD : ${{ secrets.PYPI_PASSWORD }}
8887 run : |
8988 python -m twine upload --non-interactive --skip-existing dist/*
89+
90+ - name : Determine prerelease
91+ id : prerelease
92+ run : |
93+ VERSION=$(python -c "
94+ import re
95+ with open('pyproject.toml') as f:
96+ m = re.search(r'version\s*=\s*\"([^\"]+)\"', f.read())
97+ print(m.group(1) if m else '')
98+ ")
99+ if echo "$VERSION" | grep -qE '[a-zA-Z]'; then
100+ echo "is_prerelease=true" >> "$GITHUB_OUTPUT"
101+ else
102+ echo "is_prerelease=false" >> "$GITHUB_OUTPUT"
103+ fi
104+
105+ - name : Upload to GitHub Release
106+ if : startsWith(github.ref, 'refs/tags/') || needs.release.outputs.released == 'true'
107+ uses : softprops/action-gh-release@v2
108+ with :
109+ tag_name : ${{ needs.release.outputs.tag || github.ref_name }}
110+ prerelease : ${{ steps.prerelease.outputs.is_prerelease }}
111+ files : dist/*
112+ env :
113+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
114+
115+ publish-npm :
116+ needs : release
117+ runs-on : ubuntu-latest
118+ if : >-
119+ ((github.event_name == 'push' && needs.release.outputs.released == 'true')
120+ || github.event_name == 'workflow_dispatch')
121+ && hashFiles('package.json') != ''
122+ steps :
123+ - uses : actions/checkout@v4
124+ with :
125+ ref : ${{ inputs.ref || needs.release.outputs.tag || github.sha }}
126+
127+ - name : Setup Node.js
128+ uses : actions/setup-node@v4
129+ with :
130+ node-version : " 20"
131+ registry-url : " https://registry.npmjs.org"
132+
133+ - name : Publish to npm
134+ env :
135+ NODE_AUTH_TOKEN : ${{ secrets.NPM_TOKEN }}
136+ run : npm publish --access public
0 commit comments