Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
67 changes: 38 additions & 29 deletions src/code/PublishPSResource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,12 @@ namespace Microsoft.PowerShell.PSResourceGet.Cmdlets
"PSResource",
SupportsShouldProcess = true)]
[Alias("pbres")]
public sealed class PublishPSResource : PSCmdlet, IDynamicParameters
public sealed class PublishPSResource : PSCmdlet
{
#region Parameters

private const string PathParameterSet = "PathParameterSet";
private const string NupkgPathParameterSet = "NupkgPathParameterSet";
private ContainerRegistryDynamicParameters _pkgPrefix;

/// <summary>
/// Specifies the API key that you want to use to publish a module to the online gallery.
Expand Down Expand Up @@ -117,20 +116,12 @@ public PSCredential ProxyCredential {
[ValidateNotNullOrEmpty]
public string NupkgPath { get; set; }

#endregion

#region DynamicParameters
public object GetDynamicParameters()
{
PSRepositoryInfo repository = RepositorySettings.Read(new[] { Repository }, out string[] _).FirstOrDefault();
if (repository is not null && repository.ApiVersion == PSRepositoryInfo.APIVersion.ContainerRegistry)
{
_pkgPrefix = new ContainerRegistryDynamicParameters();
return _pkgPrefix;
}

return null;
}
/// <summary>
/// Prefix for module name which only applies to repositories of type 'ContainerRegistry'
/// </summary>
[Parameter]
[ValidateNotNullOrEmpty]
public string ModulePrefix { get; set; }

#endregion

Expand All @@ -151,16 +142,42 @@ protected override void BeginProcessing()

_networkCredential = Credential != null ? new NetworkCredential(Credential.UserName, Credential.Password) : null;

// Create the repository store file (PSResourceRepository.xml) if it does not already exist
// This is to create a better experience for those who have just installed v3 and want to get up and running quickly
RepositorySettings.CheckRepositoryStore();

if (MyInvocation.BoundParameters.ContainsKey(nameof(ModulePrefix)))
{
if (MyInvocation.BoundParameters.ContainsKey(nameof(Repository))) // can remove if Repository is 'Mandatory' parameter
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does "can remove if Repository is 'Mandatory' parameter" mean? What's being removed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just meant if we make the -Repository parameter mandatory for Publish-PSResource then I'll remove the check for seeing if Repository was included in the cmdlet invocation because that condition is guaranteed.

{
// at this point it is ensured PSResourceRepository.xml file is created
PSRepositoryInfo repository = RepositorySettings.Read(new[] { Repository }, out string[] _).FirstOrDefault();
if (repository is null || repository.ApiVersion != PSRepositoryInfo.APIVersion.ContainerRegistry)
{
ThrowTerminatingError(new ErrorRecord(
new PSInvalidOperationException("ModulePrefix parameter can only be provided for a registered repository of type 'ContainerRegistry'"),
"ModulePrefixParameterIncorrectlyProvided",
ErrorCategory.InvalidOperation,
this));
}
}
else
{
// can remove if Repository is 'Mandatory' parameter
ThrowTerminatingError(new ErrorRecord(
new PSInvalidOperationException("ModulePrefix parameter can only be provided with the Repository parameter."),
"ModulePrefixParameterProvidedWithoutRepositoryParameter",
ErrorCategory.InvalidOperation,
this));
}
}

if (!string.IsNullOrEmpty(NupkgPath))
{
_isNupkgPathSpecified = true;
Path = NupkgPath;
}

// Create a respository story (the PSResourceRepository.xml file) if it does not already exist
// This is to create a better experience for those who have just installed v3 and want to get up and running quickly
RepositorySettings.CheckRepositoryStore();

_publishHelper = new PublishHelper(
this,
Credential,
Expand All @@ -186,18 +203,10 @@ protected override void EndProcessing()
return;
}

string modulePrefix = _pkgPrefix?.ModulePrefix;

_publishHelper.PushResource(Repository, modulePrefix, SkipDependenciesCheck, _networkCredential);
_publishHelper.PushResource(Repository, ModulePrefix, SkipDependenciesCheck, _networkCredential);
}

#endregion

}

