Skip to content
This repository was archived by the owner on Apr 6, 2026. It is now read-only.

Build and Release

Build and Release #36

Workflow file for this run

name: Build and Release
on:
workflow_dispatch:
env:
DOTNET_VERSION: '9.0.x'
jobs:
build-and-release:
runs-on: windows-latest
if: github.event_name == 'workflow_dispatch'
permissions:
contents: write
pull-requests: read
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
ref: ${{ github.ref }}
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
- name: Restore dependencies
run: dotnet restore YAEP.sln
- name: Build solution
run: dotnet build YAEP.sln --configuration Release --no-restore
- name: Get current version
id: get_version
run: |
$version = Select-String -Path "YAEP.AvaloniaUI\YAEP.AvaloniaUI.csproj" -Pattern '<Version>(\d+)\.(\d+)\.(\d+)</Version>' | ForEach-Object { $_.Matches.Groups[1..3].Value -join '.' }
if ([string]::IsNullOrEmpty($version)) {
$version = "1.0.0"
}
Write-Host "Current version: $version"
echo "CURRENT_VERSION=$version" >> $env:GITHUB_ENV
$parts = $version -split '\.'
echo "MAJOR=$($parts[0])" >> $env:GITHUB_ENV
echo "MINOR=$($parts[1])" >> $env:GITHUB_ENV
echo "PATCH=$($parts[2])" >> $env:GITHUB_ENV
- name: Get last tag
id: get_last_tag
run: |
$ErrorActionPreference = "Continue"
$lastTag = ""
$hasChanges = "false"
# Fetch all tags to ensure we have them
Write-Host "Fetching all tags..."
git fetch --tags --force
# Get the most recent tag (sorted by version), won't fail if no tags exist
$tagOutput = git tag --sort=-version:refname | Select-Object -First 1
if (-not [string]::IsNullOrWhiteSpace($tagOutput)) {
$lastTag = $tagOutput.Trim()
Write-Host "Found last tag: $lastTag"
# Get the commit SHA that the tag points to (handles both annotated and lightweight tags)
$tagCommit = git rev-parse "$lastTag^{commit}" 2>&1
if ($LASTEXITCODE -ne 0) {
Write-Host "Warning: Could not resolve tag commit: $tagCommit"
Write-Host "Assuming changes exist for safety"
$hasChanges = "true"
} else {
$tagCommit = $tagCommit.Trim()
Write-Host "Tag $lastTag points to commit: $tagCommit"
# Get current HEAD commit
$headCommit = git rev-parse HEAD 2>&1
if ($LASTEXITCODE -ne 0) {
Write-Host "Warning: Could not get HEAD commit"
Write-Host "Assuming changes exist for safety"
$hasChanges = "true"
} else {
$headCommit = $headCommit.Trim()
Write-Host "Current HEAD commit: $headCommit"
# Check if there are commits between tag and HEAD
# Use ^{commit} to dereference annotated tags to their commit
Write-Host "Checking for commits between $lastTag and HEAD..."
$commitCountOutput = git rev-list "$lastTag^{commit}..HEAD" --count 2>&1
if ($LASTEXITCODE -eq 0) {
if (-not [string]::IsNullOrWhiteSpace($commitCountOutput)) {
$commitCount = [int]$commitCountOutput.Trim()
Write-Host "Commit count: $commitCount"
if ($commitCount -gt 0) {
$hasChanges = "true"
Write-Host "Found $commitCount new commits since last tag"
} else {
Write-Host "No new commits since last tag, skipping version bump and release"
}
} else {
Write-Host "No commit count output, checking if commits exist..."
# Fallback: check if there are any commits at all
$commitList = git rev-list "$lastTag^{commit}..HEAD" 2>&1
if (-not [string]::IsNullOrWhiteSpace($commitList)) {
$hasChanges = "true"
Write-Host "Found commits between tag and HEAD"
} else {
Write-Host "No new commits since last tag, skipping version bump and release"
}
}
} else {
Write-Host "Warning: git rev-list failed with exit code $LASTEXITCODE"
Write-Host "Output: $commitCountOutput"
Write-Host "Assuming changes exist for safety"
$hasChanges = "true"
}
}
}
} else {
Write-Host "No existing tags found - this will be the first release"
$hasChanges = "true"
}
Write-Host "Last tag: $lastTag (empty if none)"
Write-Host "Has changes: $hasChanges"
echo "has_changes=$hasChanges" >> $env:GITHUB_OUTPUT
echo "LAST_TAG=$lastTag" >> $env:GITHUB_ENV
- name: Increment version
id: increment_version
if: steps.get_last_tag.outputs.has_changes == 'true'
run: |
$patch = [int]$env:PATCH + 1
$newVersion = "$env:MAJOR.$env:MINOR.$patch"
Write-Host "New version: $newVersion"
echo "version=$newVersion" >> $env:GITHUB_OUTPUT
- name: Update version in project files
if: steps.get_last_tag.outputs.has_changes == 'true'
run: |
$newVersion = "${{ steps.increment_version.outputs.version }}"
$files = @("YAEP.AvaloniaUI\YAEP.AvaloniaUI.csproj", "YAEP.Interop\YAEP.Interop.csproj")
foreach ($file in $files) {
$content = Get-Content $file -Raw
# Add or update Version property
if ($content -match '<Version>(\d+\.\d+\.\d+)</Version>') {
$content = $content -replace '<Version>(\d+\.\d+\.\d+)</Version>', "<Version>$newVersion</Version>"
} else {
# Add Version property after TargetFramework
$content = $content -replace '(<TargetFramework>.*?</TargetFramework>)', "`$1`n <Version>$newVersion</Version>"
}
# Add or update AssemblyVersion
if ($content -match '<AssemblyVersion>(\d+\.\d+\.\d+\.\d+)</AssemblyVersion>') {
$content = $content -replace '<AssemblyVersion>(\d+\.\d+\.\d+\.\d+)</AssemblyVersion>', "<AssemblyVersion>$newVersion.0</AssemblyVersion>"
} else {
$content = $content -replace '(<Version>.*?</Version>)', "`$1`n <AssemblyVersion>$newVersion.0</AssemblyVersion>"
}
# Add or update FileVersion
if ($content -match '<FileVersion>(\d+\.\d+\.\d+\.\d+)</FileVersion>') {
$content = $content -replace '<FileVersion>(\d+\.\d+\.\d+\.\d+)</FileVersion>', "<FileVersion>$newVersion.0</FileVersion>"
} else {
$content = $content -replace '(<AssemblyVersion>.*?</AssemblyVersion>)', "`$1`n <FileVersion>$newVersion.0</FileVersion>"
}
# Add AssemblyName to YAEP.AvaloniaUI to make executable YAEP.exe
if ($file -like "*YAEP.AvaloniaUI*") {
if (-not ($content -match '<AssemblyName>')) {
$content = $content -replace '(<FileVersion>.*?</FileVersion>)', "`$1`n <AssemblyName>YAEP</AssemblyName>"
} else {
$content = $content -replace '<AssemblyName>.*?</AssemblyName>', "<AssemblyName>YAEP</AssemblyName>"
}
}
Set-Content $file -Value $content -NoNewline
}
- name: Rebuild with new version
if: steps.get_last_tag.outputs.has_changes == 'true'
run: |
dotnet build YAEP.sln --configuration Release --no-restore
- name: Publish application
if: steps.get_last_tag.outputs.has_changes == 'true'
run: |
dotnet publish YAEP.AvaloniaUI/YAEP.AvaloniaUI.csproj --configuration Release --output ./publish --no-build
- name: Configure Git
if: steps.get_last_tag.outputs.has_changes == 'true'
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
- name: Commit version bump
if: steps.get_last_tag.outputs.has_changes == 'true'
run: |
git add YAEP.AvaloniaUI/YAEP.AvaloniaUI.csproj YAEP.Interop/YAEP.Interop.csproj
git commit -m "Bump version to ${{ steps.increment_version.outputs.version }}" || exit 0
- name: Generate release notes
id: generate_release_notes
if: steps.get_last_tag.outputs.has_changes == 'true'
uses: actions/github-script@v7
env:
LAST_TAG: ${{ env.LAST_TAG }}
with:
script: |
const fs = require('fs');
const lastTag = process.env.LAST_TAG;
const params = {
owner: context.repo.owner,
repo: context.repo.repo,
tag_name: `v${{ steps.increment_version.outputs.version }}`,
};
// If there's a previous tag, use it for comparison (as per GitHub docs)
if (lastTag && lastTag.trim() !== '') {
params.previous_tag_name = lastTag;
}
const { data: releaseNotes } = await github.rest.repos.generateReleaseNotes(params);
core.setOutput('body', releaseNotes.body);
fs.writeFileSync('CHANGELOG.md', releaseNotes.body);
- name: Create git tag
if: steps.get_last_tag.outputs.has_changes == 'true'
run: |
$version = "${{ steps.increment_version.outputs.version }}"
git tag -a "v$version" -m "Release v$version"
git push origin "v$version"
- name: Push version bump commit
if: steps.get_last_tag.outputs.has_changes == 'true'
run: |
git push origin main
- name: Create release package
id: create_package
if: steps.get_last_tag.outputs.has_changes == 'true'
run: |
$version = "${{ steps.increment_version.outputs.version }}"
$zipName = "YAEP-v$version.zip"
Compress-Archive -Path ./publish/* -DestinationPath $zipName -Force
Write-Host "Created package: $zipName"
echo "package_name=$zipName" >> $env:GITHUB_OUTPUT
- name: Create GitHub Release
if: steps.get_last_tag.outputs.has_changes == 'true'
uses: softprops/action-gh-release@v1
with:
tag_name: v${{ steps.increment_version.outputs.version }}
name: Release v${{ steps.increment_version.outputs.version }}
body_path: CHANGELOG.md
files: YAEP-v${{ steps.increment_version.outputs.version }}.zip
draft: false
prerelease: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}