Skip to content

Commit 54c0af8

Browse files
committed
Merge branch 'master' of https://github.com/PowerShell/PSResourceGet into bugfix-externalmoduledependecies
2 parents 0424405 + d389d79 commit 54c0af8

37 files changed

Lines changed: 2268 additions & 93 deletions

.ci/ci.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ pr:
1010
include:
1111
- master
1212

13+
parameters:
14+
- name: DSCVersion
15+
default: '3.2.0-rc.1'
16+
type: string
17+
1318
resources:
1419
repositories:
1520
- repository: ComplianceRepo
@@ -122,29 +127,34 @@ stages:
122127
jobName: TestPkgWin
123128
displayName: PowerShell Core on Windows
124129
imageName: windows-latest
130+
DSCVersion: ${{ parameters.DSCVersion }}
125131

126132
- template: test.yml
127133
parameters:
128134
jobName: TestPkgWinPS
129135
displayName: Windows PowerShell on Windows
130136
imageName: windows-latest
131137
powershellExecutable: powershell
138+
DSCVersion: ${{ parameters.DSCVersion }}
132139

133140
- template: test.yml
134141
parameters:
135142
jobName: TestPkgUbuntu
136143
displayName: PowerShell Core on Ubuntu
137144
imageName: ubuntu-latest
145+
DSCVersion: ${{ parameters.DSCVersion }}
138146

139147
- template: test.yml
140148
parameters:
141149
jobName: TestPkgWinMacOS
142150
displayName: PowerShell Core on macOS
143151
imageName: macOS-latest
152+
DSCVersion: ${{ parameters.DSCVersion }}
144153

145154
- template: test.yml
146155
parameters:
147156
jobName: TestPkgWinAzAuth
148157
displayName: AzAuth PowerShell Core on Windows
149158
imageName: windows-latest
150159
useAzAuth: true
160+
DSCVersion: ${{ parameters.DSCVersion }}

.ci/test.yml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ parameters:
55
powershellExecutable: pwsh
66
buildDirectory: '.'
77
useAzAuth: false
8+
DSCVersion: '3.2.0-rc.1'
89

910
jobs:
1011
- job: ${{ parameters.jobName }}
@@ -95,6 +96,56 @@ jobs:
9596
displayName: 'Setup Azure Artifacts Credential Provider secret'
9697
condition: eq(${{ parameters.useAzAuth }}, false)
9798

99+
- pwsh: |
100+
$version = '${{ parameters.DSCVersion }}'
101+
$packageName = "DSC-$version"
102+
$ext = 'tar.gz'
103+
$executableName = 'dsc'
104+
$executableExt = if ($IsWindows) { '.exe' } else { '' }
105+
106+
$uri = if ($IsWindows) {
107+
$ext = 'zip'
108+
"https://github.com/PowerShell/DSC/releases/download/v$version/DSC-$version-x86_64-pc-windows-msvc.zip"
109+
} elseif ($IsLinux) {
110+
"https://github.com/PowerShell/DSC/releases/download/v$version/DSC-$version-x86_64-linux.tar.gz"
111+
}
112+
elseif ($IsMacOS) {
113+
"https://github.com/PowerShell/DSC/releases/download/v$version/DSC-$version-x86_64-apple-darwin.tar.gz"
114+
115+
}
116+
else {
117+
throw "Unsupported OS platform"
118+
}
119+
120+
$destPath = Join-Path -Path $env:AGENT_TEMPDIRECTORY -ChildPath "$packageName.$ext"
121+
122+
Write-Verbose -Verbose "Downloading DSC v3 from $uri to $destPath"
123+
124+
Invoke-WebRequest -Uri $uri -OutFile $destPath
125+
126+
if ($IsWindows) {
127+
Expand-Archive -Path $destPath -DestinationPath $env:AGENT_TEMPDIRECTORY -Force -Verbose
128+
}
129+
else {
130+
tar -xzf $destPath -C $env:AGENT_TEMPDIRECTORY
131+
}
132+
133+
$executableFileName = $executableName + $executableExt
134+
135+
$executable = Get-ChildItem -Path $env:AGENT_TEMPDIRECTORY -File -Recurse -Verbose | Where-Object { $_.Name -eq $executableFileName } | Select-Object -First 1
136+
137+
if (-not $executable) {
138+
throw "Could not find dsc executable in the downloaded package"
139+
}
140+
141+
$dscRoot = Split-Path -Path $executable.FullName -Parent
142+
143+
$vstsCommandString = "vso[task.setvariable variable=DSC_ROOT]$dscRoot"
144+
Write-Host "sending " + $vstsCommandString
145+
Write-Host "##$vstsCommandString"
146+
147+
displayName: 'Install latest DSC v3'
148+
98149
- pwsh: |
99150
Get-ChildItem -Path env: | Out-String -width 9999 -Stream | Write-Verbose -Verbose
100151
displayName: Capture environment

