Skip to content

Release

Release #10

Workflow file for this run

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 }}"