Skip to content

Release

Release #5

Workflow file for this run

name: Release
on:
workflow_dispatch:
inputs:
tag:
description: "Release tag (e.g. v1.0.0)"
required: true
title:
description: "Release title (e.g. Release v1.0.0)"
required: false
default: ""
previous_tag:
description: "Previous tag for changelog comparison (leave empty to auto-detect)"
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: "8.0.x"
jobs:
prepare-release:
name: Prepare Release
runs-on: ubuntu-latest
outputs:
tag: ${{ steps.config.outputs.tag }}
title: ${{ steps.config.outputs.title }}
previous_tag: ${{ steps.changelog.outputs.previous_tag }}
is_pre_release: ${{ steps.config.outputs.is_pre_release }}
is_draft: ${{ steps.config.outputs.is_draft }}
commit_sha: ${{ steps.config.outputs.commit_sha }}
contributors: ${{ steps.changelog.outputs.contributors }}
whats_changed: ${{ steps.changelog.outputs.changes }}
steps:
- name: Check out Git repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Configure Release Parameters
id: config
shell: bash
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
TAG="${{ github.event.inputs.tag }}"
else
TAG="${GITHUB_REF#refs/tags/}"
fi
echo "tag=$TAG" >> $GITHUB_OUTPUT
if [ -n "${{ github.event.inputs.title }}" ]; then
echo "title=${{ github.event.inputs.title }}" >> $GITHUB_OUTPUT
else
echo "title=Release $TAG" >> $GITHUB_OUTPUT
fi
if [ "${{ github.event.inputs.pre_release }}" = "true" ]; then
echo "is_pre_release=true" >> $GITHUB_OUTPUT
elif [[ "$TAG" =~ -(alpha|beta|rc|pre|preview) ]]; then
echo "is_pre_release=true" >> $GITHUB_OUTPUT
else
echo "is_pre_release=false" >> $GITHUB_OUTPUT
fi
echo "is_draft=${{ github.event.inputs.draft }}" >> $GITHUB_OUTPUT
echo "commit_sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
- name: Generate Changelog
id: changelog
shell: bash
run: |
CURRENT_TAG="${{ steps.config.outputs.tag }}"
INPUT_PREV="${{ github.event.inputs.previous_tag }}"
if [ -n "$INPUT_PREV" ]; then
PREV_TAG="$INPUT_PREV"
else
PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
fi
echo "Current: $CURRENT_TAG, Previous: $PREV_TAG"
echo "previous_tag=$PREV_TAG" >> $GITHUB_OUTPUT
# 统一格式:
# Commits: - Subject (@**Author**)
# Contributors: - **Author** (Count commits)
if [ -z "$PREV_TAG" ]; then
echo "No previous tag found. Listing all commits."
COMMITS=$(git log --pretty=format:"- %s (@**%an**)" --reverse)
CONTRIBUTORS=$(git log --pretty=format:"%an" | sort | uniq -c | sort -nr | awk '{print "- **" $2 "** (" $1 " commits)"}')
else
echo "Generating changelog from $PREV_TAG to HEAD."
COMMITS=$(git log ${PREV_TAG}..HEAD --pretty=format:"- %s (@**%an**)" --reverse)
CONTRIBUTORS=$(git log ${PREV_TAG}..HEAD --pretty=format:"%an" | sort | uniq -c | sort -nr | awk '{print "- **" $2 "** (" $1 " commits)"}')
fi
if [ -z "$COMMITS" ]; then COMMITS="No visible changes."; fi
if [ -z "$CONTRIBUTORS" ]; then CONTRIBUTORS="No new contributors."; fi
{
echo "changes<<EOF"
echo "$COMMITS"
echo "EOF"
} >> $GITHUB_OUTPUT
{
echo "contributors<<EOF"
echo "$CONTRIBUTORS"
echo "EOF"
} >> $GITHUB_OUTPUT
build:
name: Build ${{ matrix.project.name }} (${{ matrix.platform.rid }})
runs-on: ${{ matrix.platform.runner }}
needs: prepare-release
strategy:
fail-fast: false
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
path: "OpenProfileServer/OpenProfileServer.csproj"
output_name: openprofile-server
- name: OpenProfileServer.Generator
path: "OpenProfileServer.Generator/OpenProfileServer.Generator.csproj"
output_name: openprofile-generator
steps:
- name: Check out Git repository
uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
- name: Install dependencies
run: dotnet restore "${{ matrix.project.path }}"
- name: Build and Publish
shell: bash
run: |
OUTPUT_DIR="./publish/${{ matrix.project.name }}"
ARCHIVE_NAME="${{ matrix.project.output_name }}-${{ matrix.platform.rid }}.zip"
EXTRA_ARGS="-p:PublishSingleFile=true -p:IncludeAllContentForSelfExtract=true"
if [[ "${{ matrix.platform.rid }}" == win-* ]]; then
EXTRA_ARGS="$EXTRA_ARGS -p:IncludeNativeLibrariesForSelfExtract=true"
fi
echo "Building ${{ matrix.project.name }}..."
dotnet publish "${{ matrix.project.path }}" \
--configuration Release \
--runtime "${{ matrix.platform.rid }}" \
--self-contained true \
--output "$OUTPUT_DIR" \
-p:PublishTrimmed=false \
-p:PublishReadyToRun=false \
$EXTRA_ARGS
mkdir -p ./artifacts
echo "Compressing to $ARCHIVE_NAME..."
if [[ "${{ matrix.platform.runner }}" == "windows-latest" ]]; then
# Windows: Enter directory first to ensure clean zip structure
cd "$OUTPUT_DIR"
7z a -tzip "../../artifacts/$ARCHIVE_NAME" .
else
# Linux/Mac
cd "$OUTPUT_DIR"
zip -r "../../artifacts/$ARCHIVE_NAME" .
fi
echo "Build Complete: $ARCHIVE_NAME"
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.project.output_name }}-${{ matrix.platform.rid }}
path: ./artifacts/*
retention-days: 1
create-release:
name: Create Release
runs-on: ubuntu-latest
needs: [prepare-release, build]
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: ./artifacts
- name: Display Artifacts structure
run: ls -R ./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 }}/compare/${{ needs.prepare-release.outputs.previous_tag }}...${{ needs.prepare-release.outputs.tag }}
files: ./artifacts/*/*.zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}