doBuild.ps1

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ function DoBuild
4747
Write-Verbose -Verbose -Message "Copying PSResourceRepository.admx to '$BuildOutPath'"
4848
Copy-Item -Path "${SrcPath}/PSResourceRepository.admx" -Dest "$BuildOutPath" -Force
4949

50+
Write-Verbose -Verbose -Message "Copying psresourceget.ps1 to '$BuildOutPath'"
51+
Copy-Item -Path "${SrcPath}/dsc/psresourceget.ps1" -Dest "$BuildOutPath" -Force
52+
53+
Write-Verbose -Verbose -Message "Copying resource manifests to '$BuildOutPath'"
54+
Copy-Item -Path "${SrcPath}/dsc/*.resource.json" -Dest "$BuildOutPath" -Force
55+
5056
# Build and place binaries
5157
if ( Test-Path "${SrcPath}/code" ) {
5258
Write-Verbose -Verbose -Message "Building assembly and copying to '$BuildOutPath'"

src/code/RegisterPSResourceRepository.cs

Lines changed: 87 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,19 @@ class RegisterPSResourceRepository : PSCmdlet, IDynamicParameters
2929
#region Members
3030

3131
private readonly string PSGalleryRepoName = "PSGallery";
32+
private readonly string MicrosoftArtifactRegistryRepoName = "MicrosoftArtifactRegistry";
33+
private readonly string MicrosoftArtifactRegistryRepoUri = "https://mcr.microsoft.com";
3234
private readonly string PSGalleryRepoUri = "https://www.powershellgallery.com/api/v2";
3335
private const int DefaultPriority = 50;
3436
private const bool DefaultTrusted = false;
37+
private const bool MARDefaultTrusted = true;
38+
private const int MARDefaultPriority = 40;
3539
private const string NameParameterSet = "NameParameterSet";
3640
private const string PSGalleryParameterSet = "PSGalleryParameterSet";
3741
private const string RepositoriesParameterSet = "RepositoriesParameterSet";
3842
private Uri _uri;
3943
private CredentialProviderDynamicParameters _credentialProvider;
44+
private const string MARParameterSet = "MARParameterSet";
4045

4146
#endregion
4247

@@ -62,6 +67,13 @@ class RegisterPSResourceRepository : PSCmdlet, IDynamicParameters
6267
[Parameter(Mandatory = true, ParameterSetName = PSGalleryParameterSet, HelpMessage = "PSGallery switch used to indicate registering PSGallery repository.")]
6368
public SwitchParameter PSGallery { get; set; }
6469

70+
/// <summary>
71+
/// When specified, registers Microsoft Artifact Registry repository.
72+
/// </summary>
73+
[Parameter(Mandatory = true, ParameterSetName = MARParameterSet, HelpMessage = "Switch used to indicate registering Microsoft Artifact Registry repository.")]
74+
[Alias("MAR")]
75+
public SwitchParameter MicrosoftArtifactRegistry { get; set; }
76+
6577
/// <summary>
6678
/// Specifies a hashtable of repositories and is used to register multiple repositories at once.
6779
/// </summary>
@@ -74,6 +86,7 @@ class RegisterPSResourceRepository : PSCmdlet, IDynamicParameters
7486
/// </summary>
7587
[Parameter(ParameterSetName = NameParameterSet)]
7688
[Parameter(ParameterSetName = PSGalleryParameterSet)]
89+
[Parameter(ParameterSetName = MARParameterSet)]
7790
public SwitchParameter Trusted { get; set; }
7891

7992
/// <summary>
@@ -84,8 +97,9 @@ class RegisterPSResourceRepository : PSCmdlet, IDynamicParameters
8497
/// </summary>
8598
[Parameter(ParameterSetName = NameParameterSet)]
8699
[Parameter(ParameterSetName = PSGalleryParameterSet)]
100+
[Parameter(ParameterSetName = MARParameterSet)]
87101
[ValidateRange(0, 100)]
88-
public int Priority { get; set; } = DefaultPriority;
102+
public int Priority { get; set; }
89103

90104
/// <summary>
91105
/// Specifies the Api version of the repository to be set.
@@ -122,6 +136,7 @@ public object GetDynamicParameters()
122136
// It should also not appear when using the 'Repositories' parameter set.
123137
if (ParameterSetName.Equals(PSGalleryParameterSet) ||
124138
ParameterSetName.Equals(RepositoriesParameterSet) ||
139+
ParameterSetName.Equals(MARParameterSet) ||
125140
PSRepositoryInfo.IsValidContainerRegistryURL(Uri))
126141
{
127142
return null;
@@ -149,6 +164,18 @@ protected override void ProcessRecord()
149164
repoApiVersion = ApiVersion;
150165
}
151166

167+
if (!MyInvocation.BoundParameters.ContainsKey(nameof(Priority)))
168+
{
169+
if (ParameterSetName.Equals(MARParameterSet, StringComparison.OrdinalIgnoreCase))
170+
{
171+
Priority = MARDefaultPriority;
172+
}
173+
else
174+
{
175+
Priority = DefaultPriority;
176+
}
177+
}
178+
152179
PSRepositoryInfo.CredentialProviderType? credentialProvider = _credentialProvider?.CredentialProvider;
153180

154181
switch (ParameterSetName)
@@ -218,6 +245,25 @@ protected override void ProcessRecord()
218245
}
219246
break;
220247

