Release #10
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 }}" |