diff --git a/.github/workflows/build-and-deploy.yml b/.github/workflows/build-and-deploy.yml
index 11d50ae..ca4591e 100644
--- a/.github/workflows/build-and-deploy.yml
+++ b/.github/workflows/build-and-deploy.yml
@@ -1,432 +1,432 @@
-name: Build and Deploy to NuGet
-
-on:
- push:
- branches: [ main, dev ]
- paths-ignore:
- - 'src/CloudNimble.DotNetDocs.Docs/**'
- - 'src/CloudNimble.DotNetDocs.Reference.Mintlify/**'
- - 'specs/**'
- workflow_dispatch:
- inputs:
- deploy_to_nuget:
- description: 'Deploy to NuGet'
- required: false
- default: 'false'
- type: choice
- options:
- - 'true'
- - 'false'
-
-permissions:
- contents: read
- actions: write
-
-env:
- DOTNET_VERSION: '10.0.x'
- SOLUTION_FILE: 'src/CloudNimble.DotNetDocs.slnx'
-
-jobs:
- build:
- runs-on: windows-latest
-
- steps:
- - name: Checkout code
- uses: actions/checkout@v5
- with:
- fetch-depth: 0 # Full history for versioning
-
- - name: Install .NET versions
- shell: pwsh
- run: |
- Write-Host "📥 Installing .NET versions..."
- # Install .NET 8, 9, 10
- $versions = @("8.0", "9.0", "10.0")
- foreach ($version in $versions) {
- Write-Host "Installing .NET $version..."
- Invoke-WebRequest -Uri "https://dot.net/v1/dotnet-install.ps1" -OutFile "dotnet-install.ps1"
- # if ($version -eq "10.0") {
- # ./dotnet-install.ps1 -Channel $version -Quality preview -InstallDir "$env:ProgramFiles\dotnet"
- # } else {
- ./dotnet-install.ps1 -Channel $version -InstallDir "$env:ProgramFiles\dotnet"
- # }
- }
-
- # Add to PATH for this job
- echo "$env:ProgramFiles\dotnet" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
-
- # Verify installation
- dotnet --list-sdks
-
- - name: Get version variables
- id: version
- shell: pwsh
- run: |
- # Get version components from repository variables
- $majorVersion = "${{ vars.VERSION_MAJOR }}"
- if ([string]::IsNullOrEmpty($majorVersion)) { $majorVersion = "1" }
-
- $minorVersion = "${{ vars.VERSION_MINOR }}"
- if ([string]::IsNullOrEmpty($minorVersion)) { $minorVersion = "0" }
-
- $patchVersion = "${{ vars.VERSION_PATCH }}"
- if ([string]::IsNullOrEmpty($patchVersion)) { $patchVersion = "0" }
-
- $previewSuffix = "${{ vars.VERSION_PREVIEW_SUFFIX }}"
- if ([string]::IsNullOrEmpty($previewSuffix)) { $previewSuffix = "0" }
-
- Write-Host "🔢 Version variables: MAJOR=$majorVersion, MINOR=$minorVersion, PATCH=$patchVersion, PREVIEW_SUFFIX=$previewSuffix"
-
- # Determine version based on branch
- $ref = "${{ github.ref }}"
- if ($ref -eq "refs/heads/main") {
- # Main branch: use patch version from repo variables
- Write-Host "🏷️ Main branch: using PATCH_VERSION from repo variables"
-
- $version = "$majorVersion.$minorVersion.$patchVersion"
- $buildNumber = $patchVersion
-
- # Calculate next patch version for update after successful deployment
- $nextPatchVersion = [int]$patchVersion + 1
- echo "NEXT_PATCH_VERSION=$nextPatchVersion" >> $env:GITHUB_OUTPUT
-
- Write-Host "✅ Main branch version: $version (next patch will be $nextPatchVersion)"
- }
- elseif ($ref -eq "refs/heads/dev") {
- # Dev branch: use preview versioning with incremented suffix
- $nextPreviewSuffix = [int]$previewSuffix + 1
- $version = "$majorVersion.$minorVersion.$patchVersion-preview.$nextPreviewSuffix"
- $buildNumber = 0
-
- # Store the next preview suffix for later update
- echo "NEXT_PREVIEW_SUFFIX=$nextPreviewSuffix" >> $env:GITHUB_OUTPUT
- Write-Host "✅ Dev branch version: $version (next suffix will be $nextPreviewSuffix)"
- }
- else {
- # Other branches (features/PRs): use CI versioning with timestamp
- $timestamp = Get-Date -Format "yyyyMMdd-HHmmss" -AsUTC
- $version = "$majorVersion.$minorVersion.$patchVersion-CI-$timestamp"
- $buildNumber = 0
- Write-Host "✅ Feature branch version: $version"
- }
-
- # Output variables
- echo "VERSION=$version" >> $env:GITHUB_OUTPUT
- echo "MAJOR_VERSION=$majorVersion" >> $env:GITHUB_OUTPUT
- echo "MINOR_VERSION=$minorVersion" >> $env:GITHUB_OUTPUT
- echo "PATCH_VERSION=$patchVersion" >> $env:GITHUB_OUTPUT
- echo "BUILD_NUMBER=$buildNumber" >> $env:GITHUB_OUTPUT
- echo "BRANCH_TYPE=$(if ($ref -eq 'refs/heads/main') { 'main' } elseif ($ref -eq 'refs/heads/dev') { 'dev' } else { 'feature' })" >> $env:GITHUB_OUTPUT
-
- Write-Host "📦 Final version: $version"
-
- - name: Update .docsproj SDK references
- shell: pwsh
- run: |
- $version = "${{ steps.version.outputs.VERSION }}"
- Write-Host "🔄 Updating .docsproj files to use DotNetDocs.Sdk/$version"
-
- # Find all .docsproj files
- $docsprojFiles = Get-ChildItem -Path "${{ github.workspace }}\src" -Filter "*.docsproj" -Recurse
-
- foreach ($file in $docsprojFiles) {
- Write-Host " 📝 Updating $($file.Name)..."
- $content = Get-Content $file.FullName -Raw
- $updatedContent = $content -replace 'Sdk="DotNetDocs\.Sdk/[^"]*"', "Sdk=`"DotNetDocs.Sdk/$version`""
- Set-Content -Path $file.FullName -Value $updatedContent -NoNewline
- }
-
- Write-Host "✅ Updated all .docsproj files to reference DotNetDocs.Sdk/$version"
-
- - name: Setup local NuGet feed
- shell: pwsh
- run: |
- $localFeedPath = "${{ vars.LOCAL_NUGET_FEED }}"
- if ([string]::IsNullOrEmpty($localFeedPath)) {
- $localFeedPath = "${{ github.workspace }}\local-nuget-feed"
- }
- New-Item -Path $localFeedPath -ItemType Directory -Force
- Write-Host "📁 Created local NuGet feed at: $localFeedPath"
- echo "LOCAL_NUGET_FEED=$localFeedPath" >> $env:GITHUB_ENV
-
- - name: Update NuGet.config for CI
- shell: pwsh
- run: |
- $localFeed = "${{ env.LOCAL_NUGET_FEED }}"
- $configPath = "${{ github.workspace }}\NuGet.config"
- "" | Out-File -FilePath $configPath -Encoding utf8
- "" | Add-Content -Path $configPath -Encoding utf8
- " " | Add-Content -Path $configPath -Encoding utf8
- " " | Add-Content -Path $configPath -Encoding utf8
- " " | Add-Content -Path $configPath -Encoding utf8
- " " | Add-Content -Path $configPath -Encoding utf8
- " " | Add-Content -Path $configPath -Encoding utf8
- " " | Add-Content -Path $configPath -Encoding utf8
- " " | Add-Content -Path $configPath -Encoding utf8
- " " | Add-Content -Path $configPath -Encoding utf8
- " " | Add-Content -Path $configPath -Encoding utf8
- " " | Add-Content -Path $configPath -Encoding utf8
- " " | Add-Content -Path $configPath -Encoding utf8
- " " | Add-Content -Path $configPath -Encoding utf8
- " " | Add-Content -Path $configPath -Encoding utf8
- " " | Add-Content -Path $configPath -Encoding utf8
- " " | Add-Content -Path $configPath -Encoding utf8
- "" | Add-Content -Path $configPath -Encoding utf8
- Write-Host "✅ Updated NuGet.config for CI build"
-
- - name: Build SDK project first
- shell: pwsh
- run: |
- Write-Host "🔨 Building DotNetDocs.Sdk with version ${{ steps.version.outputs.VERSION }}"
- Write-Host "📦 First, build the SDK Tasks project..."
- dotnet build src/CloudNimble.DotNetDocs.Sdk.Tasks/CloudNimble.DotNetDocs.Sdk.Tasks.csproj --configuration Release /p:Version=${{ steps.version.outputs.VERSION }}
- Write-Host "✅ SDK Tasks built successfully"
- Write-Host "🔧 Now packing the SDK project..."
- dotnet pack src/CloudNimble.DotNetDocs.Sdk/CloudNimble.DotNetDocs.Sdk.csproj --configuration Release --output "${{ env.LOCAL_NUGET_FEED }}" /p:Version=${{ steps.version.outputs.VERSION }} /p:PackageVersion=${{ steps.version.outputs.VERSION }}
- Write-Host "📦 SDK package created and pushed to local feed"
-
- - name: Restore dependencies
- run: dotnet restore ${{ env.SOLUTION_FILE }}
-
- - name: Build solution
- run: dotnet build ${{ env.SOLUTION_FILE }} --configuration Release --no-restore /p:Version=${{ steps.version.outputs.VERSION }} /p:PackageVersion=${{ steps.version.outputs.VERSION }}
-
- - name: Test
- working-directory: src
- run: dotnet test --configuration Release --no-build
-
- - name: Pack
- run: dotnet pack ${{ env.SOLUTION_FILE }} --configuration Release --no-build --output ./artifacts /p:PackageVersion=${{ steps.version.outputs.VERSION }}
-
- - name: Upload artifacts
- uses: actions/upload-artifact@v4
- with:
- name: nuget-packages
- path: ./artifacts/*.nupkg
- retention-days: 7
-
- deploy:
- needs: build
- runs-on: windows-latest
- if: |
- (github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev')) ||
- (github.event_name == 'workflow_dispatch' && github.event.inputs.deploy_to_nuget == 'true')
-
- steps:
- - name: Checkout code
- uses: actions/checkout@v5
-
- - name: Download artifacts
- uses: actions/download-artifact@v5
- with:
- name: nuget-packages
- path: ./artifacts
-
- - name: Get version data from build
- id: version
- shell: pwsh
- run: |
- # Re-calculate version data for this job (since we can't pass complex data between jobs)
- $majorVersion = "${{ vars.VERSION_MAJOR }}"
- if ([string]::IsNullOrEmpty($majorVersion)) { $majorVersion = "1" }
-
- $minorVersion = "${{ vars.VERSION_MINOR }}"
- if ([string]::IsNullOrEmpty($minorVersion)) { $minorVersion = "0" }
-
- $patchVersion = "${{ vars.VERSION_PATCH }}"
- if ([string]::IsNullOrEmpty($patchVersion)) { $patchVersion = "0" }
-
- $previewSuffix = "${{ vars.VERSION_PREVIEW_SUFFIX }}"
- if ([string]::IsNullOrEmpty($previewSuffix)) { $previewSuffix = "0" }
-
- $ref = "${{ github.ref }}"
- if ($ref -eq "refs/heads/main") {
- $nextPatchVersion = [int]$patchVersion + 1
- echo "NEXT_PATCH_VERSION=$nextPatchVersion" >> $env:GITHUB_OUTPUT
- echo "BRANCH_TYPE=main" >> $env:GITHUB_OUTPUT
- }
- elseif ($ref -eq "refs/heads/dev") {
- $nextPreviewSuffix = [int]$previewSuffix + 1
- echo "NEXT_PREVIEW_SUFFIX=$nextPreviewSuffix" >> $env:GITHUB_OUTPUT
- echo "BRANCH_TYPE=dev" >> $env:GITHUB_OUTPUT
- }
- else {
- echo "BRANCH_TYPE=other" >> $env:GITHUB_OUTPUT
- }
-
- - name: Install .NET versions
- shell: pwsh
- run: |
- Write-Host "📥 Installing .NET versions..."
- # Install .NET 8, 9, 10
- $versions = @("8.0", "9.0", "10.0")
- foreach ($version in $versions) {
- Write-Host "Installing .NET $version..."
- Invoke-WebRequest -Uri "https://dot.net/v1/dotnet-install.ps1" -OutFile "dotnet-install.ps1"
- if ($version -eq "10.0") {
- ./dotnet-install.ps1 -Channel $version -Quality preview -InstallDir "$env:ProgramFiles\dotnet"
- } else {
- ./dotnet-install.ps1 -Channel $version -InstallDir "$env:ProgramFiles\dotnet"
- }
- }
-
- # Add to PATH for this job
- echo "$env:ProgramFiles\dotnet" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
-
- - name: Push to NuGet
- id: nuget_push
- shell: pwsh
- run: |
- $deploymentSuccess = $true
- $errorMessage = ""
-
- Get-ChildItem ./artifacts/*.nupkg | ForEach-Object {
- Write-Host "📤 Pushing $($_.Name) to NuGet..."
- try {
- $result = dotnet nuget push $_.FullName `
- --api-key ${{ secrets.NUGET_API_KEY }} `
- --source https://api.nuget.org/v3/index.json `
- --skip-duplicate 2>&1
-
- Write-Host "✅ Push result: $result"
-
- # Check for specific error patterns
- if ($result -match "error.*unauthorized|invalid.*api.*key|403") {
- $deploymentSuccess = $false
- $errorMessage = "Authentication failed - invalid API key"
- Write-Host "❌ $errorMessage"
- }
- elseif ($result -match "error.*conflict|409|already exists") {
- Write-Host "⚠️ Package version already exists, continuing..."
- }
- elseif ($result -match "error") {
- $deploymentSuccess = $false
- $errorMessage = "Deployment failed: $result"
- Write-Host "❌ $errorMessage"
- }
- }
- catch {
- $deploymentSuccess = $false
- $errorMessage = "Exception during push: $($_.Exception.Message)"
- Write-Host "❌ $errorMessage"
- }
- }
-
- echo "DEPLOYMENT_SUCCESS=$deploymentSuccess" >> $env:GITHUB_OUTPUT
- echo "ERROR_MESSAGE=$errorMessage" >> $env:GITHUB_OUTPUT
-
- if (-not $deploymentSuccess) {
- Write-Host "💥 Deployment failed: $errorMessage"
- exit 1
- }
-
- - name: Update preview suffix (dev branch only)
- if: steps.version.outputs.BRANCH_TYPE == 'dev' && steps.nuget_push.outputs.DEPLOYMENT_SUCCESS == 'true'
- shell: pwsh
- env:
- GH_TOKEN: ${{ secrets.REPO_ACCESS_TOKEN }}
- run: |
- $nextSuffix = "${{ steps.version.outputs.NEXT_PREVIEW_SUFFIX }}"
- Write-Host "🔄 Updating VERSION_PREVIEW_SUFFIX to $nextSuffix"
-
- try {
- gh variable set VERSION_PREVIEW_SUFFIX --body "$nextSuffix"
- Write-Host "✅ Successfully updated VERSION_PREVIEW_SUFFIX to $nextSuffix"
- }
- catch {
- Write-Host "⚠️ Failed to update VERSION_PREVIEW_SUFFIX: $($_.Exception.Message)"
- # Don't fail the build for this
- }
-
- - name: Update patch version (main branch only)
- if: steps.version.outputs.BRANCH_TYPE == 'main' && steps.nuget_push.outputs.DEPLOYMENT_SUCCESS == 'true'
- shell: pwsh
- env:
- GH_TOKEN: ${{ secrets.REPO_ACCESS_TOKEN }}
- run: |
- $nextPatch = "${{ steps.version.outputs.NEXT_PATCH_VERSION }}"
- Write-Host "🔄 Updating VERSION_PATCH to $nextPatch and resetting VERSION_PREVIEW_SUFFIX to 0"
-
- try {
- gh variable set VERSION_PATCH --body "$nextPatch"
- Write-Host "✅ Successfully updated VERSION_PATCH to $nextPatch"
-
- gh variable set VERSION_PREVIEW_SUFFIX --body "0"
- Write-Host "✅ Successfully reset VERSION_PREVIEW_SUFFIX to 0"
- }
- catch {
- Write-Host "⚠️ Failed to update version variables: $($_.Exception.Message)"
- # Don't fail the build for this
- }
-
- create-release:
- needs: [build, deploy]
- runs-on: windows-latest
- if: |
- (github.event_name == 'push' && github.ref == 'refs/heads/main') ||
- (github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main' && github.event.inputs.deploy_to_nuget == 'true')
-
- steps:
- - name: Checkout code
- uses: actions/checkout@v5
-
- - name: Download artifacts
- uses: actions/download-artifact@v5
- with:
- name: nuget-packages
- path: ./artifacts
-
- - name: Get version from build
- id: version
- shell: pwsh
- run: |
- # Extract version from package name (assuming all have same version)
- $packageFile = Get-ChildItem ./artifacts/*.nupkg | Select-Object -First 1
- $version = $packageFile.Name -replace '.*\.(.+?)\.nupkg', '$1'
- echo "VERSION=$version" >> $env:GITHUB_OUTPUT
- Write-Host "📦 Creating release for version: $version"
-
- - name: Prepare Release Content
- id: create_release
- shell: pwsh
- run: |
- $version = "${{ steps.version.outputs.VERSION }}"
- $packages = Get-ChildItem ./artifacts/*.nupkg | ForEach-Object { $_.Name -replace '\.nupkg$', '' }
- $packageList = ""
- foreach ($package in $packages) {
- $packageName = $package -replace "\.$version$", ""
- $packageList += "- [$packageName](https://www.nuget.org/packages/$packageName/$version)`n"
- }
-
- $body = @"
- ## CloudNimble.DotNetDocs v$version
-
- ### 📦 NuGet Packages
- $packageList
-
- ### 🚀 What's Changed
- See [full changelog](https://github.com/${{ github.repository }}/compare/v${{ steps.version.outputs.PREVIOUS_VERSION }}...v$version)
-
- ### 📥 Installation
- ``````xml
-
-
-
- ``````
-
- ### 📦 Package Details
- This release includes the following NuGet packages:
- $packageList
- "@
-
- echo "RELEASE_BODY=$body" >> $env:GITHUB_OUTPUT
-
- - name: Create GitHub Release
- uses: softprops/action-gh-release@v2
- with:
- tag_name: v${{ steps.version.outputs.VERSION }}
- name: Release v${{ steps.version.outputs.VERSION }}
- body: ${{ steps.create_release.outputs.RELEASE_BODY }}
- files: ./artifacts/*.nupkg
- draft: false
+name: Build and Deploy to NuGet
+
+on:
+ push:
+ branches: [ main, dev ]
+ paths-ignore:
+ - 'src/CloudNimble.DotNetDocs.Docs/**'
+ - 'src/CloudNimble.DotNetDocs.Reference.Mintlify/**'
+ - 'specs/**'
+ workflow_dispatch:
+ inputs:
+ deploy_to_nuget:
+ description: 'Deploy to NuGet'
+ required: false
+ default: 'false'
+ type: choice
+ options:
+ - 'true'
+ - 'false'
+
+permissions:
+ contents: read
+ actions: write
+
+env:
+ DOTNET_VERSION: '10.0.x'
+ SOLUTION_FILE: 'src/CloudNimble.DotNetDocs.slnx'
+
+jobs:
+ build:
+ runs-on: windows-latest
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v5
+ with:
+ fetch-depth: 0 # Full history for versioning
+
+ - name: Install .NET versions
+ shell: pwsh
+ run: |
+ Write-Host "📥 Installing .NET versions..."
+ # Install .NET 8, 9, 10
+ $versions = @("8.0", "9.0", "10.0")
+ foreach ($version in $versions) {
+ Write-Host "Installing .NET $version..."
+ Invoke-WebRequest -Uri "https://dot.net/v1/dotnet-install.ps1" -OutFile "dotnet-install.ps1"
+ # if ($version -eq "10.0") {
+ # ./dotnet-install.ps1 -Channel $version -Quality preview -InstallDir "$env:ProgramFiles\dotnet"
+ # } else {
+ ./dotnet-install.ps1 -Channel $version -InstallDir "$env:ProgramFiles\dotnet"
+ # }
+ }
+
+ # Add to PATH for this job
+ echo "$env:ProgramFiles\dotnet" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
+
+ # Verify installation
+ dotnet --list-sdks
+
+ - name: Get version variables
+ id: version
+ shell: pwsh
+ run: |
+ # Get version components from repository variables
+ $majorVersion = "${{ vars.VERSION_MAJOR }}"
+ if ([string]::IsNullOrEmpty($majorVersion)) { $majorVersion = "1" }
+
+ $minorVersion = "${{ vars.VERSION_MINOR }}"
+ if ([string]::IsNullOrEmpty($minorVersion)) { $minorVersion = "0" }
+
+ $patchVersion = "${{ vars.VERSION_PATCH }}"
+ if ([string]::IsNullOrEmpty($patchVersion)) { $patchVersion = "0" }
+
+ $previewSuffix = "${{ vars.VERSION_PREVIEW_SUFFIX }}"
+ if ([string]::IsNullOrEmpty($previewSuffix)) { $previewSuffix = "0" }
+
+ Write-Host "🔢 Version variables: MAJOR=$majorVersion, MINOR=$minorVersion, PATCH=$patchVersion, PREVIEW_SUFFIX=$previewSuffix"
+
+ # Determine version based on branch
+ $ref = "${{ github.ref }}"
+ if ($ref -eq "refs/heads/main") {
+ # Main branch: use patch version from repo variables
+ Write-Host "🏷️ Main branch: using PATCH_VERSION from repo variables"
+
+ $version = "$majorVersion.$minorVersion.$patchVersion"
+ $buildNumber = $patchVersion
+
+ # Calculate next patch version for update after successful deployment
+ $nextPatchVersion = [int]$patchVersion + 1
+ echo "NEXT_PATCH_VERSION=$nextPatchVersion" >> $env:GITHUB_OUTPUT
+
+ Write-Host "✅ Main branch version: $version (next patch will be $nextPatchVersion)"
+ }
+ elseif ($ref -eq "refs/heads/dev") {
+ # Dev branch: use preview versioning with incremented suffix
+ $nextPreviewSuffix = [int]$previewSuffix + 1
+ $version = "$majorVersion.$minorVersion.$patchVersion-preview.$nextPreviewSuffix"
+ $buildNumber = 0
+
+ # Store the next preview suffix for later update
+ echo "NEXT_PREVIEW_SUFFIX=$nextPreviewSuffix" >> $env:GITHUB_OUTPUT
+ Write-Host "✅ Dev branch version: $version (next suffix will be $nextPreviewSuffix)"
+ }
+ else {
+ # Other branches (features/PRs): use CI versioning with timestamp
+ $timestamp = Get-Date -Format "yyyyMMdd-HHmmss" -AsUTC
+ $version = "$majorVersion.$minorVersion.$patchVersion-CI-$timestamp"
+ $buildNumber = 0
+ Write-Host "✅ Feature branch version: $version"
+ }
+
+ # Output variables
+ echo "VERSION=$version" >> $env:GITHUB_OUTPUT
+ echo "MAJOR_VERSION=$majorVersion" >> $env:GITHUB_OUTPUT
+ echo "MINOR_VERSION=$minorVersion" >> $env:GITHUB_OUTPUT
+ echo "PATCH_VERSION=$patchVersion" >> $env:GITHUB_OUTPUT
+ echo "BUILD_NUMBER=$buildNumber" >> $env:GITHUB_OUTPUT
+ echo "BRANCH_TYPE=$(if ($ref -eq 'refs/heads/main') { 'main' } elseif ($ref -eq 'refs/heads/dev') { 'dev' } else { 'feature' })" >> $env:GITHUB_OUTPUT
+
+ Write-Host "📦 Final version: $version"
+
+ - name: Update .docsproj SDK references
+ shell: pwsh
+ run: |
+ $version = "${{ steps.version.outputs.VERSION }}"
+ Write-Host "🔄 Updating .docsproj files to use DotNetDocs.Sdk/$version"
+
+ # Find all .docsproj files
+ $docsprojFiles = Get-ChildItem -Path "${{ github.workspace }}\src" -Filter "*.docsproj" -Recurse
+
+ foreach ($file in $docsprojFiles) {
+ Write-Host " 📝 Updating $($file.Name)..."
+ $content = Get-Content $file.FullName -Raw
+ $updatedContent = $content -replace 'Sdk="DotNetDocs\.Sdk/[^"]*"', "Sdk=`"DotNetDocs.Sdk/$version`""
+ Set-Content -Path $file.FullName -Value $updatedContent -NoNewline
+ }
+
+ Write-Host "✅ Updated all .docsproj files to reference DotNetDocs.Sdk/$version"
+
+ - name: Setup local NuGet feed
+ shell: pwsh
+ run: |
+ $localFeedPath = "${{ vars.LOCAL_NUGET_FEED }}"
+ if ([string]::IsNullOrEmpty($localFeedPath)) {
+ $localFeedPath = "${{ github.workspace }}\local-nuget-feed"
+ }
+ New-Item -Path $localFeedPath -ItemType Directory -Force
+ Write-Host "📁 Created local NuGet feed at: $localFeedPath"
+ echo "LOCAL_NUGET_FEED=$localFeedPath" >> $env:GITHUB_ENV
+
+ - name: Update NuGet.config for CI
+ shell: pwsh
+ run: |
+ $localFeed = "${{ env.LOCAL_NUGET_FEED }}"
+ $configPath = "${{ github.workspace }}\NuGet.config"
+ "" | Out-File -FilePath $configPath -Encoding utf8
+ "" | Add-Content -Path $configPath -Encoding utf8
+ " " | Add-Content -Path $configPath -Encoding utf8
+ " " | Add-Content -Path $configPath -Encoding utf8
+ " " | Add-Content -Path $configPath -Encoding utf8
+ " " | Add-Content -Path $configPath -Encoding utf8
+ " " | Add-Content -Path $configPath -Encoding utf8
+ " " | Add-Content -Path $configPath -Encoding utf8
+ " " | Add-Content -Path $configPath -Encoding utf8
+ " " | Add-Content -Path $configPath -Encoding utf8
+ " " | Add-Content -Path $configPath -Encoding utf8
+ " " | Add-Content -Path $configPath -Encoding utf8
+ " " | Add-Content -Path $configPath -Encoding utf8
+ " " | Add-Content -Path $configPath -Encoding utf8
+ " " | Add-Content -Path $configPath -Encoding utf8
+ " " | Add-Content -Path $configPath -Encoding utf8
+ " " | Add-Content -Path $configPath -Encoding utf8
+ "" | Add-Content -Path $configPath -Encoding utf8
+ Write-Host "✅ Updated NuGet.config for CI build"
+
+ - name: Build SDK project first
+ shell: pwsh
+ run: |
+ Write-Host "🔨 Building DotNetDocs.Sdk with version ${{ steps.version.outputs.VERSION }}"
+ Write-Host "📦 First, build the SDK Tasks project..."
+ dotnet build src/CloudNimble.DotNetDocs.Sdk.Tasks/CloudNimble.DotNetDocs.Sdk.Tasks.csproj --configuration Release /p:Version=${{ steps.version.outputs.VERSION }}
+ Write-Host "✅ SDK Tasks built successfully"
+ Write-Host "🔧 Now packing the SDK project..."
+ dotnet pack src/CloudNimble.DotNetDocs.Sdk/CloudNimble.DotNetDocs.Sdk.csproj --configuration Release --output "${{ env.LOCAL_NUGET_FEED }}" /p:Version=${{ steps.version.outputs.VERSION }} /p:PackageVersion=${{ steps.version.outputs.VERSION }}
+ Write-Host "📦 SDK package created and pushed to local feed"
+
+ - name: Restore dependencies
+ run: dotnet restore ${{ env.SOLUTION_FILE }}
+
+ - name: Build solution
+ run: dotnet build ${{ env.SOLUTION_FILE }} --configuration Release --no-restore /p:Version=${{ steps.version.outputs.VERSION }} /p:PackageVersion=${{ steps.version.outputs.VERSION }}
+
+ - name: Test
+ working-directory: src
+ run: dotnet test --configuration Release --no-build
+
+ - name: Pack
+ run: dotnet pack ${{ env.SOLUTION_FILE }} --configuration Release --no-build --output ./artifacts /p:PackageVersion=${{ steps.version.outputs.VERSION }}
+
+ - name: Upload artifacts
+ uses: actions/upload-artifact@v6
+ with:
+ name: nuget-packages
+ path: ./artifacts/*.nupkg
+ retention-days: 7
+
+ deploy:
+ needs: build
+ runs-on: windows-latest
+ if: |
+ (github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev')) ||
+ (github.event_name == 'workflow_dispatch' && github.event.inputs.deploy_to_nuget == 'true')
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v5
+
+ - name: Download artifacts
+ uses: actions/download-artifact@v5
+ with:
+ name: nuget-packages
+ path: ./artifacts
+
+ - name: Get version data from build
+ id: version
+ shell: pwsh
+ run: |
+ # Re-calculate version data for this job (since we can't pass complex data between jobs)
+ $majorVersion = "${{ vars.VERSION_MAJOR }}"
+ if ([string]::IsNullOrEmpty($majorVersion)) { $majorVersion = "1" }
+
+ $minorVersion = "${{ vars.VERSION_MINOR }}"
+ if ([string]::IsNullOrEmpty($minorVersion)) { $minorVersion = "0" }
+
+ $patchVersion = "${{ vars.VERSION_PATCH }}"
+ if ([string]::IsNullOrEmpty($patchVersion)) { $patchVersion = "0" }
+
+ $previewSuffix = "${{ vars.VERSION_PREVIEW_SUFFIX }}"
+ if ([string]::IsNullOrEmpty($previewSuffix)) { $previewSuffix = "0" }
+
+ $ref = "${{ github.ref }}"
+ if ($ref -eq "refs/heads/main") {
+ $nextPatchVersion = [int]$patchVersion + 1
+ echo "NEXT_PATCH_VERSION=$nextPatchVersion" >> $env:GITHUB_OUTPUT
+ echo "BRANCH_TYPE=main" >> $env:GITHUB_OUTPUT
+ }
+ elseif ($ref -eq "refs/heads/dev") {
+ $nextPreviewSuffix = [int]$previewSuffix + 1
+ echo "NEXT_PREVIEW_SUFFIX=$nextPreviewSuffix" >> $env:GITHUB_OUTPUT
+ echo "BRANCH_TYPE=dev" >> $env:GITHUB_OUTPUT
+ }
+ else {
+ echo "BRANCH_TYPE=other" >> $env:GITHUB_OUTPUT
+ }
+
+ - name: Install .NET versions
+ shell: pwsh
+ run: |
+ Write-Host "📥 Installing .NET versions..."
+ # Install .NET 8, 9, 10
+ $versions = @("8.0", "9.0", "10.0")
+ foreach ($version in $versions) {
+ Write-Host "Installing .NET $version..."
+ Invoke-WebRequest -Uri "https://dot.net/v1/dotnet-install.ps1" -OutFile "dotnet-install.ps1"
+ if ($version -eq "10.0") {
+ ./dotnet-install.ps1 -Channel $version -Quality preview -InstallDir "$env:ProgramFiles\dotnet"
+ } else {
+ ./dotnet-install.ps1 -Channel $version -InstallDir "$env:ProgramFiles\dotnet"
+ }
+ }
+
+ # Add to PATH for this job
+ echo "$env:ProgramFiles\dotnet" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
+
+ - name: Push to NuGet
+ id: nuget_push
+ shell: pwsh
+ run: |
+ $deploymentSuccess = $true
+ $errorMessage = ""
+
+ Get-ChildItem ./artifacts/*.nupkg | ForEach-Object {
+ Write-Host "📤 Pushing $($_.Name) to NuGet..."
+ try {
+ $result = dotnet nuget push $_.FullName `
+ --api-key ${{ secrets.NUGET_API_KEY }} `
+ --source https://api.nuget.org/v3/index.json `
+ --skip-duplicate 2>&1
+
+ Write-Host "✅ Push result: $result"
+
+ # Check for specific error patterns
+ if ($result -match "error.*unauthorized|invalid.*api.*key|403") {
+ $deploymentSuccess = $false
+ $errorMessage = "Authentication failed - invalid API key"
+ Write-Host "❌ $errorMessage"
+ }
+ elseif ($result -match "error.*conflict|409|already exists") {
+ Write-Host "⚠️ Package version already exists, continuing..."
+ }
+ elseif ($result -match "error") {
+ $deploymentSuccess = $false
+ $errorMessage = "Deployment failed: $result"
+ Write-Host "❌ $errorMessage"
+ }
+ }
+ catch {
+ $deploymentSuccess = $false
+ $errorMessage = "Exception during push: $($_.Exception.Message)"
+ Write-Host "❌ $errorMessage"
+ }
+ }
+
+ echo "DEPLOYMENT_SUCCESS=$deploymentSuccess" >> $env:GITHUB_OUTPUT
+ echo "ERROR_MESSAGE=$errorMessage" >> $env:GITHUB_OUTPUT
+
+ if (-not $deploymentSuccess) {
+ Write-Host "💥 Deployment failed: $errorMessage"
+ exit 1
+ }
+
+ - name: Update preview suffix (dev branch only)
+ if: steps.version.outputs.BRANCH_TYPE == 'dev' && steps.nuget_push.outputs.DEPLOYMENT_SUCCESS == 'true'
+ shell: pwsh
+ env:
+ GH_TOKEN: ${{ secrets.REPO_ACCESS_TOKEN }}
+ run: |
+ $nextSuffix = "${{ steps.version.outputs.NEXT_PREVIEW_SUFFIX }}"
+ Write-Host "🔄 Updating VERSION_PREVIEW_SUFFIX to $nextSuffix"
+
+ try {
+ gh variable set VERSION_PREVIEW_SUFFIX --body "$nextSuffix"
+ Write-Host "✅ Successfully updated VERSION_PREVIEW_SUFFIX to $nextSuffix"
+ }
+ catch {
+ Write-Host "⚠️ Failed to update VERSION_PREVIEW_SUFFIX: $($_.Exception.Message)"
+ # Don't fail the build for this
+ }
+
+ - name: Update patch version (main branch only)
+ if: steps.version.outputs.BRANCH_TYPE == 'main' && steps.nuget_push.outputs.DEPLOYMENT_SUCCESS == 'true'
+ shell: pwsh
+ env:
+ GH_TOKEN: ${{ secrets.REPO_ACCESS_TOKEN }}
+ run: |
+ $nextPatch = "${{ steps.version.outputs.NEXT_PATCH_VERSION }}"
+ Write-Host "🔄 Updating VERSION_PATCH to $nextPatch and resetting VERSION_PREVIEW_SUFFIX to 0"
+
+ try {
+ gh variable set VERSION_PATCH --body "$nextPatch"
+ Write-Host "✅ Successfully updated VERSION_PATCH to $nextPatch"
+
+ gh variable set VERSION_PREVIEW_SUFFIX --body "0"
+ Write-Host "✅ Successfully reset VERSION_PREVIEW_SUFFIX to 0"
+ }
+ catch {
+ Write-Host "⚠️ Failed to update version variables: $($_.Exception.Message)"
+ # Don't fail the build for this
+ }
+
+ create-release:
+ needs: [build, deploy]
+ runs-on: windows-latest
+ if: |
+ (github.event_name == 'push' && github.ref == 'refs/heads/main') ||
+ (github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main' && github.event.inputs.deploy_to_nuget == 'true')
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v5
+
+ - name: Download artifacts
+ uses: actions/download-artifact@v5
+ with:
+ name: nuget-packages
+ path: ./artifacts
+
+ - name: Get version from build
+ id: version
+ shell: pwsh
+ run: |
+ # Extract version from package name (assuming all have same version)
+ $packageFile = Get-ChildItem ./artifacts/*.nupkg | Select-Object -First 1
+ $version = $packageFile.Name -replace '.*\.(.+?)\.nupkg', '$1'
+ echo "VERSION=$version" >> $env:GITHUB_OUTPUT
+ Write-Host "📦 Creating release for version: $version"
+
+ - name: Prepare Release Content
+ id: create_release
+ shell: pwsh
+ run: |
+ $version = "${{ steps.version.outputs.VERSION }}"
+ $packages = Get-ChildItem ./artifacts/*.nupkg | ForEach-Object { $_.Name -replace '\.nupkg$', '' }
+ $packageList = ""
+ foreach ($package in $packages) {
+ $packageName = $package -replace "\.$version$", ""
+ $packageList += "- [$packageName](https://www.nuget.org/packages/$packageName/$version)`n"
+ }
+
+ $body = @"
+ ## CloudNimble.DotNetDocs v$version
+
+ ### 📦 NuGet Packages
+ $packageList
+
+ ### 🚀 What's Changed
+ See [full changelog](https://github.com/${{ github.repository }}/compare/v${{ steps.version.outputs.PREVIOUS_VERSION }}...v$version)
+
+ ### 📥 Installation
+ ``````xml
+
+
+
+ ``````
+
+ ### 📦 Package Details
+ This release includes the following NuGet packages:
+ $packageList
+ "@
+
+ echo "RELEASE_BODY=$body" >> $env:GITHUB_OUTPUT
+
+ - name: Create GitHub Release
+ uses: softprops/action-gh-release@v2
+ with:
+ tag_name: v${{ steps.version.outputs.VERSION }}
+ name: Release v${{ steps.version.outputs.VERSION }}
+ body: ${{ steps.create_release.outputs.RELEASE_BODY }}
+ files: ./artifacts/*.nupkg
+ draft: false
prerelease: false
\ No newline at end of file
diff --git a/.github/workflows/pr-validation.yml b/.github/workflows/pr-validation.yml
index 92c46d5..6dd5449 100644
--- a/.github/workflows/pr-validation.yml
+++ b/.github/workflows/pr-validation.yml
@@ -1,171 +1,171 @@
-name: PR Validation
-
-on:
- pull_request:
- branches: [ main, dev ]
- types: [opened, synchronize, reopened]
- paths-ignore:
- - 'src/CloudNimble.DotNetDocs.Docs/**'
- - 'src/CloudNimble.DotNetDocs.Reference.Mintlify/**'
- - 'specs/**'
- workflow_dispatch:
-
-permissions:
- contents: read
- actions: write
-
-env:
- DOTNET_VERSION: '10.0.x'
- SOLUTION_FILE: 'src/CloudNimble.DotNetDocs.slnx'
-
-jobs:
- validate:
- runs-on: windows-latest
-
- steps:
- - name: Checkout code
- uses: actions/checkout@v5
- with:
- fetch-depth: 0 # Full history for versioning
-
- - name: Install .NET versions
- shell: pwsh
- run: |
- Write-Host "📥 Installing .NET versions..."
- # Install .NET 8, 9, 10
- $versions = @("8.0", "9.0", "10.0")
- foreach ($version in $versions) {
- Write-Host "Installing .NET $version..."
- Invoke-WebRequest -Uri "https://dot.net/v1/dotnet-install.ps1" -OutFile "dotnet-install.ps1"
- # if ($version -eq "10.0") {
- # ./dotnet-install.ps1 -Channel $version -Quality preview -InstallDir "$env:ProgramFiles\dotnet"
- # } else {
- ./dotnet-install.ps1 -Channel $version -InstallDir "$env:ProgramFiles\dotnet"
- # }
- }
-
- # Add to PATH for this job
- echo "$env:ProgramFiles\dotnet" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
-
- # Verify installation
- dotnet --list-sdks
-
- - name: Get version variables
- id: version
- shell: pwsh
- run: |
- # Get version components from repository variables
- $majorVersion = "${{ vars.VERSION_MAJOR }}"
- if ([string]::IsNullOrEmpty($majorVersion)) { $majorVersion = "1" }
-
- $minorVersion = "${{ vars.VERSION_MINOR }}"
- if ([string]::IsNullOrEmpty($minorVersion)) { $minorVersion = "0" }
-
- Write-Host "🔢 Version variables: MAJOR=$majorVersion, MINOR=$minorVersion"
-
- # PR validation: always use CI versioning with timestamp (no version increment)
- $timestamp = Get-Date -Format "yyyyMMdd-HHmmss" -AsUTC
- $version = "$majorVersion.$minorVersion.0-CI-$timestamp"
-
- Write-Host "✅ PR validation version: $version"
-
- # Output variables
- echo "VERSION=$version" >> $env:GITHUB_OUTPUT
- echo "MAJOR_VERSION=$majorVersion" >> $env:GITHUB_OUTPUT
- echo "MINOR_VERSION=$minorVersion" >> $env:GITHUB_OUTPUT
-
- Write-Host "📦 Final version: $version"
-
- - name: Update .docsproj SDK references
- shell: pwsh
- run: |
- $version = "${{ steps.version.outputs.VERSION }}"
- Write-Host "🔄 Updating .docsproj files to use DotNetDocs.Sdk/$version"
-
- # Find all .docsproj files
- $docsprojFiles = Get-ChildItem -Path "${{ github.workspace }}\src" -Filter "*.docsproj" -Recurse
-
- foreach ($file in $docsprojFiles) {
- Write-Host " 📝 Updating $($file.Name)..."
- $content = Get-Content $file.FullName -Raw
- $updatedContent = $content -replace 'Sdk="DotNetDocs\.Sdk/[^"]*"', "Sdk=`"DotNetDocs.Sdk/$version`""
- Set-Content -Path $file.FullName -Value $updatedContent -NoNewline
- }
-
- Write-Host "✅ Updated all .docsproj files to reference DotNetDocs.Sdk/$version"
-
- - name: Setup local NuGet feed
- shell: pwsh
- run: |
- $localFeedPath = "${{ vars.LOCAL_NUGET_FEED }}"
- if ([string]::IsNullOrEmpty($localFeedPath)) {
- $localFeedPath = "${{ github.workspace }}\local-nuget-feed"
- }
- New-Item -Path $localFeedPath -ItemType Directory -Force
- Write-Host "📁 Created local NuGet feed at: $localFeedPath"
- echo "LOCAL_NUGET_FEED=$localFeedPath" >> $env:GITHUB_ENV
-
- - name: Update NuGet.config for CI
- shell: pwsh
- run: |
- $localFeed = "${{ env.LOCAL_NUGET_FEED }}"
- $configPath = "${{ github.workspace }}\NuGet.config"
- "" | Out-File -FilePath $configPath -Encoding utf8
- "" | Add-Content -Path $configPath -Encoding utf8
- " " | Add-Content -Path $configPath -Encoding utf8
- " " | Add-Content -Path $configPath -Encoding utf8
- " " | Add-Content -Path $configPath -Encoding utf8
- " " | Add-Content -Path $configPath -Encoding utf8
- " " | Add-Content -Path $configPath -Encoding utf8
- " " | Add-Content -Path $configPath -Encoding utf8
- " " | Add-Content -Path $configPath -Encoding utf8
- " " | Add-Content -Path $configPath -Encoding utf8
- " " | Add-Content -Path $configPath -Encoding utf8
- " " | Add-Content -Path $configPath -Encoding utf8
- " " | Add-Content -Path $configPath -Encoding utf8
- " " | Add-Content -Path $configPath -Encoding utf8
- " " | Add-Content -Path $configPath -Encoding utf8
- " " | Add-Content -Path $configPath -Encoding utf8
- " " | Add-Content -Path $configPath -Encoding utf8
- "" | Add-Content -Path $configPath -Encoding utf8
- Write-Host "✅ Updated NuGet.config for CI build"
-
- - name: Build SDK project first
- shell: pwsh
- run: |
- Write-Host "🔨 Building DotNetDocs.Sdk with version ${{ steps.version.outputs.VERSION }}"
- Write-Host "📦 First, build the SDK Tasks project..."
- dotnet build src/CloudNimble.DotNetDocs.Sdk.Tasks/CloudNimble.DotNetDocs.Sdk.Tasks.csproj --configuration Release /p:Version=${{ steps.version.outputs.VERSION }}
- Write-Host "✅ SDK Tasks built successfully"
- Write-Host "🔧 Now packing the SDK project..."
- dotnet pack src/CloudNimble.DotNetDocs.Sdk/CloudNimble.DotNetDocs.Sdk.csproj --configuration Release --output "${{ env.LOCAL_NUGET_FEED }}" /p:Version=${{ steps.version.outputs.VERSION }} /p:PackageVersion=${{ steps.version.outputs.VERSION }}
- Write-Host "📦 SDK package created and pushed to local feed"
-
- - name: Restore dependencies
- run: dotnet restore ${{ env.SOLUTION_FILE }}
-
- - name: Build solution
- run: dotnet build ${{ env.SOLUTION_FILE }} --configuration Release --no-restore /p:Version=${{ steps.version.outputs.VERSION }} /p:PackageVersion=${{ steps.version.outputs.VERSION }}
-
- - name: Test
- working-directory: src
- run: dotnet test --configuration Release --no-build
-
- - name: Pack
- run: dotnet pack ${{ env.SOLUTION_FILE }} --configuration Release --no-build --output ./artifacts /p:PackageVersion=${{ steps.version.outputs.VERSION }}
-
- - name: Upload artifacts
- uses: actions/upload-artifact@v4
- with:
- name: nuget-packages-pr
- path: ./artifacts/*.nupkg
- retention-days: 7
-
- - name: Validate packages
- shell: pwsh
- run: |
- Write-Host "📦 Validating NuGet packages..."
- Get-ChildItem ./artifacts/*.nupkg | ForEach-Object {
- Write-Host "✅ Found package: $($_.Name)"
- }
+name: PR Validation
+
+on:
+ pull_request:
+ branches: [ main, dev ]
+ types: [opened, synchronize, reopened]
+ paths-ignore:
+ - 'src/CloudNimble.DotNetDocs.Docs/**'
+ - 'src/CloudNimble.DotNetDocs.Reference.Mintlify/**'
+ - 'specs/**'
+ workflow_dispatch:
+
+permissions:
+ contents: read
+ actions: write
+
+env:
+ DOTNET_VERSION: '10.0.x'
+ SOLUTION_FILE: 'src/CloudNimble.DotNetDocs.slnx'
+
+jobs:
+ validate:
+ runs-on: windows-latest
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v5
+ with:
+ fetch-depth: 0 # Full history for versioning
+
+ - name: Install .NET versions
+ shell: pwsh
+ run: |
+ Write-Host "📥 Installing .NET versions..."
+ # Install .NET 8, 9, 10
+ $versions = @("8.0", "9.0", "10.0")
+ foreach ($version in $versions) {
+ Write-Host "Installing .NET $version..."
+ Invoke-WebRequest -Uri "https://dot.net/v1/dotnet-install.ps1" -OutFile "dotnet-install.ps1"
+ # if ($version -eq "10.0") {
+ # ./dotnet-install.ps1 -Channel $version -Quality preview -InstallDir "$env:ProgramFiles\dotnet"
+ # } else {
+ ./dotnet-install.ps1 -Channel $version -InstallDir "$env:ProgramFiles\dotnet"
+ # }
+ }
+
+ # Add to PATH for this job
+ echo "$env:ProgramFiles\dotnet" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
+
+ # Verify installation
+ dotnet --list-sdks
+
+ - name: Get version variables
+ id: version
+ shell: pwsh
+ run: |
+ # Get version components from repository variables
+ $majorVersion = "${{ vars.VERSION_MAJOR }}"
+ if ([string]::IsNullOrEmpty($majorVersion)) { $majorVersion = "1" }
+
+ $minorVersion = "${{ vars.VERSION_MINOR }}"
+ if ([string]::IsNullOrEmpty($minorVersion)) { $minorVersion = "0" }
+
+ Write-Host "🔢 Version variables: MAJOR=$majorVersion, MINOR=$minorVersion"
+
+ # PR validation: always use CI versioning with timestamp (no version increment)
+ $timestamp = Get-Date -Format "yyyyMMdd-HHmmss" -AsUTC
+ $version = "$majorVersion.$minorVersion.0-CI-$timestamp"
+
+ Write-Host "✅ PR validation version: $version"
+
+ # Output variables
+ echo "VERSION=$version" >> $env:GITHUB_OUTPUT
+ echo "MAJOR_VERSION=$majorVersion" >> $env:GITHUB_OUTPUT
+ echo "MINOR_VERSION=$minorVersion" >> $env:GITHUB_OUTPUT
+
+ Write-Host "📦 Final version: $version"
+
+ - name: Update .docsproj SDK references
+ shell: pwsh
+ run: |
+ $version = "${{ steps.version.outputs.VERSION }}"
+ Write-Host "🔄 Updating .docsproj files to use DotNetDocs.Sdk/$version"
+
+ # Find all .docsproj files
+ $docsprojFiles = Get-ChildItem -Path "${{ github.workspace }}\src" -Filter "*.docsproj" -Recurse
+
+ foreach ($file in $docsprojFiles) {
+ Write-Host " 📝 Updating $($file.Name)..."
+ $content = Get-Content $file.FullName -Raw
+ $updatedContent = $content -replace 'Sdk="DotNetDocs\.Sdk/[^"]*"', "Sdk=`"DotNetDocs.Sdk/$version`""
+ Set-Content -Path $file.FullName -Value $updatedContent -NoNewline
+ }
+
+ Write-Host "✅ Updated all .docsproj files to reference DotNetDocs.Sdk/$version"
+
+ - name: Setup local NuGet feed
+ shell: pwsh
+ run: |
+ $localFeedPath = "${{ vars.LOCAL_NUGET_FEED }}"
+ if ([string]::IsNullOrEmpty($localFeedPath)) {
+ $localFeedPath = "${{ github.workspace }}\local-nuget-feed"
+ }
+ New-Item -Path $localFeedPath -ItemType Directory -Force
+ Write-Host "📁 Created local NuGet feed at: $localFeedPath"
+ echo "LOCAL_NUGET_FEED=$localFeedPath" >> $env:GITHUB_ENV
+
+ - name: Update NuGet.config for CI
+ shell: pwsh
+ run: |
+ $localFeed = "${{ env.LOCAL_NUGET_FEED }}"
+ $configPath = "${{ github.workspace }}\NuGet.config"
+ "" | Out-File -FilePath $configPath -Encoding utf8
+ "" | Add-Content -Path $configPath -Encoding utf8
+ " " | Add-Content -Path $configPath -Encoding utf8
+ " " | Add-Content -Path $configPath -Encoding utf8
+ " " | Add-Content -Path $configPath -Encoding utf8
+ " " | Add-Content -Path $configPath -Encoding utf8
+ " " | Add-Content -Path $configPath -Encoding utf8
+ " " | Add-Content -Path $configPath -Encoding utf8
+ " " | Add-Content -Path $configPath -Encoding utf8
+ " " | Add-Content -Path $configPath -Encoding utf8
+ " " | Add-Content -Path $configPath -Encoding utf8
+ " " | Add-Content -Path $configPath -Encoding utf8
+ " " | Add-Content -Path $configPath -Encoding utf8
+ " " | Add-Content -Path $configPath -Encoding utf8
+ " " | Add-Content -Path $configPath -Encoding utf8
+ " " | Add-Content -Path $configPath -Encoding utf8
+ " " | Add-Content -Path $configPath -Encoding utf8
+ "" | Add-Content -Path $configPath -Encoding utf8
+ Write-Host "✅ Updated NuGet.config for CI build"
+
+ - name: Build SDK project first
+ shell: pwsh
+ run: |
+ Write-Host "🔨 Building DotNetDocs.Sdk with version ${{ steps.version.outputs.VERSION }}"
+ Write-Host "📦 First, build the SDK Tasks project..."
+ dotnet build src/CloudNimble.DotNetDocs.Sdk.Tasks/CloudNimble.DotNetDocs.Sdk.Tasks.csproj --configuration Release /p:Version=${{ steps.version.outputs.VERSION }}
+ Write-Host "✅ SDK Tasks built successfully"
+ Write-Host "🔧 Now packing the SDK project..."
+ dotnet pack src/CloudNimble.DotNetDocs.Sdk/CloudNimble.DotNetDocs.Sdk.csproj --configuration Release --output "${{ env.LOCAL_NUGET_FEED }}" /p:Version=${{ steps.version.outputs.VERSION }} /p:PackageVersion=${{ steps.version.outputs.VERSION }}
+ Write-Host "📦 SDK package created and pushed to local feed"
+
+ - name: Restore dependencies
+ run: dotnet restore ${{ env.SOLUTION_FILE }}
+
+ - name: Build solution
+ run: dotnet build ${{ env.SOLUTION_FILE }} --configuration Release --no-restore /p:Version=${{ steps.version.outputs.VERSION }} /p:PackageVersion=${{ steps.version.outputs.VERSION }}
+
+ - name: Test
+ working-directory: src
+ run: dotnet test --configuration Release --no-build
+
+ - name: Pack
+ run: dotnet pack ${{ env.SOLUTION_FILE }} --configuration Release --no-build --output ./artifacts /p:PackageVersion=${{ steps.version.outputs.VERSION }}
+
+ - name: Upload artifacts
+ uses: actions/upload-artifact@v6
+ with:
+ name: nuget-packages-pr
+ path: ./artifacts/*.nupkg
+ retention-days: 7
+
+ - name: Validate packages
+ shell: pwsh
+ run: |
+ Write-Host "📦 Validating NuGet packages..."
+ Get-ChildItem ./artifacts/*.nupkg | ForEach-Object {
+ Write-Host "✅ Found package: $($_.Name)"
+ }
Write-Host "✅ PR validation completed successfully"
\ No newline at end of file