248+
case MARParameterSet:
249+
if (MicrosoftArtifactRegistry)
250+
{
251+
try
252+
{
253+
bool trustedValue = Trusted.IsPresent ? Trusted : MARDefaultTrusted;
254+
items.Add(MicrosoftArtifactRegistryParameterSetHelper(Priority, trustedValue));
255+
}
256+
catch (Exception e)
257+
{
258+
ThrowTerminatingError(new ErrorRecord(
259+
new PSInvalidOperationException(e.Message),
260+
"ErrorInMARParameterSet",
261+
ErrorCategory.InvalidArgument,
262+
this));
263+
}
264+
}
265+
break;
266+
221267
default:
222268
Dbg.Assert(false, "Invalid parameter set");
223269
break;
@@ -262,6 +308,34 @@ private PSRepositoryInfo PSGalleryParameterSetHelper(int repoPriority, bool repo
262308
return addedRepo;
263309
}
264310

311+
private PSRepositoryInfo MicrosoftArtifactRegistryParameterSetHelper(int repoPriority, bool repoTrusted)
312+
{
313+
WriteDebug("In RegisterPSResourceRepository::MicrosoftArtifactRegistryParameterSetHelper()");
314+
Uri marUri = new Uri(MicrosoftArtifactRegistryRepoUri);
315+
WriteDebug("Internal name and uri values for Microsoft Artifact Registry are hardcoded and validated. Priority and trusted values, if passed in, also validated");
316+
var addedRepo = RepositorySettings.AddToRepositoryStore(MicrosoftArtifactRegistryRepoName,
317+
marUri,
318+
repoPriority,
319+
repoTrusted,
320+
apiVersion: null,
321+
repoCredentialInfo: null,
322+
credentialProvider: null,
323+
Force,
324+
this,
325+
out string errorMsg);
326+
327+
if (!string.IsNullOrEmpty(errorMsg))
328+
{
329+
ThrowTerminatingError(new ErrorRecord(
330+
new PSInvalidOperationException(errorMsg),
331+
"RepositoryCredentialSecretManagementUnavailableModule",
332+
ErrorCategory.ResourceUnavailable,
333+
this));
334+
}
335+
336+
return addedRepo;
337+
}
338+
265339
private List<PSRepositoryInfo> RepositoriesParameterSetHelper()
266340
{
267341
WriteDebug("In RegisterPSResourceRepository::RepositoriesParameterSetHelper()");
@@ -323,7 +397,7 @@ private PSRepositoryInfo RepoValidationHelper(Hashtable repo)
323397
return null;
324398
}
325399

