Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
181 changes: 181 additions & 0 deletions .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
name: .NET Build and Test

on:
push:
branches: [ "main", "develop", "claude/**" ]
pull_request:
branches: [ "main", "develop" ]
workflow_dispatch:

jobs:
build-and-test:
name: Build and Test
runs-on: windows-latest

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'

- name: Display .NET version
run: dotnet --version

- name: Set development build version
shell: pwsh
run: |
$buildNumber = "${{ github.run_number }}"
$version = "0.0.$buildNumber"
echo "BUILD_VERSION=$version" >> $env:GITHUB_ENV
echo "Building version: $version"

- name: Restore dependencies
run: dotnet restore PrettyScreenSHOT.csproj

- name: Build solution
run: dotnet build PrettyScreenSHOT.csproj --configuration Release --no-restore /p:Version=${{ env.BUILD_VERSION }} /p:AssemblyVersion=${{ env.BUILD_VERSION }} /p:FileVersion=${{ env.BUILD_VERSION }} /p:InformationalVersion=${{ env.BUILD_VERSION }}-build.${{ github.run_number }}

- name: Restore test dependencies
run: dotnet restore Tests/PrettyScreenSHOT.Tests.csproj

- name: Build tests
run: dotnet build Tests/PrettyScreenSHOT.Tests.csproj --configuration Release --no-restore /p:Version=${{ env.BUILD_VERSION }}

- name: Run unit tests
run: dotnet test Tests/PrettyScreenSHOT.Tests.csproj --configuration Release --no-build --verbosity normal --logger "trx;LogFileName=test-results.trx" --collect:"XPlat Code Coverage"

- name: Display build version info
shell: pwsh
run: |
echo "✅ Build completed successfully"
echo "📦 Version: ${{ env.BUILD_VERSION }}"
echo "🔢 Build number: ${{ github.run_number }}"
echo "🌿 Branch: ${{ github.ref_name }}"

- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: test-results
path: '**/test-results.trx'

- name: Upload code coverage
if: always()
uses: actions/upload-artifact@v4
with:
name: code-coverage
path: '**/coverage.cobertura.xml'

- name: Publish build artifacts
uses: actions/upload-artifact@v4
with:
name: build-artifacts
path: |
bin/Release/net10.0-windows/
!bin/Release/net10.0-windows/**/*.pdb

code-quality:
name: Code Quality Analysis
runs-on: windows-latest
needs: build-and-test

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'

- name: Restore dependencies
run: dotnet restore PrettyScreenSHOT.csproj

- name: Build for analysis
run: dotnet build PrettyScreenSHOT.csproj --configuration Release --no-restore /p:TreatWarningsAsErrors=false

- name: Run code analysis
run: dotnet build PrettyScreenSHOT.csproj --configuration Release --no-restore /p:RunAnalyzers=true /p:AnalysisLevel=latest
continue-on-error: true

test-coverage-report:
name: Test Coverage Report
runs-on: windows-latest
needs: build-and-test
if: github.event_name == 'pull_request'

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Download coverage artifacts
uses: actions/download-artifact@v4
with:
name: code-coverage
path: coverage

- name: Code Coverage Summary
uses: irongut/CodeCoverageSummary@v1.3.0
with:
filename: coverage/**/coverage.cobertura.xml
badge: true
format: markdown
output: both
continue-on-error: true

- name: Add Coverage PR Comment
uses: marocchino/sticky-pull-request-comment@v2
if: github.event_name == 'pull_request'
with:
recreate: true
path: code-coverage-results.md
continue-on-error: true

security-scan:
name: Security Scan
runs-on: windows-latest
needs: build-and-test

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'

- name: Restore dependencies
run: dotnet restore PrettyScreenSHOT.csproj

- name: Run security audit
run: dotnet list package --vulnerable --include-transitive
continue-on-error: true

build-status:
name: Build Status Summary
runs-on: windows-latest
needs: [build-and-test, code-quality, security-scan]
if: always()

steps:
- name: Check build status
run: |
echo "Build and Test: ${{ needs.build-and-test.result }}"
echo "Code Quality: ${{ needs.code-quality.result }}"
echo "Security Scan: ${{ needs.security-scan.result }}"

- name: Report success
if: needs.build-and-test.result == 'success'
run: echo "✅ All checks passed!"

- name: Report failure
if: needs.build-and-test.result != 'success'
run: |
echo "❌ Build or tests failed!"
exit 1
166 changes: 166 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
name: Release Build

on:
push:
tags:
- 'v*.*.*'
workflow_dispatch:
inputs:
version:
description: 'Release version (e.g., 1.0.0)'
required: true
type: string

jobs:
create-release:
name: Create Release Build
runs-on: windows-latest

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'

- name: Extract and validate version
id: version
shell: pwsh
run: |
if ("${{ github.event_name }}" -eq "workflow_dispatch") {
$version = "${{ github.event.inputs.version }}"
} else {
$version = "${{ github.ref_name }}".TrimStart('v')
}

# Validate version format and determine release type
# Version scheme:
# 0.0.X = Development builds (X = build number) - handled by CI
# 0.X.0 = Pre-release/Beta (X = release number)
# X.0.0 = Full production release (X = major version)
if ($version -match '^(\d+)\.0\.0$') {
$releaseType = "production"
$versionLabel = "Production Release"
$isPrerelease = $false
} elseif ($version -match '^0\.(\d+)\.0$') {
$releaseType = "prerelease"
$versionLabel = "Pre-release/Beta"
$isPrerelease = $true
} elseif ($version -match '^0\.0\.(\d+)$') {
$releaseType = "development"
$versionLabel = "Development Build"
$isPrerelease = $true
} else {
# Fallback for any other semantic version
$releaseType = "custom"
$versionLabel = "Release"
$isPrerelease = $version -match '(alpha|beta|rc|dev)'
}

