Skip to content

Release

Release #3

Workflow file for this run

name: Release
on:
workflow_dispatch:
inputs:
tag:
description: "Release tag (e.g. RELEASE.1.0.0.0)"
required: true
title:
description: "Release title (e.g. Release v1.0.0.0)"
required: false
default: ""
pre_release:
description: "Mark as pre-release"
required: false
default: "false"
type: boolean
draft:
description: "Create as draft"
required: false
default: "false"
type: boolean
permissions:
contents: write
env:
DOTNET_VERSION: "10.0.x"
jobs:
prepare-release:
name: Prepare Release
runs-on: ubuntu-latest
outputs:
tag: ${{ steps.get-tag.outputs.tag }}
title: ${{ steps.get-title.outputs.title }}
is_pre_release: ${{ steps.check-pre-release.outputs.is_pre_release }}
is_draft: ${{ steps.check-draft.outputs.is_draft }}
commit_sha: ${{ steps.get-commit.outputs.commit_sha }}
contributors: ${{ steps.get-contributors.outputs.contributors }}
whats_changed: ${{ steps.whats-changed.outputs.changes }}
steps:
- name: Check out Git repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get release tag
id: get-tag
shell: bash
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "tag=${{ github.event.inputs.tag }}" >> $GITHUB_OUTPUT
else
echo "tag=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
fi
- name: Get release title
id: get-title
shell: bash
run: |
if [ -n "${{ github.event.inputs.title }}" ]; then
echo "title=${{ github.event.inputs.title }}" >> $GITHUB_OUTPUT
else
echo "title=Release ${{ steps.get-tag.outputs.tag }}" >> $GITHUB_OUTPUT
fi
- name: Check if pre-release
id: check-pre-release
shell: bash
run: |
if [ "${{ github.event.inputs.pre_release }}" = "true" ]; then
echo "is_pre_release=true" >> $GITHUB_OUTPUT
else
TAG="${{ steps.get-tag.outputs.tag }}"
if [[ "$TAG" =~ -(alpha|beta|rc|pre|preview) ]]; then
echo "is_pre_release=true" >> $GITHUB_OUTPUT
else
echo "is_pre_release=false" >> $GITHUB_OUTPUT
fi
fi
- name: Check if draft
id: check-draft
shell: bash
run: |
if [ "${{ github.event.inputs.draft }}" = "true" ]; then
echo "is_draft=true" >> $GITHUB_OUTPUT
else
echo "is_draft=false" >> $GITHUB_OUTPUT
fi
- name: Get commit SHA
id: get-commit
shell: bash
run: |
echo "commit_sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
- name: Get contributors
id: get-contributors
shell: bash
run: |
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
if [ -z "$LAST_TAG" ]; then
CONTRIBUTORS=$(git log --pretty=format:"%an" | sort | uniq -c | sort -nr | awk '{print "- " $2 " (" $1 " commit(s))"}')
else
CONTRIBUTORS=$(git log ${LAST_TAG}..HEAD --pretty=format:"%an" | sort | uniq -c | sort -nr | awk '{print "- " $2 " (" $1 " commit(s))"}')
fi
if [ -z "$CONTRIBUTORS" ]; then CONTRIBUTORS="No new contributors"; fi
{
echo "contributors<<EOF"
echo "$CONTRIBUTORS"
echo "EOF"
} >> $GITHUB_OUTPUT
- name: Generate What's Changed
id: whats-changed
shell: bash
run: |
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
if [ -z "$LAST_TAG" ]; then
COMMITS=$(git log --pretty=format:"- %s" --reverse)
else
COMMITS=$(git log ${LAST_TAG}..HEAD --pretty=format:"- %s" --reverse)
fi
if [ -z "$COMMITS" ]; then COMMITS="No changes"; fi
# 使用 EOF 语法正确处理多行输出
{
echo "changes<<EOF"
echo "$COMMITS"
echo "EOF"
} >> $GITHUB_OUTPUT
build:
name: Build ${{ matrix.project.name }} on ${{ matrix.platform.name }}
runs-on: ${{ matrix.platform.runner }}
needs: prepare-release
strategy:
matrix:
platform:
- name: linux-x64
runner: ubuntu-latest
rid: linux-x64
- name: linux-arm64
runner: ubuntu-latest
rid: linux-arm64
- name: win-x64
runner: windows-latest
rid: win-x64
- name: osx-arm64
runner: macos-latest
rid: osx-arm64
project:
- name: OpenProfileServer
project_file: "OpenProfileServer/OpenProfileServer.csproj"
output_name: openprofile-server
- name: OpenProfileServer.Generator
project_file: "OpenProfileServer.Generator/OpenProfileServer.Generator.csproj"
output_name: openprofile-generator
fail-fast: false
steps:
- name: Check out Git repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
- name: Install dependencies
run: dotnet restore ${{ matrix.project.project_file }}
- name: Build ${{ matrix.project.name }} for ${{ matrix.platform.name }}
shell: bash
run: |
OUTPUT_DIR="./publish/${{ matrix.platform.name }}/${{ matrix.project.name }}"
ARCHIVE_NAME="${{ matrix.project.output_name }}-${{ matrix.platform.rid }}.tar.gz"
SINGLE_FILE_ARGS="-p:PublishSingleFile=true -p:IncludeAllContentForSelfExtract=true"
if [[ "${{ matrix.platform.rid }}" == win-* ]]; then
SINGLE_FILE_ARGS="$SINGLE_FILE_ARGS -p:IncludeNativeLibrariesForSelfExtract=true"
fi
dotnet publish "${{ matrix.project.project_file }}" \
--configuration Release \
--runtime "${{ matrix.platform.rid }}" \
--self-contained true \
--output "$OUTPUT_DIR" \
-p:PublishTrimmed=false \
-p:PublishReadyToRun=true \
$SINGLE_FILE_ARGS
mkdir -p ./artifacts
# 使用 -C 参数简化 tar 命令,避免 pushd/popd 错误
tar -czf "./artifacts/$ARCHIVE_NAME" -C "$OUTPUT_DIR" .
echo "Created archive: $ARCHIVE_NAME"
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.project.output_name }}-${{ matrix.platform.name }}
path: ./artifacts/*
retention-days: 7
create-release:
name: Create Release
runs-on: ubuntu-latest
needs: [prepare-release, build]
steps:
- name: Check out Git repository
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: ./artifacts
- name: Create Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.prepare-release.outputs.tag }}
name: ${{ needs.prepare-release.outputs.title }}
target_commitish: ${{ needs.prepare-release.outputs.commit_sha }}
draft: ${{ needs.prepare-release.outputs.is_draft }}
prerelease: ${{ needs.prepare-release.outputs.is_pre_release }}
generate_release_notes: false
body: |
## What's Changed
${{ needs.prepare-release.outputs.whats_changed }}
## Contributors
${{ needs.prepare-release.outputs.contributors }}
---
**Full Changelog**: https://github.com/${{ github.repository }}/commits/${{ needs.prepare-release.outputs.tag }}
files: ./artifacts/*/*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}