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 同时触发)。wheel / sdist 只发 PyPI 和 GitHub Release。 # 桌面安装包与 FnOS FPK 挂到同一 GitHub Release 后,再上传到同一个 COS 版本目录。 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 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 - 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 }}"