Create Release and Publish to NuGet #7
This file contains 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: Create Release and Publish to NuGet | |
on: | |
workflow_dispatch: | |
inputs: | |
release_type: | |
description: 'Release type' | |
required: true | |
default: 'patch' | |
type: choice | |
options: | |
- patch | |
- minor | |
- major | |
jobs: | |
build-and-release: | |
runs-on: ubuntu-latest | |
steps: | |
# Checkout repository with full history | |
- uses: actions/checkout@v3 | |
with: | |
fetch-depth: 0 | |
# Setup .NET SDK | |
- name: Setup .NET | |
uses: actions/setup-dotnet@v3 | |
with: | |
dotnet-version: '9.0.x' | |
# Check which projects changed and calculate their new versions | |
- name: Check Changes and Calculate Versions | |
id: version_check | |
run: | | |
SHOULD_RELEASE="false" | |
CHANGED_PROJECTS="" | |
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "") | |
# Check each project for changes and update versions | |
for proj in $(find . -name "*.csproj"); do | |
PROJECT_NAME=$(basename "$proj") | |
PROJECT_DIR=$(dirname "$proj") | |
# Get current version from csproj | |
CURRENT_VERSION=$(grep -oP '(?<=<Version>).*(?=</Version>)' "$proj" || echo "0.0.0") | |
# Split version into parts | |
IFS='.' read -r -a VERSION_PARTS <<< "$CURRENT_VERSION" | |
MAJOR="${VERSION_PARTS[0]}" | |
MINOR="${VERSION_PARTS[1]}" | |
PATCH="${VERSION_PARTS[2]}" | |
# Check if project has changes since last tag | |
if [ -z "$LATEST_TAG" ] || ! git diff --quiet $LATEST_TAG HEAD -- "$PROJECT_DIR"; then | |
# Calculate new version based on release type | |
case "${{ github.event.inputs.release_type }}" in | |
"major") | |
NEW_VERSION="$((MAJOR + 1)).0.0" | |
;; | |
"minor") | |
NEW_VERSION="${MAJOR}.$((MINOR + 1)).0" | |
;; | |
"patch") | |
NEW_VERSION="${MAJOR}.${MINOR}.$((PATCH + 1))" | |
;; | |
esac | |
# Update version in csproj | |
sed -i "s/<Version>.*<\/Version>/<Version>${NEW_VERSION}<\/Version>/g" "$proj" | |
CHANGED_PROJECTS="$CHANGED_PROJECTS$PROJECT_NAME -> $NEW_VERSION\n" | |
SHOULD_RELEASE="true" | |
fi | |
done | |
# Set environment variables for next steps | |
echo "CHANGED_PROJECTS<<EOF" >> $GITHUB_ENV | |
echo -e "$CHANGED_PROJECTS" >> $GITHUB_ENV | |
echo "EOF" >> $GITHUB_ENV | |
echo "SHOULD_RELEASE=$SHOULD_RELEASE" >> $GITHUB_ENV | |
# Generate release notes with commits and changed projects | |
- name: Generate Release Notes | |
if: env.SHOULD_RELEASE == 'true' | |
id: release_notes | |
run: | | |
PREVIOUS_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "") | |
if [ -z "$PREVIOUS_TAG" ]; then | |
COMMITS=$(git log --pretty=format:"- %s" --no-merges) | |
else | |
COMMITS=$(git log ${PREVIOUS_TAG}..HEAD --pretty=format:"- %s" --no-merges) | |
fi | |
echo "RELEASE_NOTES<<EOF" >> $GITHUB_ENV | |
echo "## What's Changed" >> $GITHUB_ENV | |
echo "$COMMITS" >> $GITHUB_ENV | |
echo -e "\n## Updated Projects" >> $GITHUB_ENV | |
echo "${{ env.CHANGED_PROJECTS }}" >> $GITHUB_ENV | |
echo "EOF" >> $GITHUB_ENV | |
# Restore project dependencies | |
- name: Restore dependencies | |
if: env.SHOULD_RELEASE == 'true' | |
run: dotnet restore | |
# Build solution | |
- name: Build | |
if: env.SHOULD_RELEASE == 'true' | |
run: dotnet build --configuration Release --no-restore | |
# Create NuGet packages | |
- name: Pack | |
if: env.SHOULD_RELEASE == 'true' | |
run: dotnet pack --configuration Release --no-build --output nupkgs | |
# Create GitHub release | |
- name: Create Release | |
if: env.SHOULD_RELEASE == 'true' | |
id: create_release | |
uses: actions/create-release@v1 | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
with: | |
tag_name: v${{ env.NEW_VERSION }} | |
release_name: Release v${{ env.NEW_VERSION }} | |
body: ${{ env.RELEASE_NOTES }} | |
draft: false | |
prerelease: false | |
# Upload NuGet packages as release assets | |
- name: Upload Release Assets | |
if: env.SHOULD_RELEASE == 'true' | |
uses: softprops/action-gh-release@v1 | |
with: | |
files: ./nupkgs/*.nupkg | |
tag_name: v${{ env.NEW_VERSION }} | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
# Publish packages to NuGet.org | |
- name: Push to NuGet | |
if: env.SHOULD_RELEASE == 'true' | |
run: dotnet nuget push "./nupkgs/*.nupkg" --source "https://api.nuget.org/v3/index.json" --api-key ${{secrets.NUGET_API_KEY}} --skip-duplicate | |
# Commit version updates and create tag | |
- name: Commit version updates | |
if: env.SHOULD_RELEASE == 'true' | |
run: | | |
git config --local user.email "[email protected]" | |
git config --local user.name "GitHub Action" | |
git add . | |
git commit -m "Update project versions" | |
git tag -a "v${{ env.NEW_VERSION }}" -m "Release v${{ env.NEW_VERSION }}" | |
git push --follow-tags |