发布 #34
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: 发布 | |
| on: | |
| push: | |
| branches: | |
| - main | |
| tags: | |
| - 'v*' | |
| workflow_dispatch: | |
| inputs: | |
| snapshot: | |
| description: '仅测试构建(不发布)' | |
| type: boolean | |
| default: false | |
| draft: | |
| description: '创建草稿发布' | |
| type: boolean | |
| default: false | |
| permissions: | |
| contents: write | |
| env: | |
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true | |
| jobs: | |
| auto-tag: | |
| if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| outputs: | |
| tag: ${{ steps.version.outputs.tag }} | |
| steps: | |
| - name: 检出代码 | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: 读取版本号 | |
| id: version | |
| shell: bash | |
| run: | | |
| VERSION=$(sed -n 's/^[[:space:]]*version = "\(.*\)"/\1/p' common/globals.go) | |
| if [ -z "$VERSION" ]; then | |
| echo "❌ 无法从 common/globals.go 读取版本号" | |
| exit 1 | |
| fi | |
| TAG="v${VERSION}" | |
| echo "version=${VERSION}" >> "$GITHUB_OUTPUT" | |
| echo "tag=${TAG}" >> "$GITHUB_OUTPUT" | |
| echo "准备发布 ${TAG}" | |
| - name: 创建发布标签 | |
| shell: bash | |
| run: | | |
| TAG="${{ steps.version.outputs.tag }}" | |
| if git ls-remote --exit-code --tags origin "refs/tags/${TAG}" >/tmp/tag-ref 2>/dev/null; then | |
| git fetch --force origin "refs/tags/${TAG}:refs/tags/${TAG}" | |
| TAG_COMMIT=$(git rev-list -n 1 "${TAG}") | |
| HEAD_COMMIT=$(git rev-parse HEAD) | |
| if [ "$TAG_COMMIT" = "$HEAD_COMMIT" ]; then | |
| echo "✅ ${TAG} 已指向当前提交,跳过创建" | |
| exit 0 | |
| fi | |
| echo "❌ ${TAG} 已存在,但不指向当前提交" | |
| echo "tag: ${TAG_COMMIT}" | |
| echo "head: ${HEAD_COMMIT}" | |
| exit 1 | |
| fi | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| git tag -a "${TAG}" -m "Release ${TAG}" | |
| git push origin "${TAG}" | |
| release: | |
| needs: [auto-tag] | |
| if: ${{ always() && (startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref == 'refs/heads/main' && needs.auto-tag.result == 'success')) }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 90 | |
| steps: | |
| - name: 检出代码 | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: 解析发布标签 | |
| id: release_tag | |
| shell: bash | |
| env: | |
| AUTO_TAG: ${{ needs.auto-tag.outputs.tag }} | |
| SNAPSHOT: ${{ inputs.snapshot }} | |
| run: | | |
| if [[ "${GITHUB_REF}" == refs/tags/* ]]; then | |
| TAG="${GITHUB_REF_NAME}" | |
| elif [ "${GITHUB_EVENT_NAME}" = "push" ] && [ "${GITHUB_REF}" = "refs/heads/main" ]; then | |
| TAG="${AUTO_TAG}" | |
| git fetch --force origin "refs/tags/${TAG}:refs/tags/${TAG}" | |
| elif [ "${GITHUB_EVENT_NAME}" = "workflow_dispatch" ] && [ "${SNAPSHOT}" = "true" ]; then | |
| TAG="${GITHUB_REF_NAME}" | |
| else | |
| echo "❌ 非 snapshot 手动发布必须从 tag 触发" | |
| exit 1 | |
| fi | |
| echo "tag=${TAG}" >> "$GITHUB_OUTPUT" | |
| echo "RELEASE_TAG=${TAG}" >> "$GITHUB_ENV" | |
| - name: 准备 Release Notes | |
| if: ${{ !inputs.snapshot }} | |
| run: | | |
| TAG="${RELEASE_TAG}" | |
| NOTES_FILE=".github/release-notes/${TAG}.md" | |
| if [ -f "$NOTES_FILE" ]; then | |
| echo "📝 找到版本 Release Notes: $NOTES_FILE" | |
| cp "$NOTES_FILE" /tmp/release-notes.md | |
| else | |
| echo "⚠️ 未找到 $NOTES_FILE,使用自动生成的 changelog" | |
| echo "" > /tmp/release-notes.md | |
| fi | |
| echo "RELEASE_NOTES_FILE=/tmp/release-notes.md" >> $GITHUB_ENV | |
| - name: 构建和发布 | |
| uses: ./.github/actions/build-release | |
| with: | |
| mode: ${{ inputs.snapshot && 'snapshot' || 'release' }} | |
| go-version: '1.25' | |
| retention-days: '90' | |
| release-args: ${{ inputs.draft && '--draft' || '' }} | |
| - name: 更新 Release Notes | |
| if: ${{ !inputs.snapshot && env.RELEASE_NOTES_FILE != '' }} | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| TAG="${RELEASE_TAG}" | |
| NOTES_FILE="${RELEASE_NOTES_FILE}" | |
| if [ -s "$NOTES_FILE" ]; then | |
| echo "📝 更新 Release Notes..." | |
| # 用版本特定的 notes 替换 goreleaser 生成的 body | |
| gh release edit "$TAG" --notes-file "$NOTES_FILE" | |
| echo "✅ Release Notes 已更新" | |
| fi |