public class ContainerRegistryDynamicParameters
{
[Parameter]
public string ModulePrefix { get; set; }
}
}
40 changes: 40 additions & 0 deletions test/PublishPSResourceTests/PublishPSResource.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ Describe "Test Publish-PSResource" -tags 'CI' {

# Create test module with missing required module
CreateTestModule -Path $TestDrive -ModuleName 'ModuleWithMissingRequiredModule'

$script:PSGalleryName = 'PSGallery'
}
AfterAll {
Get-RevertPSResourceRepositoryFile
Expand Down Expand Up @@ -149,6 +151,44 @@ Describe "Test Publish-PSResource" -tags 'CI' {
(Get-ChildItem $script:repositoryPath).FullName | Should -Be $expectedPath
}

It "Publish should create PSResourceRepository.xml file if its not there" {
# Remove the PSResourceRepository.xml file
$powerShellGetPath = Join-Path -Path ([Environment]::GetFolderPath([System.Environment+SpecialFolder]::LocalApplicationData)) -ChildPath "PSResourceGet"
$originalXmlFilePath = Join-Path -Path $powerShellGetPath -ChildPath "PSResourceRepository.xml" #this is the temporary PSResourceRepository.xml file created in the 'BeforeAll' section of this test file

$tempXmlFilePath = Join-Path -Path $powerShellGetPath -ChildPath "tempfortest.xml"

if (Test-Path -Path $originalXmlFilePath) {
Copy-Item -Path $originalXmlFilePath -Destination $tempXmlFilePath
Remove-Item -Path $originalXmlFilePath -Force -ErrorAction Ignore
}

# Attempt to publish.
# Publish-PSResource should create PSResourceRepository.xml file if not present. It will register the 'PSGallery' repository as a default, so this test will still fail
# But we can ensure the PSResourceRepository.xml file is created.
$version = "1.0.0"
New-ModuleManifest -Path (Join-Path -Path $script:PublishModuleBase -ChildPath "$script:PublishModuleName.psd1") -ModuleVersion $version -Description "$script:PublishModuleName module"

Publish-PSResource -Path $script:PublishModuleBase -Repository $testRepository2 -ErrorVariable err -ErrorAction SilentlyContinue
$err[0].FullyQualifiedErrorId | Should -Be "RepositoryNotRegistered,Microsoft.PowerShell.PSResourceGet.Cmdlets.PublishPSResource"

$registeredRepos = Get-PSResourceRepository
$registeredRepos.Count | Should -Be 1
$registeredRepos[0].Name | Should -Be $script:PSGalleryName

# Cleanup
# Remove the new PSResourceRepository.xml file created by the Publish-PSResource command and put back the original created in the 'BeforeAll' section of this test file
if (Test-Path -Path $tempXmlFilePath) {
Copy-Item -Path $tempXmlFilePath -Destination $originalXmlFilePath -Force -Verbose
Remove-Item -Path $tempXmlFilePath -Force -ErrorAction Ignore
}

# Verify old repositories are restored
$originalRegisteredRepo = Get-PSResourceRepository -Name $testRepository2 -ErrorVariable err2 -ErrorAction SilentlyContinue
$err2.Count | Should -Be 0
$originalRegisteredRepo.Name | Should -Be $testRepository2
}

#region Local Source Path
It "Publish a module with -Path and -Repository" {
$version = "1.0.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ Describe "Test Publish-PSResource" -tags 'CI' {

# Path to specifically to that invalid test nupkgs folder
$script:testNupkgsFolderPath = Join-Path $script:testFilesFolderPath -ChildPath "testNupkgs"

$script:PSGalleryName = "PSGallery"
}
AfterEach {
if(!(Test-Path $script:PublishModuleBase))
Expand Down Expand Up @@ -515,6 +517,27 @@ Describe "Test Publish-PSResource" -tags 'CI' {
$results[0].Version | Should -Be $version
}

It "not Publish a resource when ModulePrefix is given for a Repository that is not of type ContainerRegistry"
{
$version = "1.0.0"
$modulePrefix = "unlisted"
New-ModuleManifest -Path (Join-Path -Path $script:PublishModuleBase -ChildPath "$script:PublishModuleName.psd1") -ModuleVersion $version -Description "$script:PublishModuleName module"

Publish-PSResource -Path $script:PublishModuleBase -Repository $script:PSGalleryName -ModulePrefix $modulePrefix -ErrorVariable err -ErrorAction SilentlyContinue
$err.Count | Should -Not -Be 0
$err[0].FullyQualifiedErrorId | Should -BeExactly "ModulePrefixParameterIncorrectlyProvided,Microsoft.PowerShell.PSResourceGet.Cmdlets.PublishPSResource"
}

It "not Publish a resource when ModulePrefix is provided without Repository parameter" {
$version = "1.0.0"
$modulePrefix = "unlisted"
New-ModuleManifest -Path (Join-Path -Path $script:PublishModuleBase -ChildPath "$script:PublishModuleName.psd1") -ModuleVersion $version -Description "$script:PublishModuleName module"

Publish-PSResource -Path $script:PublishModuleBase -ModulePrefix $modulePrefix -ErrorVariable err -ErrorAction SilentlyContinue
$err.Count | Should -Not -Be 0
$err[0].FullyQualifiedErrorId | Should -BeExactly "ModulePrefixParameterProvidedWithoutRepositoryParameter,Microsoft.PowerShell.PSResourceGet.Cmdlets.PublishPSResource"
}

It "Publish a package given NupkgPath to a package with .psd1" {
$packageName = "temp-testmodule-nupkgpath"
$version = "1.0.0.0"
Expand Down