326-
if (repo["Name"].ToString().Equals("PSGallery"))
400+
if (repo["Name"].ToString().Equals("PSGallery", StringComparison.OrdinalIgnoreCase))
327401
{
328402
WriteError(new ErrorRecord(
329403
new PSInvalidOperationException("Cannot register PSGallery with -Name parameter. Try: Register-PSResourceRepository -PSGallery"),
@@ -334,6 +408,17 @@ private PSRepositoryInfo RepoValidationHelper(Hashtable repo)
334408
return null;
335409
}
336410

411+
if (repo["Name"].ToString().Equals("MAR", StringComparison.OrdinalIgnoreCase))
412+
{
413+
WriteError(new ErrorRecord(
414+
new PSInvalidOperationException("Cannot register MAR with -Name parameter. The MAR repository is automatically registered. Try: Reset-PSResourceRepository to restore default repositories."),
415+
"MARProvidedAsNameRepoPSet",
416+
ErrorCategory.InvalidArgument,
417+
this));
418+
419+
return null;
420+
}
421+
337422
if (!repo.ContainsKey("Uri") || repo["Uri"] == null || String.IsNullOrEmpty(repo["Uri"].ToString()))
338423
{
339424
WriteError(new ErrorRecord(

src/code/RepositorySettings.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,12 @@ internal static class RepositorySettings
2626
// The repository store file's location is currently only at '%LOCALAPPDATA%\PSResourceGet' for the user account.
2727
private const string PSGalleryRepoName = "PSGallery";
2828
private const string PSGalleryRepoUri = "https://www.powershellgallery.com/api/v2";
29+
private const string MARRepoName = "MicrosoftArtifactRegistry";
30+
private const string MARRepoUri = "https://mcr.microsoft.com";
2931
private const int DefaultPriority = 50;
32+
private const int MARDefaultPriority = 40;
3033
private const bool DefaultTrusted = false;
34+
private const bool MARDefaultTrusted = true;
3135
private const string RepositoryFileName = "PSResourceRepository.xml";
3236
private static readonly string RepositoryPath = Path.Combine(Environment.GetFolderPath(
3337
Environment.SpecialFolder.LocalApplicationData), "PSResourceGet");
@@ -63,6 +67,10 @@ public static void CheckRepositoryStore()
6367
// Add PSGallery to the newly created store
6468
Uri psGalleryUri = new Uri(PSGalleryRepoUri);
6569
Add(PSGalleryRepoName, psGalleryUri, DefaultPriority, DefaultTrusted, repoCredentialInfo: null, repoCredentialProvider: CredentialProviderType.None, APIVersion.V2, force: false);
70+
71+
// Add MAR to the newly created store
72+
Uri marUri = new Uri(MARRepoUri);
73+
Add(MARRepoName, marUri, MARDefaultPriority, MARDefaultTrusted, repoCredentialInfo: null, repoCredentialProvider: CredentialProviderType.None, APIVersion.ContainerRegistry, force: false);
6674
}
6775

6876
// Open file (which should exist now), if cannot/is corrupted then throw error
@@ -85,6 +93,12 @@ public static PSRepositoryInfo AddRepository(string repoName, Uri repoUri, int r
8593
return null;
8694
}
8795

96+
if (repoName.Equals("MicrosoftArtifactRegistry", StringComparison.OrdinalIgnoreCase))
97+
{
98+
errorMsg = "Cannot register MAR with -Name parameter. Try: Register-PSResourceRepository -MicrosoftArtifactRegistry.";
99+
return null;
100+
}
101+
88102
return AddToRepositoryStore(repoName, repoUri, repoPriority, repoTrusted, apiVersion, repoCredentialInfo, repoCredentialProvider, force, cmdletPassedIn, out errorMsg);
89103
}
90104

@@ -187,6 +201,20 @@ public static PSRepositoryInfo UpdateRepositoryStore(string repoName, Uri repoUr
187201
return null;
188202
}
189203

204+
// check MAR Uri is not trying to be set
205+
if (repoName.Equals("MicrosoftArtifactRegistry", StringComparison.OrdinalIgnoreCase) && repoUri != null)
206+
{
207+
errorMsg = "The MAR repository has a predefined Uri. Setting the -Uri parameter for this repository is not allowed. Please run 'Reset-PSResourceRepository' to restore default repositories.";
208+
return null;
209+
}
210+
211+
// check MAR CredentialInfo is not trying to be set
212+
if (repoName.Equals("MicrosoftArtifactRegistry", StringComparison.OrdinalIgnoreCase) && repoCredentialInfo != null)
213+
{
214+
errorMsg = "Setting the -CredentialInfo parameter for MAR is not allowed. Run 'Reset-PSResourceRepository' to restore default repositories.";
215+
return null;
216+
}
217+
190218
// determine trusted value to pass in (true/false if set, null otherwise, hence the nullable bool variable)
191219
bool? _trustedNullable = isSet ? new bool?(repoTrusted) : new bool?();
192220

@@ -908,6 +936,10 @@ public static PSRepositoryInfo Reset(out string errorMsg)
908936
Uri psGalleryUri = new Uri(PSGalleryRepoUri);
909937
PSRepositoryInfo psGalleryRepo = Add(PSGalleryRepoName, psGalleryUri, DefaultPriority, DefaultTrusted, repoCredentialInfo: null, repoCredentialProvider: CredentialProviderType.None, APIVersion.V2, force: false);
910938

939+
// Add MAR to the newly created store
940+
Uri marUri = new Uri(MARRepoUri);
941+
Add(MARRepoName, marUri, MARDefaultPriority, MARDefaultTrusted, repoCredentialInfo: null, repoCredentialProvider: CredentialProviderType.None, APIVersion.ContainerRegistry, force: false);
942+
911943
// Clean up backup file on success
912944
if (!string.IsNullOrEmpty(backupFilePath) && File.Exists(backupFilePath))
913945
{

src/code/ResetPSResourceRepository.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace Microsoft.PowerShell.PSResourceGet.Cmdlets
1010
/// <summary>
1111
/// The Reset-PSResourceRepository cmdlet resets the repository store by creating a new PSRepositories.xml file.
1212
/// This is useful when the repository store becomes corrupted.
13-
/// It will create a new repository store with only the PSGallery repository registered.
13+
/// It will create a new repository store with PSGallery and MAR repositories registered.
1414
/// </summary>
1515
[Cmdlet(VerbsCommon.Reset,
1616
"PSResourceRepository",
@@ -39,8 +39,8 @@ protected override void ProcessRecord()
3939
"PSResourceRepository.xml");
4040

4141
WriteVerbose($"Resetting repository store at: {repositoryStorePath}");
42-
43-
if (!ShouldProcess(repositoryStorePath, "Reset repository store and create new PSRepositories.xml file with PSGallery registered"))
42+
43+
if (!ShouldProcess(repositoryStorePath, "Reset repository store and create new PSRepositories.xml file with PSGallery and MAR registered"))
4444
{
4545
return;
4646
}
@@ -57,7 +57,7 @@ protected override void ProcessRecord()
5757
return;
5858
}
5959

60-
WriteVerbose("Repository store reset successfully. PSGallery has been registered.");
60+
WriteVerbose("Repository store reset successfully. PSGallery and MAR have been registered.");
6161

6262
if (PassThru)
6363
{

0 commit comments

Comments
 (0)