Skip to content

Commit a130535

Browse files
authored
Merge pull request #1 from FinMind/ci/pypi-publish
ci: GitHub Actions CI + PyPI 自動發佈(推 tag 觸發,OIDC)
2 parents d755453 + f7e5818 commit a130535

2 files changed

Lines changed: 114 additions & 0 deletions

File tree

.github/workflows/ci.yml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [master]
6+
pull_request:
7+
8+
# 只跑離線檢查(pytest 全 mock、smoke 用假 token、build_instructions 純本地)。
9+
# regression/runner.py 會打 live API、需要 FINMIND_TOKEN,故不放 CI,由發版前人工跑。
10+
11+
jobs:
12+
test:
13+
runs-on: ubuntu-latest
14+
strategy:
15+
fail-fast: false
16+
matrix:
17+
python-version: ["3.10", "3.11", "3.12"]
18+
steps:
19+
- uses: actions/checkout@v4
20+
21+
- name: Install uv
22+
uses: astral-sh/setup-uv@v5
23+
with:
24+
python-version: ${{ matrix.python-version }}
25+
enable-cache: true
26+
27+
- name: Install dependencies
28+
run: uv sync --extra dev
29+
30+
- name: Unit tests (mocked, offline)
31+
run: uv run pytest -q
32+
33+
- name: Stdio smoke test
34+
run: uv run python smoke.py
35+
36+
- name: ChatGPT instructions build (must stay under the 8000-char Action limit)
37+
run: uv run python chatgpt/build_instructions.py

.github/workflows/publish.yml

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
name: Publish to PyPI
2+
3+
# 推一個新的版本 tag(vX.Y.Z)就自動 build + 上傳 PyPI(也可手動 workflow_dispatch)。
4+
# 用 PyPI Trusted Publishing(OIDC)—— 不需要存任何 API token / secret。
5+
#
6+
# 一次性設定(使用者在 PyPI 端做,我做不了):
7+
# 1. https://pypi.org/manage/account/publishing/ → Add a new pending publisher
8+
# PyPI Project Name: finmind-mcp
9+
# Owner: FinMind
10+
# Repository name: FinMind-MCP
11+
# Workflow name: publish.yml
12+
# Environment name: pypi
13+
# (專案還沒上 PyPI 沒關係,用 "pending publisher",第一次發版會自動建立專案)
14+
# 2. GitHub repo → Settings → Environments → 新增名為 `pypi` 的 environment
15+
# (名稱要跟上面 PyPI 設定一致;可另設保護規則,例如限定 reviewer 才能發版)
16+
#
17+
# 發版流程(tag 驅動):
18+
# - 先把 pyproject.toml 的 version bump 好(PyPI 版本號不可重複)
19+
# - git tag vX.Y.Z(要跟 version 一致,下方 job 會檢查)
20+
# - git push origin vX.Y.Z ← 推 tag 就觸發本 workflow,自動 build → 上傳 PyPI
21+
22+
on:
23+
push:
24+
tags:
25+
- "v[0-9]*" # vX.Y.Z
26+
- "[0-9]*" # 也接受沒有 v 前綴的 X.Y.Z
27+
workflow_dispatch:
28+
29+
jobs:
30+
build:
31+
runs-on: ubuntu-latest
32+
steps:
33+
- uses: actions/checkout@v4
34+
35+
- name: Install uv
36+
uses: astral-sh/setup-uv@v5
37+
38+
- name: Verify pushed tag matches pyproject version
39+
if: startsWith(github.ref, 'refs/tags/')
40+
run: |
41+
VERSION=$(grep -m1 '^version' pyproject.toml | sed -E 's/.*"(.*)".*/\1/')
42+
TAG="${GITHUB_REF_NAME#v}"
43+
echo "pyproject version: $VERSION pushed tag: $TAG"
44+
if [ "$VERSION" != "$TAG" ]; then
45+
echo "::error::pushed tag ($TAG) does not match pyproject version ($VERSION). Bump the version or fix the tag."
46+
exit 1
47+
fi
48+
49+
- name: Build sdist + wheel
50+
run: uv build
51+
52+
- name: Check distribution metadata
53+
run: uvx twine check dist/*
54+
55+
- name: Upload build artifacts
56+
uses: actions/upload-artifact@v4
57+
with:
58+
name: dist
59+
path: dist/
60+
61+
pypi-publish:
62+
needs: build
63+
runs-on: ubuntu-latest
64+
environment:
65+
name: pypi
66+
url: https://pypi.org/project/finmind-mcp/
67+
permissions:
68+
id-token: write # OIDC token for PyPI Trusted Publishing — no password needed
69+
steps:
70+
- name: Download build artifacts
71+
uses: actions/download-artifact@v4
72+
with:
73+
name: dist
74+
path: dist/
75+
76+
- name: Publish to PyPI
77+
uses: pypa/gh-action-pypi-publish@release/v1

0 commit comments

Comments
 (0)