Repository navigation
181 lines (159 loc) · 5.5 KB
/
Copy pathrelease.yml
File metadata and controls
181 lines (159 loc) · 5.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
name: Release
# 版本标签 v* → 测包、发 PyPI、建 GitHub Release,再级联:
# - Sync Main Into Develop
# - Build Octop FPK(复用本 Release 的 wheel;等待 docker-publish 的 GHCR 镜像)
#
# 与 docker-publish.yml / octop-desktop.yml 并行(由 Auto Tag 同时 dispatch,
# 或人工 push v* tag 同时触发)。桌面产物由 Desktop Package 挂到同一 GitHub Release。
on:
push:
tags:
- "v*"
# Allow Auto Tag On Release Merge to cascade after a GITHUB_TOKEN tag push
# (token-authored pushes do not retrigger push workflows).
workflow_dispatch:
permissions:
contents: write
actions: write
id-token: write
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false
jobs:
build:
name: Build distributions
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/v')
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Verify release tag matches package version
run: |
set -euo pipefail
package_version=$(sed -nE 's/^version[[:space:]]*=[[:space:]]*"([^"]+)".*/\1/p' pyproject.toml | head -1)
tag_version="${GITHUB_REF_NAME#v}"
if [[ -z "$package_version" || "$package_version" != "$tag_version" ]]; then
echo "Refusing release: tag $GITHUB_REF_NAME does not match pyproject.toml $package_version" >&2
exit 1
fi
- uses: astral-sh/setup-uv@v4
with:
enable-cache: true
- name: Set up Python
run: uv python install 3.12
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: npm
cache-dependency-path: dashboard/package-lock.json
- name: Install dependencies
run: make install
- name: Run tests
run: make test
- name: Build package
run: make build
- name: Upload distributions
uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
publish:
name: Publish to PyPI
needs: build
runs-on: ubuntu-latest
environment: pypi
steps:
- name: Download distributions
uses: actions/download-artifact@v4
with:
name: dist
path: dist/
- name: Publish package
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.PYPI_API_TOKEN }}
github-release:
name: Create GitHub Release
needs: publish
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Download distributions
uses: actions/download-artifact@v4
with:
name: dist
path: dist/
- name: Extract version from tag
id: version
run: echo "version=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT"
- name: Extract release notes
run: |
version=${{ steps.version.outputs.version }}
if [ -f CHANGELOG.md ]; then
awk "/^## \[?$version\]?/{flag=1;next}/^## /{flag=0}flag" CHANGELOG.md > .release-notes.md || true
fi
if [ ! -s .release-notes.md ]; then
PREV=$(git tag --sort=-version:refname | grep -v "^${GITHUB_REF_NAME}$" | head -1)
{
echo "## What's changed"
echo ""
if [ -n "$PREV" ]; then
git log "${PREV}..${GITHUB_REF_NAME}" --oneline --no-decorate
else
git log --oneline --no-decorate | head -20
fi
echo ""
echo "## Install"
echo ""
echo '```bash'
echo "pip install octop==$version"
echo '```'
} > .release-notes.md
fi
if ! grep -q '^## Downloads' .release-notes.md; then
python3 scripts/release_download_links.py "$version" >> .release-notes.md
fi
- name: Create release
uses: softprops/action-gh-release@v2
with:
body_path: .release-notes.md
files: dist/*
generate_release_notes: true
# workflow_run / release:published are unreliable when Release itself was
# started via GITHUB_TOKEN workflow_dispatch (Auto Tag). Explicitly cascade.
#
# This job intentionally has no checkout: pass --repo so `gh` does not need a
# local .git (bare runner → "fatal: not a git repository"). Dispatch failure
# must fail this workflow so a missed sync is visible.
sync-develop:
name: Trigger sync main into develop
needs: github-release
runs-on: ubuntu-latest
steps:
- name: Dispatch Sync Main Into Develop
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh workflow run sync-main-to-develop.yml \
--repo "${{ github.repository }}" \
--ref main \
-f version="${{ github.ref_name }}"
# FnOS FPK:复用本 Release 的 wheel + docker-publish 的 GHCR 镜像。
# 与 sync-develop 并行。Dispatch 失败必须让本 workflow 变红(PyPI 已发布仍如此)。
trigger-fnos:
name: Trigger FnOS FPK build
needs: github-release
runs-on: ubuntu-latest
steps:
- name: Dispatch Build Octop FPK
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# --ref 用版本 tag,保证 FPK 打在与 PyPI / 镜像相同的 commit 上
gh workflow run fnos-build-fpk.yml \
--repo "${{ github.repository }}" \
--ref "${{ github.ref_name }}"