-
-
Notifications
You must be signed in to change notification settings - Fork 69
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add initial PSGalleryScript implementation
- Loading branch information
1 parent
37c0e0f
commit 3d31dc5
Showing
7 changed files
with
351 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,202 @@ | ||
<# | ||
.SYNOPSIS | ||
Deploys a script to a PowerShell repository like the PowerShell Gallery. | ||
.DESCRIPTION | ||
Deploys a script to a PowerShell repository like the PowerShell Gallery. | ||
This only supports publishing items that do not already have a PSScriptInfo header. | ||
We might support this down the line when Update-ScriptFileInfo is fixed. | ||
Notes on how we define the PSScriptInfo header based on your WithOptions parameters and other info: | ||
* If you specify a WithOptions parameter, that takes precedence over an existing publication | ||
* If you do not specify a WithOptions parameter and have previously published this, | ||
we query and re-use data from the existing published script | ||
* In a few special cases (required fields), we will generate initial data if you | ||
do not include it in WithOptions or have an existing published script: | ||
GUID - We create a new GUID | ||
VERSION - we set to 1.0.0 | ||
AUTHOR - We set to Unknown | ||
DESCRIPTION - We set to the file name (e.g. if I publish Open-IseFunction.ps1, DESCRIPTION=Open-ISEFunction) | ||
.PARAMETER Deployment | ||
Deployment to run | ||
Source is the path of the module to deploy. | ||
Target is a valid PSRepository name. Defaults to PSGallery | ||
.PARAMETER ApiKey | ||
API Key used to authenticate to PowerShell repository. | ||
.PARAMETER VERSION | ||
VERSION for script info | ||
We set to 1.0.0 if you don't include it here or in a previously published version | ||
Note that you need to bump this for a successful publish, you can't overwrite an existing version | ||
.PARAMETER GUID | ||
GUID for script info | ||
We create a new one if you don't include it here or in a previously published version | ||
.PARAMETER AUTHOR | ||
AUTHOR for script info | ||
We set to unknown if you don't include it here or in a previously published version | ||
.PARAMETER DESCRIPTION | ||
DESCRIPTION for script info | ||
We set to the basename of your script if you don't include it here or in a previously published version | ||
.PARAMETER COMPANYNAME | ||
COMPANYNAME for script info | ||
.PARAMETER COPYRIGHT | ||
COPYRIGHT for script info | ||
.PARAMETER TAGS | ||
TAGS for script info | ||
.PARAMETER LICENSEURI | ||
LICENSEURI for script info | ||
.PARAMETER PROJECTURI | ||
PROJECTURI for script info | ||
.PARAMETER ICONURI | ||
ICONURI for script info | ||
.PARAMETER EXTERNALMODULEDEPENDENCIES | ||
EXTERNALMODULEDEPENDENCIES for script info | ||
.PARAMETER REQUIREDSCRIPTS | ||
REQUIREDSCRIPTS for script info | ||
.PARAMETER EXTERNALSCRIPTDEPENDENCIES | ||
EXTERNALSCRIPTDEPENDENCIES for script info | ||
.PARAMETER RELEASENOTES | ||
RELEASENOTES for script info | ||
#> | ||
[cmdletbinding()] | ||
param( | ||
[ValidateScript({ $_.PSObject.TypeNames[0] -eq 'PSDeploy.Deployment' })] | ||
[psobject[]]$Deployment, | ||
|
||
[Parameter(Mandatory)] | ||
[string]$ApiKey | ||
) | ||
|
||
# We make the assumption that WithOptions may be updated by the user or build process. It takes precedence. | ||
function Pick-Precedence { | ||
[cmdletbinding()] | ||
param( | ||
$Name, | ||
$PSGalleryOutput = $Existing | ||
) | ||
|
||
$WithOptionsValue = $null | ||
$WithOptionsValue = $Deploy.DeploymentOptions.$Name | ||
$ExistingValue = $null | ||
$ExistingValue = $PSGalleryOutput.$Name | ||
if($WithOptionsValue) | ||
{ | ||
$WithOptionsValue | ||
} | ||
else | ||
{ | ||
$ExistingValue | ||
} | ||
} | ||
|
||
foreach($deploy in $Deployment) { | ||
if(-not $deploy.Targets) | ||
{ | ||
#Default to the PSGallery | ||
$deploy.Targets = @('PSGallery') | ||
} | ||
foreach($target in $deploy.Targets) { | ||
Write-Verbose -Message "Starting deployment [$($deploy.DeploymentName)] to PowerShell repository [$Target]" | ||
|
||
# Validate that $target has been setup as a valid PowerShell repository | ||
$validRepo = Get-PSRepository -Name $target -Verbose:$false -ErrorAction SilentlyContinue | ||
if (-not $validRepo) { | ||
throw "[$target] has not been setup as a valid PowerShell repository." | ||
} | ||
|
||
# Check gallery for existing. We don't want a new GUID every time... | ||
$Name = ( Get-Item $Deploy.source -ErrorAction Stop ).BaseName | ||
$Existing = $null | ||
$Existing = @( Find-Script -Name $Name -Repository $Target ) | ||
if ($Existing.Count -gt 1) | ||
{ | ||
Write-Error "We found more than one script matching $Name. Did you include a wildcard?" | ||
continue | ||
} | ||
|
||
# guid is in the additionalmetadata hash | ||
$Existing[0] | Add-Member -MemberType NoteProperty -Name GUID -Value $Existing.AdditionalMetadata['GUID'] | ||
# Extract deployment options / header values. Not all of these are props. | ||
$AllNodes = echo VERSION GUID AUTHOR COMPANYNAME COPYRIGHT, | ||
TAGS LICENSEURI PROJECTURI ICONURI, | ||
EXTERNALMODULEDEPENDENCIES, REQUIREDSCRIPTS, | ||
EXTERNALSCRIPTDEPENDENCIES, RELEASENOTES, DESCRIPTION | ||
|
||
foreach($item in $AllNodes) | ||
{ | ||
$value = $null | ||
$value = Pick-Precedence -Name $Item -PSGalleryOutput $Existing | ||
Set-Variable -Name $Item -Value $value | ||
} | ||
|
||
# Items that might be blank on new scripts, that we need filled out | ||
if(-not $GUID) | ||
{ | ||
$GUID = [GUID]::NewGuid().Guid | ||
} | ||
if(-not $VERSION) | ||
{ | ||
$VERSION = '1.0.0' | ||
} | ||
if(-not $AUTHOR) | ||
{ | ||
$AUTHOR = 'Unknown' | ||
} | ||
if(-NOT $DESCRIPTION) | ||
{ | ||
$DESCRIPTION = $Name | ||
} | ||
|
||
# Build up the header | ||
$Header = "<#PSScriptInfo`r`n" | ||
$Nodes = echo VERSION GUID AUTHOR DESCRIPTION COMPANYNAME COPYRIGHT TAGS LICENSEURI PROJECTURI, | ||
ICONURI EXTERNALMODULEDEPENDENCIES REQUIREDSCRIPTS EXTERNALSCRIPTDEPENDENCIES RELEASENOTES | ||
|
||
foreach($item in $Nodes) | ||
{ | ||
$Value = $null | ||
If($Value = Get-Variable -Name $item -ValueOnly -ErrorAction SilentlyContinue) | ||
{ | ||
$header += ".$item`r`n $Value`r`n" | ||
} | ||
} | ||
|
||
$header += "#>`r`n" | ||
|
||
# Write the header, publish | ||
$SourceContent = Get-Content $Deploy.Source -Raw | ||
Set-Content $Deploy.Source -Value "$Header$SourceContent" -Force | ||
|
||
# Start building params | ||
$Params = @{ | ||
Path = $Deploy.Source | ||
Repository = $Target | ||
NugetApiKey = $Deploy.DeploymentOptions.ApiKey | ||
Verbose = $VerbosePreference | ||
} | ||
|
||
Publish-Script @params | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
Remove-Module PSDeploy -ErrorAction SilentlyContinue | ||
Import-Module $PSScriptRoot\..\..\PSDeploy\PSDeploy.psd1 | ||
Set-BuildEnvironment -Path $PSScriptRoot\..\.. | ||
|
||
|
||
InModuleScope 'PSDeploy' { | ||
$PSVersion = $PSVersionTable.PSVersion.Major | ||
$ProjectRoot = $ENV:BHProjectPath | ||
|
||
$Verbose = @{} | ||
if($ENV:BHBranchName -notlike "master" -or $env:BHCommitMessage -match "!verbose") | ||
{ | ||
$Verbose.add("Verbose",$True) | ||
} | ||
|
||
Describe "PSGalleryScript PS$PSVersion" { | ||
|
||
Context 'Publishes Script' { | ||
Mock Publish-Script { Return $true } | ||
Mock Get-PSRepository { Return $true } | ||
Mock Find-Script { } | ||
Mock Set-Content { } | ||
|
||
$Results = Invoke-PSDeploy @Verbose -Path "$ProjectRoot\Tests\artifacts\DeploymentsPSGalleryScript.psdeploy.ps1" -Force | ||
|
||
It 'Should execute Set-Content' { | ||
Assert-MockCalled Set-Content -Times 1 -Exactly | ||
} | ||
|
||
It 'Should execute Publish-Module' { | ||
Assert-MockCalled Publish-Script -Times 1 -Exactly | ||
} | ||
|
||
It 'Should Return Mocked output' { | ||
$Results | Should be $True | ||
} | ||
} | ||
|
||
Context 'Repository does not Exist' { | ||
Mock Publish-Script {} | ||
Mock Get-PSRepository { Return $false } | ||
Mock Find-Script { } | ||
Mock Set-Content { } | ||
|
||
It 'Throws because Repository could not be found' { | ||
$Results = { Invoke-PSDeploy @Verbose -Path "$ProjectRoot\Tests\artifacts\DeploymentsPSGalleryScript.psdeploy.ps1" -Force } | ||
$Results | Should Throw | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
Deploy TestScript { | ||
By PSGalleryScript { | ||
FromSource '\Scripts\Test-Script.ps1' | ||
To 'PSGallery' | ||
Tagged Testing | ||
WithOptions @{ | ||
ApiKey = '0c3e374b-49a3-4b05-a597-fd45773a4fb6' | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
function Open-ISEFunction { | ||
<# | ||
.SYNOPSIS | ||
Open a function in ISE | ||
.DESCRIPTION | ||
Open a function in ISE. Any function that can be obtained by (get-command <command>).definition. Pretty much anything that isn't compiled in a DLL or obfuscated in some other manner. | ||
.FUNCTIONALITY | ||
General Command | ||
#> | ||
[cmdletbinding()] | ||
param( | ||
|
||
#In the validation block, check if input is a function and get the definition | ||
[ValidateScript({ Get-Command -commandtype function -name $_ })] | ||
[string[]]$function | ||
) | ||
|
||
foreach($fn in $function){ | ||
|
||
#Get the definition | ||
$definition = (Get-Command -commandtype function -name $fn).definition | ||
|
||
#If the definition exists, add a new tab with the contents. | ||
if($definition){ | ||
|
||
#Definition won't include function keyword. Add it. | ||
$definition = "function $fn { $definition }" | ||
|
||
#Add the file and definition content | ||
$tab = $psise.CurrentPowerShellTab.files.Add() | ||
$tab.editor.text = $definition | ||
|
||
#set the caret to column 1 line 1 | ||
$tab.editor.SetCaretPosition(1,1) | ||
|
||
#Sleep a few milliseconds. Not sure why but omitting this has caused issues for me. | ||
start-sleep -Milliseconds 200 | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
This is a quick example showing a PSGalleryScript deployment: | ||
|
||
## Example | ||
|
||
Here's the deployment config, My.PSDeploy.ps1: | ||
|
||
```PowerShell | ||
Deploy Script { | ||
By PSGalleryScript { | ||
FromSource 'Relative\Path\To\This-Script.ps1' | ||
To PSGallery | ||
WithOptions @{ | ||
ApiKey = $ENV:NugetApiKey | ||
Version = $ENV:Version | ||
Author = "Warren F." | ||
Description = "A Description for the gallery" | ||
} | ||
} | ||
} | ||
``` | ||
|
||
In this example, we're deploying the script 'This-Script.ps1' using an API key stored in $ENV:NugetApiKey. | ||
|
||
The API key might be stored in a [secure variable](https://www.appveyor.com/docs/build-configuration#secure-variables) of some sort for your build system. | ||
|
||
## Notes | ||
|
||
WARNING: This deployment type will modify the content of your FromSource files, by appending a header with script info required by the PowerShell Gallery. | ||
|
||
Notes on how we define the PSScriptInfo header based on your WithOptions parameters and other info: | ||
|
||
* If you specify a WithOptions parameter, that takes precedence over an existing publication | ||
* If you do not specify a WithOptions parameter and have previously published this, we query and re-use data from the existing published script | ||
* In a few special cases (required fields), we will generate initial data if you do not include it in WithOptions or have an existing published script: | ||
* GUID - We create a new GUID | ||
* VERSION - we set to 1.0.0 | ||
* AUTHOR - We set to Unknown | ||
* DESCRIPTION - We set to the file name (e.g. if I publish Open-IseFunction.ps1, DESCRIPTION=Open-ISEFunction) | ||
|
||
No output is produced from this deployment type. | ||
|