diff --git a/.github/workflows/publish-powershell-gallery.yml b/.github/workflows/publish-powershell-gallery.yml deleted file mode 100644 index a8a640f..0000000 --- a/.github/workflows/publish-powershell-gallery.yml +++ /dev/null @@ -1,220 +0,0 @@ -name: Publish to PowerShell Gallery - -on: - push: - branches: [ main ] - paths: - - 'src/PSBlogger.psd1' - -jobs: - check-version: - runs-on: ubuntu-latest - outputs: - version-changed: ${{ steps.version-check.outputs.version-changed }} - new-version: ${{ steps.version-check.outputs.new-version }} - old-version: ${{ steps.version-check.outputs.old-version }} - steps: - - name: Checkout current commit - uses: actions/checkout@v4 - with: - fetch-depth: 2 - - - name: Check if version changed - id: version-check - shell: pwsh - run: | - # Get the current version from the manifest - $manifestPath = "src/PSBlogger.psd1" - $manifest = Import-PowerShellDataFile -Path $manifestPath - $currentVersion = $manifest.ModuleVersion - Write-Host "Current version: $currentVersion" - - # Get the previous version from the previous commit - git checkout HEAD~1 -- $manifestPath 2>$null - if ($LASTEXITCODE -eq 0) { - $previousManifest = Import-PowerShellDataFile -Path $manifestPath - $previousVersion = $previousManifest.ModuleVersion - Write-Host "Previous version: $previousVersion" - } else { - Write-Host "No previous version found (first commit?)" - $previousVersion = "0.0.0" - } - - # Restore current version - git checkout HEAD -- $manifestPath - - # Check if version changed - if ($currentVersion -ne $previousVersion) { - Write-Host "Version changed from $previousVersion to $currentVersion" - echo "version-changed=true" >> $env:GITHUB_OUTPUT - echo "new-version=$currentVersion" >> $env:GITHUB_OUTPUT - echo "old-version=$previousVersion" >> $env:GITHUB_OUTPUT - } else { - Write-Host "Version unchanged: $currentVersion" - echo "version-changed=false" >> $env:GITHUB_OUTPUT - echo "new-version=$currentVersion" >> $env:GITHUB_OUTPUT - echo "old-version=$previousVersion" >> $env:GITHUB_OUTPUT - } - - publish: - needs: check-version - if: needs.check-version.outputs.version-changed == 'true' - runs-on: windows-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Install PowerShell Module Dependencies - shell: pwsh - run: | - Set-PSRepository PSGallery -InstallationPolicy Trusted - Install-Module -Name PowerShell-Yaml -Force -SkipPublisherCheck - - - name: Validate Module Manifest - shell: pwsh - run: | - # Test module manifest - $manifestPath = "./src/PSBlogger.psd1" - Write-Host "Testing module manifest at: $manifestPath" - - # Test manifest syntax - $manifest = Test-ModuleManifest -Path $manifestPath -Verbose - Write-Host "Module manifest is valid" - Write-Host "Module Name: $($manifest.Name)" - Write-Host "Module Version: $($manifest.Version)" - Write-Host "Module Author: $($manifest.Author)" - Write-Host "Module Description: $($manifest.Description)" - - # Check required fields for PowerShell Gallery - if (-not $manifest.Description) { - throw "Module description is required for PowerShell Gallery" - } - if (-not $manifest.Author) { - throw "Module author is required for PowerShell Gallery" - } - - # Test that the module can be imported successfully - Import-Module $manifestPath -Force - $loadedModule = Get-Module PSBlogger - Write-Host "Successfully imported module. Exported commands:" - $loadedModule.ExportedCommands.Keys | Sort-Object | ForEach-Object { Write-Host " - $_" } - - - name: Run Tests - shell: pwsh - run: | - # Install Pester for testing - Install-Module -Name Pester -Force -SkipPublisherCheck - - # Install pandoc for tests - choco install pandoc -y - - # Change to src directory and run tests - Set-Location "./src" - - # Configure Pester - $PesterConfig = @{ - Run = @{ - Path = './tests' - } - Output = @{ - Verbosity = 'Normal' - } - Should = @{ - ErrorAction = 'Stop' - } - } - - # Run tests and fail if any tests fail - $testResults = Invoke-Pester -Configuration $PesterConfig - if ($testResults.FailedCount -gt 0) { - throw "Tests failed. Cannot publish to PowerShell Gallery." - } - - - name: Get Commit Messages for Release Notes - id: release-notes - shell: pwsh - run: | - # Get the previous tag - $previousTag = git describe --tags --abbrev=0 HEAD~1 2>$null - if ($LASTEXITCODE -ne 0) { - # If no previous tag, get all commits - $commits = git log --oneline --pretty=format:"- %s (%h)" - } else { - # Get commits since the previous tag - $commits = git log --oneline --pretty=format:"- %s (%h)" "$previousTag..HEAD" - } - - $releaseNotes = @" - ## Changes in version ${{ needs.check-version.outputs.new-version }} - - $($commits -join "`n") - "@ - - # Escape for GitHub Actions - $releaseNotes = $releaseNotes -replace "`r`n", "`n" -replace "`n", "%0A" - echo "release-notes=$releaseNotes" >> $env:GITHUB_OUTPUT - - - name: Create Git Tag - shell: pwsh - run: | - git config user.name "github-actions" - git config user.email "github-actions@github.com" - git tag -a "v${{ needs.check-version.outputs.new-version }}" -m "Release version ${{ needs.check-version.outputs.new-version }}" - git push origin "v${{ needs.check-version.outputs.new-version }}" - - - name: Create GitHub Release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: v${{ needs.check-version.outputs.new-version }} - release_name: Release v${{ needs.check-version.outputs.new-version }} - body: ${{ steps.release-notes.outputs.release-notes }} - draft: false - prerelease: false - - - name: Publish to PowerShell Gallery - shell: pwsh - env: - NUGET_API_KEY: ${{ secrets.POWERSHELLGALLERY_API }} - run: | - # Validate that we have the API key - if (-not $env:NUGET_API_KEY) { - throw "POWERSHELLGALLERY_API secret is not set" - } - - Write-Host "Publishing PSBlogger version ${{ needs.check-version.outputs.new-version }} to PowerShell Gallery..." - - # Check if this version already exists - try { - $existingModule = Find-Module -Name PSBlogger -RequiredVersion ${{ needs.check-version.outputs.new-version }} -ErrorAction SilentlyContinue - if ($existingModule) { - throw "Version ${{ needs.check-version.outputs.new-version }} already exists on PowerShell Gallery" - } - } catch { - if ($_.Exception.Message -notlike "*Version*already exists*") { - Write-Host "Could not check existing versions (this is normal for new modules): $($_.Exception.Message)" - } else { - throw - } - } - - # Publish the module - try { - Publish-Module -Path "./src" -NuGetApiKey $env:NUGET_API_KEY -Verbose -Force - Write-Host "โœ… Successfully published to PowerShell Gallery" - } catch { - Write-Error "โŒ Failed to publish to PowerShell Gallery: $_" - throw - } - - - name: Notify Success - if: success() - shell: pwsh - run: | - Write-Host "๐ŸŽ‰ Successfully published PSBlogger v${{ needs.check-version.outputs.new-version }} to PowerShell Gallery!" - Write-Host "๐Ÿ“ฆ Module is now available at: https://www.powershellgallery.com/packages/PSBlogger/${{ needs.check-version.outputs.new-version }}" - Write-Host "๐Ÿท๏ธ Created release: https://github.com/${{ github.repository }}/releases/tag/v${{ needs.check-version.outputs.new-version }}" diff --git a/.github/workflows/manual-publish-powershell-gallery.yml b/.github/workflows/publish.yml similarity index 61% rename from .github/workflows/manual-publish-powershell-gallery.yml rename to .github/workflows/publish.yml index 82df521..1058632 100644 --- a/.github/workflows/manual-publish-powershell-gallery.yml +++ b/.github/workflows/publish.yml @@ -1,6 +1,13 @@ -name: Manual Publish to PowerShell Gallery +name: PowerShell Gallery Publishing on: + # Automatic trigger: when module version changes on main branch + push: + branches: [ main ] + paths: + - 'src/PSBlogger.psd1' + + # Manual trigger: workflow dispatch with options workflow_dispatch: inputs: mode: @@ -17,13 +24,75 @@ on: type: string jobs: + # Version check job (only runs for automatic triggers) + check-version: + runs-on: ubuntu-latest + if: github.event_name == 'push' + outputs: + version-changed: ${{ steps.version-check.outputs.version-changed }} + new-version: ${{ steps.version-check.outputs.new-version }} + old-version: ${{ steps.version-check.outputs.old-version }} + steps: + - name: Checkout current commit + uses: actions/checkout@v4 + with: + fetch-depth: 2 + + - name: Check if version changed + id: version-check + shell: pwsh + run: | + # Get the current version from the manifest + $manifestPath = "src/PSBlogger.psd1" + $manifest = Import-PowerShellDataFile -Path $manifestPath + $currentVersion = $manifest.ModuleVersion + Write-Host "Current version: $currentVersion" + + # Get the previous version from the previous commit + git checkout HEAD~1 -- $manifestPath 2>$null + if ($LASTEXITCODE -eq 0) { + $previousManifest = Import-PowerShellDataFile -Path $manifestPath + $previousVersion = $previousManifest.ModuleVersion + Write-Host "Previous version: $previousVersion" + } else { + Write-Host "No previous version found (first commit?)" + $previousVersion = "0.0.0" + } + + # Restore current version + git checkout HEAD -- $manifestPath + + # Check if version changed + if ($currentVersion -ne $previousVersion) { + Write-Host "Version changed from $previousVersion to $currentVersion" + echo "version-changed=true" >> $env:GITHUB_OUTPUT + echo "new-version=$currentVersion" >> $env:GITHUB_OUTPUT + echo "old-version=$previousVersion" >> $env:GITHUB_OUTPUT + } else { + Write-Host "Version unchanged: $currentVersion" + echo "version-changed=false" >> $env:GITHUB_OUTPUT + echo "new-version=$currentVersion" >> $env:GITHUB_OUTPUT + echo "old-version=$previousVersion" >> $env:GITHUB_OUTPUT + } + + # Main publishing job publish: runs-on: windows-latest - if: github.event.inputs.mode == 'DRY_RUN' || (github.event.inputs.mode == 'PUBLISH' && github.event.inputs.confirm_publish == 'CONFIRM') + needs: [check-version] + if: | + always() && ( + (github.event_name == 'push' && needs.check-version.outputs.version-changed == 'true') || + (github.event_name == 'workflow_dispatch' && ( + github.event.inputs.mode == 'DRY_RUN' || + (github.event.inputs.mode == 'PUBLISH' && github.event.inputs.confirm_publish == 'CONFIRM') + )) + ) steps: - name: Checkout code uses: actions/checkout@v4 + with: + fetch-depth: 0 - name: Install PowerShell Module Dependencies shell: pwsh @@ -41,6 +110,21 @@ jobs: Write-Host "Module version: $version" echo "version=$version" >> $env:GITHUB_OUTPUT + - name: Determine Run Mode + id: run-mode + shell: pwsh + run: | + if ("${{ github.event_name }}" -eq "push") { + # Automatic publish on version change + echo "is-dry-run=false" >> $env:GITHUB_OUTPUT + echo "trigger-type=automatic" >> $env:GITHUB_OUTPUT + } else { + # Manual workflow dispatch + $isDryRun = "${{ github.event.inputs.mode }}" -eq "DRY_RUN" + echo "is-dry-run=$isDryRun" >> $env:GITHUB_OUTPUT + echo "trigger-type=manual" >> $env:GITHUB_OUTPUT + } + - name: Validate Module Manifest shell: pwsh run: | @@ -65,7 +149,9 @@ jobs: } # Test that the module can be imported successfully - Import-Module $manifestPath -Force + # Use absolute path to the manifest file + $manifestAbsolutePath = Resolve-Path $manifestPath + Import-Module $manifestAbsolutePath -Force $loadedModule = Get-Module PSBlogger Write-Host "Successfully imported module. Exported commands:" $loadedModule.ExportedCommands.Keys | Sort-Object | ForEach-Object { Write-Host " - $_" } @@ -104,16 +190,19 @@ jobs: - name: Publish to PowerShell Gallery shell: pwsh env: - NUGET_API_KEY: ${{ secrets.POWERSHELLGALLERY_API }} + NUGET_API_KEY: ${{ secrets.POWERSHELLGALLERY_APIKEY }} run: | - $isDryRun = "${{ github.event.inputs.mode }}" -eq "DRY_RUN" + $isDryRun = "${{ steps.run-mode.outputs.is-dry-run }}" -eq "true" + $triggerType = "${{ steps.run-mode.outputs.trigger-type }}" + Write-Host "๐Ÿ”ง Trigger: $triggerType" if ($isDryRun) { Write-Host "๐Ÿงช DRY RUN MODE - No actual publishing will occur" } else { + Write-Host "๐Ÿš€ PUBLISH MODE - Will publish to PowerShell Gallery" # Validate that we have the API key if (-not $env:NUGET_API_KEY) { - throw "POWERSHELLGALLERY_API secret is not set" + throw "POWERSHELLGALLERY_APIKEY secret is not set" } } @@ -139,11 +228,24 @@ jobs: # Publish the module try { + # Create a proper module structure for publishing + $tempModuleDir = Join-Path $env:TEMP "PSBlogger" + if (Test-Path $tempModuleDir) { + Remove-Item $tempModuleDir -Recurse -Force + } + New-Item -ItemType Directory -Path $tempModuleDir -Force | Out-Null + + # Copy module files excluding tests + Copy-Item "./src/PSBlogger.psd1" $tempModuleDir -Force + Copy-Item "./src/PSBlogger.psm1" $tempModuleDir -Force + Copy-Item "./src/private" $tempModuleDir -Recurse -Force + Copy-Item "./src/public" $tempModuleDir -Recurse -Force + if ($isDryRun) { - Publish-Module -Path "./src" -WhatIf -Verbose Write-Host "๐Ÿงช DRY RUN: Would publish to PowerShell Gallery (no actual publishing)" + Publish-Module -Path $tempModuleDir -NuGetApiKey $env:NUGET_API_KEY -WhatIf -Verbose } else { - Publish-Module -Path "./src" -NuGetApiKey $env:NUGET_API_KEY -Verbose -Force + Publish-Module -Path $tempModuleDir -NuGetApiKey $env:NUGET_API_KEY -Verbose -Force Write-Host "โœ… Successfully published to PowerShell Gallery" } } catch { @@ -152,14 +254,10 @@ jobs: } - name: Create Git Tag and Release + if: steps.run-mode.outputs.is-dry-run == 'false' shell: pwsh run: | - $isDryRun = "${{ github.event.inputs.mode }}" -eq "DRY_RUN" - - if ($isDryRun) { - Write-Host "๐Ÿงช DRY RUN: Would create tag v${{ steps.version.outputs.version }} and GitHub release" - return - } + Write-Host "๐Ÿท๏ธ Creating Git tag and GitHub release..." # Configure git git config user.name "github-actions" @@ -177,6 +275,7 @@ jobs: } - name: Get Commit Messages for Release Notes + if: steps.run-mode.outputs.is-dry-run == 'false' id: release-notes shell: pwsh run: | @@ -206,7 +305,7 @@ jobs: echo "release-notes=$releaseNotes" >> $env:GITHUB_OUTPUT - name: Create GitHub Release - if: github.event.inputs.mode == 'PUBLISH' + if: steps.run-mode.outputs.is-dry-run == 'false' uses: actions/create-release@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -221,7 +320,8 @@ jobs: if: success() shell: pwsh run: | - $isDryRun = "${{ github.event.inputs.mode }}" -eq "DRY_RUN" + $isDryRun = "${{ steps.run-mode.outputs.is-dry-run }}" -eq "true" + $triggerType = "${{ steps.run-mode.outputs.trigger-type }}" if ($isDryRun) { Write-Host "๐Ÿงช DRY RUN COMPLETED SUCCESSFULLY!" @@ -235,4 +335,5 @@ jobs: Write-Host "๐ŸŽ‰ Successfully published PSBlogger v${{ steps.version.outputs.version }} to PowerShell Gallery!" Write-Host "๐Ÿ“ฆ Module is now available at: https://www.powershellgallery.com/packages/PSBlogger/${{ steps.version.outputs.version }}" Write-Host "๐Ÿท๏ธ Created release: https://github.com/${{ github.repository }}/releases/tag/v${{ steps.version.outputs.version }}" + Write-Host "๐Ÿ”ง Triggered by: $triggerType" } diff --git a/src/PSBlogger.psd1 b/src/PSBlogger.psd1 index 10d6163..6fbeac7 100644 --- a/src/PSBlogger.psd1 +++ b/src/PSBlogger.psd1 @@ -47,7 +47,7 @@ PowerShellVersion = '5.1' RequiredModules = @("Powershell-yaml") # Assemblies that must be loaded prior to importing this module -RequiredAssemblies = '' +RequiredAssemblies = @() # Script files (.ps1) that are run in the caller's environment prior to importing this module. # ScriptsToProcess = @()