echo "VERSION=$version" >> $env:GITHUB_OUTPUT
echo "RELEASE_TYPE=$releaseType" >> $env:GITHUB_OUTPUT
echo "VERSION_LABEL=$versionLabel" >> $env:GITHUB_OUTPUT
echo "IS_PRERELEASE=$isPrerelease" >> $env:GITHUB_OUTPUT
echo "📦 Release version: v$version"
echo "🏷️ Release type: $versionLabel"
echo "🔖 Pre-release: $isPrerelease"

- name: Restore dependencies
run: dotnet restore PrettyScreenSHOT.csproj

- name: Build Release
run: dotnet build PrettyScreenSHOT.csproj --configuration Release --no-restore /p:Version=${{ steps.version.outputs.VERSION }}

- name: Run tests
run: dotnet test Tests/PrettyScreenSHOT.Tests.csproj --configuration Release --no-build --verbosity normal

- name: Publish Windows x64
run: dotnet publish PrettyScreenSHOT.csproj --configuration Release --runtime win-x64 --self-contained false --output publish/win-x64 /p:Version=${{ steps.version.outputs.VERSION }} /p:PublishSingleFile=false

- name: Publish Windows x64 Self-Contained
run: dotnet publish PrettyScreenSHOT.csproj --configuration Release --runtime win-x64 --self-contained true --output publish/win-x64-standalone /p:Version=${{ steps.version.outputs.VERSION }} /p:PublishSingleFile=true

- name: Create ZIP archives
shell: pwsh
run: |
Compress-Archive -Path publish/win-x64/* -DestinationPath PrettyScreenSHOT-v${{ steps.version.outputs.VERSION }}-win-x64.zip
Compress-Archive -Path publish/win-x64-standalone/* -DestinationPath PrettyScreenSHOT-v${{ steps.version.outputs.VERSION }}-win-x64-standalone.zip

- name: Generate checksums
shell: pwsh
run: |
Get-FileHash PrettyScreenSHOT-v${{ steps.version.outputs.VERSION }}-win-x64.zip -Algorithm SHA256 | Select-Object Hash, Path | Out-File -FilePath checksums.txt
Get-FileHash PrettyScreenSHOT-v${{ steps.version.outputs.VERSION }}-win-x64-standalone.zip -Algorithm SHA256 | Select-Object Hash, Path | Out-File -Append -FilePath checksums.txt

- name: Create Release Notes
shell: pwsh
run: |
$versionLabel = "${{ steps.version.outputs.VERSION_LABEL }}"
$releaseType = "${{ steps.version.outputs.RELEASE_TYPE }}"

@"
# PrettyScreenSHOT v${{ steps.version.outputs.VERSION }} - $versionLabel

## 🏷️ Release Information

- **Version:** ${{ steps.version.outputs.VERSION }}
- **Type:** $versionLabel
- **Build Date:** $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss UTC')

## 📦 Downloads

- **PrettyScreenSHOT-v${{ steps.version.outputs.VERSION }}-win-x64.zip** - Requires .NET 10.0 Runtime
- **PrettyScreenSHOT-v${{ steps.version.outputs.VERSION }}-win-x64-standalone.zip** - Standalone (includes runtime)

## 📋 Version Scheme

This project uses the following versioning scheme:
- **0.0.X** - Development builds (X = CI build number)
- **0.X.0** - Pre-release/Beta versions (X = release number)
- **X.0.0** - Full production releases (X = major version)

## ✅ Changes

See [CHANGELOG.md](https://github.com/${{ github.repository }}/blob/main/CHANGELOG.md) for details.

## 🔒 Checksums

SHA256 checksums are available in the checksums.txt file.

## 📝 Installation

1. Download the appropriate ZIP file
2. Extract to a folder
3. Run PrettyScreenSHOT.exe

For detailed instructions, see [INSTALLATION.md](https://github.com/${{ github.repository }}/blob/main/docs/installation/INSTALLATION.md).
"@ | Out-File -FilePath release-notes.md

- name: Upload Release Artifacts
uses: actions/upload-artifact@v4
with:
name: release-artifacts-v${{ steps.version.outputs.VERSION }}
path: |
PrettyScreenSHOT-v${{ steps.version.outputs.VERSION }}-win-x64.zip
PrettyScreenSHOT-v${{ steps.version.outputs.VERSION }}-win-x64-standalone.zip
checksums.txt
release-notes.md

- name: Create GitHub Release
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
uses: softprops/action-gh-release@v1
with:
files: |
PrettyScreenSHOT-v${{ steps.version.outputs.VERSION }}-win-x64.zip
PrettyScreenSHOT-v${{ steps.version.outputs.VERSION }}-win-x64-standalone.zip
checksums.txt
body_path: release-notes.md
draft: false
prerelease: ${{ steps.version.outputs.IS_PRERELEASE == 'True' }}
name: "v${{ steps.version.outputs.VERSION }} - ${{ steps.version.outputs.VERSION_LABEL }}"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Loading
Loading