所有分支的提交所有分支的提交都要跑test都要跑test
大石头 authored at 2022-03-29 23:35:41
4.53 KiB
NewLife.RocketMQ
name: publish

on:
  push:
    tags: [ v* ]
  workflow_dispatch:

# 必须同时声明:缺 packages: write 会让 GitHub Packages 推送 403,缺 contents: write 无法创建 Release
permissions:
  contents: write
  packages: write

jobs:
  build-publish:
    # 优先 Ubuntu:打包与发包均为纯托管流程,无需 Windows 专属工具链
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4
    - name: Setup dotNET
      uses: actions/setup-dotnet@v4
      with:
        dotnet-version: |
          6.x
          7.x
          8.x
          9.x
          10.x
    - name: Resolve version
      id: version
      # tag 发布时以 tag 为准(去掉 v 前缀),保证包版本与 tag 完全一致;
      # 手工触发时不传 Version,沿用 csproj 中「主.次.当天」的默认版本
      run: |
        if [ "${{ github.ref_type }}" = "tag" ]; then
          VERSION="${GITHUB_REF_NAME#v}"
          echo "version=$VERSION" >> "$GITHUB_OUTPUT"
          echo "pack_args=-p:Version=$VERSION" >> "$GITHUB_OUTPUT"
        else
          echo "version=(csproj default)" >> "$GITHUB_OUTPUT"
          echo "pack_args=" >> "$GITHUB_OUTPUT"
        fi
    - name: Build
      run: |
        dotnet pack -c Release -o out ${{ steps.version.outputs.pack_args }} NewLife.RocketMQ/NewLife.RocketMQ.csproj
        ls -l out
    - name: Publish to GitHub Packages
      id: ghpackages
      # 备用镜像渠道,失败只告警,不阻断 NuGet.org 正式发布
      continue-on-error: true
      run: |
        dotnet nuget push ./out/*.nupkg --skip-duplicate --source https://nuget.pkg.github.com/NewLifeX/index.json --api-key ${{ github.token }}
    - name: Publish to NuGet.org
      id: nuget
      run: |
        dotnet nuget push ./out/*.nupkg --skip-duplicate --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.nugetKey }}
    - name: Create GitHub Release
      id: release
      # 仅 tag 推送时创建;手工触发(无 tag)只发包
      if: startsWith(github.ref, 'refs/tags/')
      # 观察期:失败只告警,不影响已完成的发包;结尾 Publish Summary 会显式标红
      continue-on-error: true
      env:
        GH_TOKEN: ${{ github.token }}
      run: |
        set -euo pipefail
        tag="$GITHUB_REF_NAME"

        # 幂等:同 tag 已有 Release 就直接跳过,失败重跑不会报错
        if gh release view "$tag" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
          echo "Release $tag 已存在,跳过"
          exit 0
        fi

        # 发布说明优先取 ChangeLog.md 中当前版本段落(标题形如 "## v3.3.2026.1024 (2026-10-24)")
        version="${tag#v}"
        escaped=$(printf '%s' "$version" | sed 's/[.]/\\./g')
        start=$(grep -nE "^## v?${escaped}([ (]|\$)" ChangeLog.md | head -1 | cut -d: -f1 || true)

        args=(release create "$tag" --repo "$GITHUB_REPOSITORY" --title "$tag" --verify-tag)
        if [ -n "$start" ]; then
          end=$(awk -v s="$start" 'NR>s && /^## /{print NR; exit}' ChangeLog.md)
          [ -n "$end" ] || end=$(( $(wc -l < ChangeLog.md) + 1 ))
          sed -n "${start},$((end - 1))p" ChangeLog.md > release-notes.md
          args+=(--notes-file release-notes.md)
          echo "发布说明取自 ChangeLog.md 的 $version 段落($((end - start)) 行)"
        else
          args+=(--generate-notes)
          echo "ChangeLog.md 未找到 $version 段落,改用自动生成说明"
        fi

        shopt -s nullglob
        assets=(out/*.nupkg out/*.snupkg)
        args+=("${assets[@]}")
        gh "${args[@]}"
        echo "已创建 Release $tag,附加资产 ${#assets[@]} 个"
    - name: Publish Summary
      if: always()
      run: |
        summary="$GITHUB_STEP_SUMMARY"
        echo "### 发布结果" >> "$summary"
        echo "" >> "$summary"
        echo "| 渠道 | 结果 |" >> "$summary"
        echo "| --- | --- |" >> "$summary"
        for row in \
          "GitHub Packages|${{ steps.ghpackages.outcome }}" \
          "NuGet.org|${{ steps.nuget.outcome }}" \
          "GitHub Release|${{ steps.release.outcome }}"
        do
          name="${row%%|*}"
          outcome="${row##*|}"
          case "$outcome" in
            success) mark="✅" ;;
            failure) mark="⚠️" ;;
            skipped) mark="⏭" ;;
            cancelled) mark="⛔" ;;
            *) mark="❔" ;;
          esac
          echo "| $name | $mark $outcome |" >> "$summary"
        done
        echo "" >> "$summary"
        echo "> GitHub Release 仅 tag 推送时创建;手工触发只发包。" >> "$summary"