Skip to content

Commit b783599

Browse files
ayousuf23t-ayousufAbdullah Yousuf
authored
Archive module preview 1 PR (#131)
* Add .gitattributes, .gitignore, and README.md. * Add project files. * added path helper, archive entry * updated path helper * resolved bug where GetEntryName was throwing an ArgumentException * fixed a bug, started work on zip support * worked on zip archive support * added ArchiveFactory class * imporved zip support * fixed a bug in tests, added error handling for DestinationPath * fixed bug in tests where Test-ZipArchive was not working correctly * added tests for DestinationPath * added additional tests, added TODOs * updated tests * added resx files for messages, refactored code, updated structure, etc. * refactored PathHelper class * worked on automatically determining archive format based on DestinationPath's extension * added support for determining archive format automatically based on DestinationPath's extension * fixed a bug with archive format warning, added TarArchive file * renamed Action to WriteMode, fixed bug with compressing directories, added support for tar, added support for overwrite * fixed bug where the directory structure of directories was not being preserved, fixed bug where error and warning messages were not being shown * addded exception handling to PathHelper class * removed files from git, removed tar support for preview release, added psd1 file * updated build script, updated exception handling in PathHelper * used FileSystemInfo instead of String to store full path information * updated checking for the same source path and destination path * updated build configuration * updated project version with prelease info, removed tar support after merging branches * updated CI config, fixed bug with missing error message, fixed tests * updated CI to build module and run tests across all platforms * updated CI to run tests, added and reorganized tests, solved a bug where overwriting the working directory could succeed * used pascal case for ArchiveFormat enum members, refactored some code based on feedback * fixed formatting for multiple files, updated csproj to generate Messages.Designer.cs and to remove debug symbols in Release config * fixed missing quotation mark in CI config, updated switch code in ArchiveFactory.TryGetArchiveFormatFromExtension, added another list to keep track of paths from -LiteralPath and -Path seperately * added assertions to prevent possible null error, added RequiredVersion when installing Pester in tests script, removed default valuesm in parameter attributes, and other minor changes * added localized messages for Add, Create, and progress bar text, minor formatting changes * added copyright header, removed usage of DS in tests, minor formatting changes * updated .gitignore, added explanation for why ArchiveAddition.EntryName is not necessarily equal to FileSystemInfo.Name * updated Compress-Archive cmdlet to resolve a path one at a time rather than collecting all paths first * fixed a bug where PathNotFound error was not thrown, fixed a bug when testing invalid paths * added custom assertions for testing zip archives * updated CI to run tests using new assertion, updated README with Azure CI status, fixed a bug where a path is determined to be relative to the working directory if the working directory is on a different drive than the path Co-authored-by: t-ayousuf <t-ayousuf@DESKTOP-SU5OBBS> Co-authored-by: Abdullah Yousuf <[email protected]>
1 parent 0d4537d commit b783599

38 files changed

+4910
-2829
lines changed

.azdevops/CI.yml

Lines changed: 37 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -27,51 +27,46 @@ stages:
2727
displayName: Build module
2828
steps:
2929

30-
- pwsh: |
31-
& $(Build.SourcesDirectory)\SimpleBuild.ps1
32-
displayName: Build Microsoft.PowerShell.Archive module
33-
condition: succeededOrFailed()
30+
- task: UseDotNet@2
31+
displayName: 'Get .NET 7.0 SDK'
32+
inputs:
33+
packageType: sdk
34+
version: 7.x
35+
includePreviewVersions: true
3436

3537
- pwsh: |
36-
dir "$(BuildOutDir)\*" -Recurse
37-
displayName: Show BuildOutDirectory
38-
39-
- template: Sbom.yml@ComplianceRepo
40-
parameters:
41-
BuildDropPath: "$(BuildOutDir)"
42-
Build_Repository_Uri: 'https://github.com/PowerShell/Microsoft.PowerShell.Archive'
43-
PackageName: $(PackageName)
44-
PackageVersion: $(PackageVersion)
45-
46-
- pwsh: |
47-
dir "$(BuildOutDir)\*" -Recurse
48-
displayName: Show BuildOutDirectory
38+
& "$(Build.SourcesDirectory)\Build.ps1"
39+
displayName: Build Microsoft.PowerShell.Archive module
4940
50-
- pwsh: |
51-
$signSrcPath = "$(BuildOutDir)"
52-
# Set signing src path variable
53-
$vstsCommandString = "vso[task.setvariable variable=signSrcPath]${signSrcPath}"
54-
Write-Host "sending " + $vstsCommandString
55-
Write-Host "##$vstsCommandString"
56-
$signOutPath = "$(Build.SourcesDirectory)\signed\Microsoft.PowerShell.Archive"
57-
$null = New-Item -ItemType Directory -Path $signOutPath
58-
# Set signing out path variable
59-
$vstsCommandString = "vso[task.setvariable variable=signOutPath]${signOutPath}"
60-
Write-Host "sending " + $vstsCommandString
61-
Write-Host "##$vstsCommandString"
62-
# Set path variable for guardian codesign validation
63-
$vstsCommandString = "vso[task.setvariable variable=GDN_CODESIGN_TARGETDIRECTORY]${signOutPath}"
64-
Write-Host "sending " + $vstsCommandString
65-
Write-Host "##$vstsCommandString"
66-
displayName: Setup variables for signing
41+
- task: CopyFiles@2
42+
displayName: 'Copy build'
43+
inputs:
44+
sourceFolder: '$(BuildOutDir)'
45+
contents: '**'
46+
targetFolder: '$(Build.ArtifactStagingDirectory)/Microsoft.PowerShell.Archive'
6747

68-
- pwsh: |
69-
Copy-Item -Path "$(signSrcPath)\*" -Destination "$(signOutPath)"
70-
displayName: Fake Signing
48+
- publish: '$(Build.ArtifactStagingDirectory)/Microsoft.PowerShell.Archive'
49+
displayName: 'Publish module build'
50+
artifact: ModuleBuild
7151

72-
- pwsh: |
73-
Compress-Archive -Path "$(signOutPath)\*" -DestinationPath "$(System.ArtifactsDirectory)\Microsoft.PowerShell.Archive.zip"
74-
displayName: Create Microsoft.PowerShell.Archive.zip
52+
- stage: Test
53+
dependsOn: Build
54+
displayName: Run tests
55+
jobs:
56+
- template: TestsTemplate.yml
57+
parameters:
58+
vmImageName: windows-2019
59+
jobName: run_test_windows
60+
jobDisplayName: Run Windows tests
7561

76-
- publish: $(System.ArtifactsDirectory)\Microsoft.PowerShell.Archive.zip
77-
artifact: SignedModule
62+
- template: TestsTemplate.yml
63+
parameters:
64+
vmImageName: ubuntu-latest
65+
jobName: run_test_linux
66+
jobDisplayName: Run Linux tests
67+
68+
- template: TestsTemplate.yml
69+
parameters:
70+
vmImageName: macos-latest
71+
jobName: run_test_macos
72+
jobDisplayName: Run macOS tests

.azdevops/ReleaseBuildPipeline.yml

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
name: Microsoft.PowerShell.Archive-$(Build.BuildId)
2+
trigger: none
3+
4+
pr: none
5+
6+
variables:
7+
DOTNET_CLI_TELEMETRY_OPTOUT: 1
8+
POWERSHELL_TELEMETRY_OPTOUT: 1
9+
10+
resources:
11+
repositories:
12+
- repository: ComplianceRepo
13+
type: github
14+
endpoint: ComplianceGHRepo
15+
name: PowerShell/compliance
16+
ref: master
17+
18+
stages:
19+
- stage: Build
20+
displayName: Build
21+
pool:
22+
name: 1ES
23+
demands:
24+
- ImageOverride -equals PSMMS2019-Secure
25+
jobs:
26+
- job: Build_Job
27+
displayName: Build Microsoft.PowerShell.Archive
28+
variables:
29+
- group: ESRP
30+
steps:
31+
- checkout: self
32+
33+
- task: UseDotNet@2
34+
displayName: 'Get .NET 7.0 SDK'
35+
inputs:
36+
packageType: sdk
37+
version: 7.x
38+
includePreviewVersions: true
39+
40+
- pwsh: |
41+
& $(Build.SourcesDirectory)/Microsoft.PowerShell.Archive/SimpleBuild.ps1
42+
displayName: Build Microsoft.PowerShell.Archive module
43+
44+
- pwsh: |
45+
Get-ChildItem "$(BuildOutDir)\*" -Recurse | Write-Verbose -Verbose
46+
displayName: Show BuildOutDirectory
47+
48+
- pwsh: |
49+
$signSrcPath = "$(BuildOutDir)"
50+
# Set signing src path variable
51+
$vstsCommandString = "vso[task.setvariable variable=signSrcPath]${signSrcPath}"
52+
Write-Host "sending " + $vstsCommandString
53+
Write-Host "##$vstsCommandString"
54+
# Get the module version
55+
$ManifestPath = Join-Path $(BuildOutDir) "Microsoft.PowerShell.Archive.psd1"
56+
$ManifestData = Import-PowerShellDataFile -Path $ManifestPath
57+
$Version = $ManifestData.ModuleVersion
58+
$signOutPath = "$(Build.SourcesDirectory)\signed\Microsoft.PowerShell.Archive\${Version}"
59+
$null = New-Item -ItemType Directory -Path $signOutPath
60+
# Set signing out path variable
61+
$vstsCommandString = "vso[task.setvariable variable=signOutPath]${signOutPath}"
62+
Write-Host "sending " + $vstsCommandString
63+
Write-Host "##$vstsCommandString"
64+
# Set path variable for guardian codesign validation
65+
$vstsCommandString = "vso[task.setvariable variable=GDN_CODESIGN_TARGETDIRECTORY]${signOutPath}"
66+
Write-Host "sending " + $vstsCommandString
67+
Write-Host "##$vstsCommandString"
68+
displayName: Setup variables for signing
69+
70+
- checkout: ComplianceRepo
71+
72+
- task: UseDotNet@2
73+
displayName: 'Get .NET 2.1 SDK'
74+
inputs:
75+
packageType: sdk
76+
version: 2.x
77+
includePreviewVersions: true
78+
79+
- template: EsrpSign.yml@ComplianceRepo
80+
parameters:
81+
# the folder which contains the binaries to sign
82+
buildOutputPath: $(signSrcPath)
83+
# the location to put the signed output
84+
signOutputPath: $(signOutPath)
85+
# the certificate ID to use
86+
certificateId: "CP-230012"
87+
# the file pattern to use, comma separated
88+
pattern: '*.psd1,*.dll'
89+
90+
- template: Sbom.yml@ComplianceRepo
91+
parameters:
92+
BuildDropPath: $(signOutPath)
93+
Build_Repository_Uri: 'https://github.com/PowerShell/Microsoft.PowerShell.Archive'
94+
95+
- pwsh: |
96+
Get-ChildItem $(signOutPath) -Recurse | Write-Output
97+
98+
- pwsh: |
99+
Set-Location "$(Build.SourcesDirectory)"
100+
# signOutPath points to directory with version number -- we want to point to the parent of that directory
101+
$ModulePath = Split-Path $(signOutPath) -Parent
102+
$(Build.SourcesDirectory)/Microsoft.PowerShell.Archive/.azdevops/SignAndPackageModule.ps1 -SignedPath $ModulePath
103+
Get-ChildItem -recurse -file -name | Write-Verbose -Verbose
104+
displayName: package build
105+
106+
- publish: "$(signSrcPath)"
107+
artifact: build
108+
displayName: Publish build
109+
110+
- stage: compliance
111+
displayName: Compliance
112+
dependsOn: Build
113+
jobs:
114+
- job: Compliance_Job
115+
pool:
116+
name: 1ES # Package ES CodeHub Lab E
117+
steps:
118+
- checkout: self
119+
- checkout: ComplianceRepo
120+
- download: current
121+
artifact: build
122+
123+
- pwsh: |
124+
Get-ChildItem -Path "$(Pipeline.Workspace)\build" -Recurse
125+
displayName: Capture downloaded artifacts
126+
- template: script-module-compliance.yml@ComplianceRepo
127+
parameters:
128+
# component-governance
129+
sourceScanPath: '$(Build.SourcesDirectory)\Microsoft.PowerShell.Archive\src'
130+
# credscan
131+
suppressionsFile: ''
132+
# TermCheck
133+
optionsRulesDBPath: ''
134+
optionsFTPath: ''
135+
# tsa-upload
136+
codeBaseName: 'PSNativeCommandProxy_2020'
137+
# selections
138+
APIScan: false # set to false when not using Windows APIs.

.azdevops/RunTests.ps1

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Copyright (c) Microsoft Corporation.
2+
# Licensed under the MIT License.
3+
4+
# Import the built module
5+
Import-Module "$env:PIPELINE_WORKSPACE/ModuleBuild/Microsoft.PowerShell.Archive.psd1"
6+
7+
Get-ChildItem "$env:PIPELINE_WORKSPACE/ModuleBuild" | Write-Verbose -Verbose
8+
9+
$pesterMinVersion = "5.3.0"
10+
$pesterMaxVersion = "5.3.9"
11+
12+
# If Pester 5.3.x is not installed, install it
13+
$pesterModule = Get-InstalledModule -Name "Pester" -MinimumVersion $pesterMinVersion -MaximumVersion $pesterMaxVersion
14+
if ($null -eq $pesterModule) {
15+
Install-Module -Name "Pester" -MinimumVersion $pesterMinVersion -MaximumVersion $pesterMaxVersion -Force
16+
}
17+
18+
# Load Pester
19+
Import-Module -Name "Pester" -MinimumVersion $pesterMinVersion -MaximumVersion $pesterMaxVersion
20+
21+
# Run tests
22+
$OutputFile = "$PWD/build-unit-tests.xml"
23+
$results = $null
24+
$results = Invoke-Pester -Script ./Tests/Compress-Archive.Tests.ps1 -OutputFile $OutputFile -PassThru -OutputFormat NUnitXml -Show Failed, Context, Describe, Fails
25+
Write-Host "##vso[artifact.upload containerfolder=testResults;artifactname=testResults]$OutputFile"
26+
if(!$results -or $results.FailedCount -gt 0 -or !$results.TotalCount)
27+
{
28+
throw "Build or tests failed. Passed: $($results.PassedCount) Failed: $($results.FailedCount) Total: $($results.TotalCount)"
29+
}

.azdevops/SignAndPackageModule.ps1

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Copyright (c) Microsoft Corporation.
2+
# Licensed under the MIT License.
3+
[CmdletBinding(SupportsShouldProcess=$true)]
4+
param (
5+
[string]$SignedPath
6+
)
7+
8+
9+
$root = (Resolve-Path -Path "${PSScriptRoot}/../")[0]
10+
$Name = "Microsoft.PowerShell.Archive"
11+
$BuildOutputDir = Join-Path $root "\src\bin\Release"
12+
$ManifestPath = "${BuildOutputDir}\${Name}.psd1"
13+
$ManifestData = Import-PowerShellDataFile -Path $ManifestPath
14+
$Version = $ManifestData.ModuleVersion
15+
16+
# this takes the files for the module and publishes them to a created, local repository
17+
# so the nupkg can be used to publish to the PSGallery
18+
function Export-Module
19+
{
20+
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingWriteHost", "")]
21+
param()
22+
$packageRoot = $SignedPath
23+
24+
if ( -not (Test-Path $packageRoot)) {
25+
throw "'$PubDir' does not exist"
26+
}
27+
28+
# now constuct a nupkg by registering a local repository and calling publish module
29+
$repoName = [guid]::newGuid().ToString("N")
30+
Register-PSRepository -Name $repoName -SourceLocation $packageRoot -InstallationPolicy Trusted
31+
Publish-Module -Path $packageRoot -Repository $repoName
32+
Unregister-PSRepository -Name $repoName
33+
Get-ChildItem -Recurse -Name $packageRoot | Write-Verbose
34+
$nupkgName = "{0}.{1}-preview1.nupkg" -f ${Name},${Version}
35+
$nupkgPath = Join-Path $packageRoot $nupkgName
36+
if ($env:TF_BUILD) {
37+
# In Azure DevOps
38+
Write-Host "##vso[artifact.upload containerfolder=$nupkgName;artifactname=$nupkgName;]$nupkgPath"
39+
}
40+
}
41+
42+
# The SBOM should already be in -SignedPath, so there is no need to copy it
43+
44+
Export-Module

.azdevops/TestsTemplate.yml

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
parameters:
2+
- name: vmImageName
3+
type: string
4+
default: 'windows-2019'
5+
6+
- name: jobName
7+
type: string
8+
default: 'run_test_windows'
9+
10+
- name: jobDisplayName
11+
type: string
12+
default: 'Run test'
13+
14+
jobs:
15+
- job: '${{ parameters.jobName }}'
16+
pool:
17+
vmImage: ${{ parameters.vmImageName }}
18+
displayName: ${{ parameters.jobDisplayName }}
19+
steps:
20+
- download: current
21+
artifact: ModuleBuild
22+
23+
- pwsh: |
24+
Write-Output ${{ parameters.vmImageName }}
25+
26+
if ("${{ parameters.vmImageName }}" -like 'windows-*')
27+
{
28+
$url = "https://github.com/PowerShell/PowerShell/releases/download/v7.3.0-preview.6/PowerShell-7.3.0-preview.6-win-x64.zip"
29+
$downloadFilename = "pwsh_download.msi"
30+
}
31+
32+
if ("${{ parameters.vmImageName }}" -like 'macos-*')
33+
{
34+
$url = "https://github.com/PowerShell/PowerShell/releases/download/v7.3.0-preview.6/powershell-7.3.0-preview.6-osx-x64.pkg"
35+
$downloadFilename = "pwsh_download.pkg"
36+
}
37+
if ("${{ parameters.vmImageName }}" -like 'ubuntu-*')
38+
{
39+
$url = "https://github.com/PowerShell/PowerShell/releases/download/v7.3.0-preview.6/powershell-7.3.0-preview.6-linux-x64.tar.gz"
40+
$downloadFilename = "pwsh_download.tar.gz"
41+
}
42+
43+
$downloadDestination = Join-Path $pwd $downloadFilename
44+
Invoke-WebRequest -Uri $url -OutFile $downloadDestination
45+
46+
# Installation steps for windows
47+
if ("${{ parameters.vmImageName }}" -like 'windows-*') {
48+
Expand-Archive -Path $downloadDestination -DestinationPath "pwsh-preview"
49+
$powerShellPreview = Join-Path $pwd "pwsh-preview" "pwsh.exe"
50+
}
51+
if ("${{ parameters.vmImageName }}" -like 'ubuntu-*')
52+
{
53+
gunzip -d $downloadDestination
54+
$downloadDestination = $downloadDestination.Replace(".gz", "")
55+
mkdir "pwsh-preview"
56+
tar -x -f $downloadDestination -C "pwsh-preview"
57+
$powerShellPreview = Join-Path $pwd "pwsh-preview" "pwsh"
58+
}
59+
if ("${{ parameters.vmImageName }}" -like 'macos-*')
60+
{
61+
sudo xattr -rd com.apple.quarantine "${downloadDestination}"
62+
sudo installer -pkg "${downloadDestination}" -target /
63+
$powerShellPreview = "pwsh-preview"
64+
}
65+
# Write the location of PowerShell Preview
66+
Write-Host "##vso[task.setvariable variable=PowerShellPreviewExecutablePath;]$powershellPreview"
67+
displayName: Download and Install PowerShell Preview
68+
69+
- pwsh: |
70+
$destination = Join-Path $pwd "7z.exe"
71+
$installUrl = "https://www.7-zip.org/a/7z2201-x64.exe"
72+
Invoke-WebRequest -Uri $installUrl -OutFile $destination
73+
# Run the installer in silent mode
74+
.$destination /S /D="C:\Program Files\7-Zip"
75+
displayName: Install 7-zip
76+
condition: and(succeeded(), startswith('${{ parameters.vmImageName }}', 'windows'))
77+
78+
- pwsh: |
79+
if ("${{ parameters.vmImageName }}" -like 'windows-*')
80+
{
81+
# Add 7-zip to PATH on Windows
82+
[System.Environment]::SetEnvironmentVariable('PATH',$Env:PATH+';C:\Program Files\7-zip')
83+
}
84+
"$(PowerShellPreviewExecutablePath) .azdevops/RunTests.ps1" | Invoke-Expression
85+
displayName: Run Tests
86+
87+
- task: PublishTestResults@2
88+
displayName: 'Publish Test Results **/*tests.xml'
89+
inputs:
90+
testResultsFormat: NUnit
91+
testResultsFiles: '**/*tests.xml'
92+
testRunTitle: 'Build Unit Tests'
93+
continueOnError: true
94+
condition: succeededOrFailed()

0 commit comments

Comments
 (0)