public/Publish-ToPSGallery.ps1

Function Publish-ToPSGallery
{
    <#
    .SYNOPSIS
    .DESCRIPTION
        This is a simple helper script to publish scripts to PSGallery
    .EXAMPLE
    .NOTES
    #>


    Param([Parameter(Mandatory=$true)]
          [String] 
          $PSGalleryKey  # Name of secure Repo for PSRepository
        , [String] $secureRepoName = 'N/A' # Name for secure Repo in powershell
        , [String] $secureRepopublishApiKey = 'N/A' # API URI for secure Repo
        , [String] $secureRepopublishApiURL = 'N/A' # API URI for secure Repo
        , [String] $secureRepoUser = 'N/A' # Repo credentials
        , [String] $secureRepoPass = 'N/A' # Repo credentials
        , [String] $codePath
        )

    # ==============================================================
    # INIT
    # ==============================================================
    if ($codePath -eq "" -or -not $codePath)
    {
        $codePath = $MyInvocation.PSScriptRoot
        try {
            test-path $codePath
        }
        catch {
            Write-Warning -Message "Unable to find codepath or myinvocation.psscriptroot variables. Defaulting to current path."
            $codePath = Get-Location
        }
    }
    If (-not (Test-Path $codePath)){Write-Error "Unable to find the local path for processing scripting";continue}

    $secureRepoParams = @{
        Name                      = $secureRepoName
        SourceLocation            = $secureRepopublishApiURL
        ScriptSourceLocation      = $secureRepopublishApiURL
        PublishLocation           = $secureRepopublishApiURL
        Credential                = [PSCredential]::New($secureRepoUser, ($secureRepoPass | ConvertTo-SecureString -AsPlainText -Force))
        InstallationPolicy        = 'Trusted'
        PackageManagementProvider = 'NuGet'
        Verbose                   = $true
    }

    $publicRepoParams = @{
        Name                      = 'PSGallery'
        SourceLocation            = 'https://www.powershellgallery.com/api/v2'
        ScriptSourceLocation      = 'https://www.powershellgallery.com/api/v2/'
        InstallationPolicy        = 'Trusted'
        PackageManagementProvider = 'NuGet'
        Verbose                   = $true
        PublishApiKey             = $PSGalleryKey
    }

    # ==============================================================
    # MAIN
    # ==============================================================
    If ($secureRepoName -ne 'N/A')
    {
        # This needs to be done each time for some reason... when you register a repo with credentials, the credentials are not reserved session to session
        "Registering PSRepository..."

        Unregister-PSRepository -Name $secureRepoParams.Name -WarningAction silentlycontinue -ErrorAction silentlycontinue
        Register-PSRepository @secureRepoParams
        
        # This needs to be added after registering the repo to recycle the splat params
        $secureRepoParams.PublishApiKey   = $secureRepopublishApiKey
    }

    Get-PackageProvider -Name NuGet -ForceBootstrap | Out-Null

    $currentPath = $PWD
    Set-Location $codePath

    $modules = Get-ChildItem ./modules/ -Directory
    ForEach($module in $modules)
    {
        $moduleName = $module.basename
        "Processing '$moduleName'..."

        #create paths
        $PublishModulePath = Join-Path $module.FullName /$moduleName
        $UserModulePath = Join-Path $env:USERPROFILE /Documents/WindowsPowerShell/Modules

        $null = Get-Content -Path "$PublishModulePath/$moduleName.psd1" | Where-Object { $_ -match 'ModuleVersion =(.*)' }
        $thisVersion = Invoke-Expression -Command $matches[1]

        $null = Get-Content -Path "$PublishModulePath/$moduleName.psd1" | Where-Object { $_ -match 'Tags =(.*)' }
        $Tags = Invoke-Expression -Command $matches[1]
        If ($tags -contains 'Private')
        {
            $moduleParams = @{
                Name            = $moduleName
                Repository      = $secureRepoParams.Name
                Credential      = $secureRepoParams.Credential
                NuGetApiKey     = $secureRepopublishApiKey
            }
        }
        elseIf ($tags -contains 'Public')
        {
            $moduleParams = @{
                Name            = $moduleName
                Repository      = $publicRepoParams.Name
                NuGetApiKey     = $publicRepoParams.PublishApiKey
            }
        }
        Else
        {
            " No public or private flag found for $moduleName... moving to next module"
            Continue
        }

        $pubModule = Find-Module -Name $moduleParams.Name -Repository $moduleParams.Repository -ErrorAction Ignore -WarningAction Ignore
        if ($pubmodule)
        {
            $pubVersion = $pubModule | Select-Object -Expand version
        }
        else
        {
            $pubVersion = '0.0.0'
        }
        " Published version of '$moduleName': $($pubVersion)"
        " This version of '$moduleName': $($thisVersion)"

        if ($thisVersion -gt $pubVersion)
        {
            " Published version is older than this version. Publishing '$moduleName' to repo $($moduleParams.Repository)..."
            copy-item $PublishModulePath $UserModulePath -force -Recurse
            Publish-Module @moduleParams -RequiredVersion $thisVersion
            Remove-Item (Join-Path $UserModulePath $moduleName) -Force -Recurse
        }
        else
        {
            " Published version is not older than this version. module '$moduleName' will not be published."
        }
    }

    Set-Location $codePath
    $scripts = Get-ChildItem ./scripts -File -Recurse -Filter "*.ps1"
    ForEach($script in $scripts)
    {
        $scriptName = $script.BaseName

        "Processing $scriptName..."

        $thisVersion = Test-ScriptFileInfo -Path $script.FullName | Select-Object -Expand version
        $Tags = Test-ScriptFileInfo -Path $script.FullName | Select-Object -Expand Tags

        If ($tags -contains 'Private')
        {
            $scriptParams = @{
                LiteralPath     = $script.FullName
                Repository      = $secureRepoParams.Name
                Credential      = $secureRepoParams.Credential
                NuGetApiKey     = $secureRepopublishApiKey 
            }
        }
        elseif ($tags -contains 'Public')
        {
            $scriptParams = @{
                LiteralPath     = $script.FullName
                Repository      = $publicRepoParams.Name
                NuGetApiKey     = $PSGalleryKey
            }
        }
        Else
        {
            " No public or private flag found for $scriptName... moving to next script"
            Continue
        }

        $pubscript = Find-script -Name $scriptName -Repository $scriptParams.Repository -ErrorAction Ignore -WarningAction Ignore
        if ($pubscript)
        {
            $pubVersion = $pubscript | Select-Object -Expand version
        }
        else
        {
            $pubVersion = '0.0.0'
        }
        " Published version of '$scriptName': $($pubVersion)"
        " This version of '$scriptName': $($thisVersion)"

        if ($thisVersion -gt $pubVersion)
        {
            " Published version is older than this version. Publishing '$scriptName' to repo $($scriptParams.Repository)..."
            Publish-script @scriptParams
        }
        else
        {
            " Published version is not older than this version. script '$scriptName' will not be published."
        }
    }
    Set-location $currentPath
}