From 1e96ffd5585781f365e9115cd6769befeb727f13 Mon Sep 17 00:00:00 2001 From: Paul Higinbotham Date: Thu, 10 Jun 2021 10:32:04 -0700 Subject: [PATCH] Add CI release and repo mirror yaml --- .ci/ci.yml | 4 +- .ci/ci_release.yml | 229 +++++++++++++++++++++++++++ .ci/mirror.yml | 31 ++++ .ci/mirrorTemplates/githubMirror.yml | 107 +++++++++++++ .ci/release.yml | 47 ++++++ nuget.config | 1 - 6 files changed, 416 insertions(+), 3 deletions(-) create mode 100644 .ci/ci_release.yml create mode 100644 .ci/mirror.yml create mode 100644 .ci/mirrorTemplates/githubMirror.yml create mode 100644 .ci/release.yml diff --git a/.ci/ci.yml b/.ci/ci.yml index 632159b..d40d087 100644 --- a/.ci/ci.yml +++ b/.ci/ci.yml @@ -145,10 +145,10 @@ stages: parameters: jobName: TestPkgUbuntu16 displayName: PowerShell Core on Ubuntu 16.04 - imageName: ubuntu-16.04 + imageName: ubuntu-latest - template: test.yml parameters: jobName: TestPkgWinMacOS displayName: PowerShell Core on macOS - imageName: macOS-10.14 + imageName: macOS-latest diff --git a/.ci/ci_release.yml b/.ci/ci_release.yml new file mode 100644 index 0000000..613892a --- /dev/null +++ b/.ci/ci_release.yml @@ -0,0 +1,229 @@ +name: $(BuildDefinitionName)-$(date:yyMM).$(date:dd)$(rev:rrr) +trigger: + # Batch merge builds together while a merge build is running + batch: true + branches: + include: + - master +pr: + branches: + include: + - master + +variables: + - group: ESRP + +resources: + repositories: + - repository: ComplianceRepo + type: github + endpoint: ComplianceGHRepo + name: PowerShell/compliance + +stages: +- stage: Build + displayName: Build SecretStore Module Package + jobs: + - job: BuildPkg + displayName: Build Package + pool: + name: 1ES + demands: + - ImageOverride -equals MMS2019 + + steps: + - powershell: | + $powerShellPath = Join-Path -Path $env:AGENT_TEMPDIRECTORY -ChildPath 'powershell' + Invoke-WebRequest -Uri https://raw.githubusercontent.com/PowerShell/PowerShell/master/tools/install-powershell.ps1 -outfile ./install-powershell.ps1 + ./install-powershell.ps1 -Destination $powerShellPath + $vstsCommandString = "vso[task.setvariable variable=PATH]$powerShellPath;$env:PATH" + Write-Host "sending " + $vstsCommandString + Write-Host "##$vstsCommandString" + displayName: Install PowerShell Core + + - task: UseDotNet@2 + displayName: 'Install .NET Core 3.1.401 sdk' + inputs: + packageType: sdk + version: 3.1.401 + + - task: NuGetToolInstaller@1 + displayName: 'Install NuGet 5.6.0' + inputs: + checkLatest: false + version: 5.6.0 + + - pwsh: | + Get-ChildItem -Path env: + displayName: Capture environment for build + condition: succeededOrFailed() + + - pwsh: | + $modulePath = Join-Path -Path $env:AGENT_TEMPDIRECTORY -ChildPath 'TempModules' + if (Test-Path -Path $modulePath) { + Write-Verbose -Verbose "Deleting existing temp module path: $modulePath" + Remove-Item -Path $modulePath -Recurse -Force -ErrorAction Ignore + } + if (! (Test-Path -Path $modulePath)) { + Write-Verbose -Verbose "Creating new temp module path: $modulePath" + $null = New-Item -Path $modulePath -ItemType Directory + } + displayName: Create temporary module path + + - pwsh: | + $modulePath = Join-Path -Path $env:AGENT_TEMPDIRECTORY -ChildPath 'TempModules' + Write-Verbose -Verbose "Install PowerShellGet V3 to temp module path" + Save-Module -Name PowerShellGet -Path $modulePath -MinimumVersion 3.0.0-beta10 -AllowPrerelease -Force + Write-Verbose -Verbose "Install PlatyPS to temp module path" + Save-Module -Name "platyPS" -Path $modulePath -Force + Write-Verbose -Verbose "Install PSScriptAnalyzer to temp module path" + Save-Module -Name "PSScriptAnalyzer" -Path $modulePath -RequiredVersion 1.18.0 -Force + Write-Verbose -Verbose "Install Pester 4.X to temp module path" + Save-Module -Name "Pester" -MaximumVersion 4.99 -Path $modulePath -Force + Write-Verbose -Verbose "Install PSPackageProject to temp module path" + Save-Module -Name PSPackageProject -Path $modulePath -Force + displayName: Install PSPackageProject and dependencies + + - pwsh: | + $modulePath = Join-Path -Path $env:AGENT_TEMPDIRECTORY -ChildPath 'TempModules' + $env:PSModulePath = $modulePath + [System.IO.Path]::PathSeparator + $env:PSModulePath + $modPath = Join-Path -Path $modulePath -ChildPath PSPackageProject + Write-Verbose -Verbose "Importing PSPackageProject from: $modPath" + Import-Module -Name $modPath -Force + # + $(Build.SourcesDirectory)/build.ps1 -Build -Clean -BuildConfiguration Release + displayName: Build and publish artifact + + - pwsh: | + $modulePath = Join-Path -Path $env:AGENT_TEMPDIRECTORY -ChildPath 'TempModules' + $env:PSModulePath = $modulePath + [System.IO.Path]::PathSeparator + $env:PSModulePath + $modPath = Join-Path -Path $modulePath -ChildPath PSPackageProject + Write-Verbose -Verbose "Importing PSPackageProject from: $modPath" + Import-Module -Name $modPath -Force + # + $config = Get-PSPackageProjectConfiguration + $signSrcPath = "$($config.BuildOutputPath)\$($config.ModuleName)" + $signOutPath = "$($config.SignedOutputPath)\$($config.ModuleName)" + if (! (Test-Path -Path $signOutPath)) { + $null = New-Item -Path $signOutPath -ItemType Directory + } + + # Set signing src path variable + $vstsCommandString = "vso[task.setvariable variable=signSrcPath]${signSrcPath}" + Write-Host "sending " + $vstsCommandString + Write-Host "##$vstsCommandString" + + # Set signing out path variable + $vstsCommandString = "vso[task.setvariable variable=signOutPath]${signOutPath}" + Write-Host "sending " + $vstsCommandString + Write-Host "##$vstsCommandString" + displayName: Set signing variables for possible module code signing + + - pwsh: | + Get-ChildItem -Path env: + displayName: Capture environment for module code signing + condition: succeededOrFailed() + + - template: EsrpSign.yml@ComplianceRepo + parameters: + buildOutputPath: $(signSrcPath) + signOutputPath: $(signOutPath) + certificateId: "CP-230012" + pattern: | + Microsoft.PowerShell.SecretStore.dll + **\*.psd1 + **\*.psm1 + useMinimatch: true + + - pwsh: | + $modulePath = Join-Path -Path $env:AGENT_TEMPDIRECTORY -ChildPath 'TempModules' + $env:PSModulePath = $modulePath + [System.IO.Path]::PathSeparator + $env:PSModulePath + $modPath = Join-Path -Path $modulePath -ChildPath PSPackageProject + Write-Verbose -Verbose "Importing PSPackageProject from: $modPath" + Import-Module -Name $modPath -Force + # + $config = Get-PSPackageProjectConfiguration + if ($env:SkipSigning -eq 'True') + { + $srcModulePath = Resolve-Path -Path "$($config.BuildOutputPath)/$($config.ModuleName)" + $(Build.SourcesDirectory)/build.ps1 -Publish + } + else + { + $srcModulePath = Resolve-Path -Path "$($config.SignedOutputPath)/$($config.ModuleName)" + $(Build.SourcesDirectory)/build.ps1 -Publish -Signed + } + # Publish un-packaged module directory + Get-ChildItem $srcModulePath + $artifactName = "$($config.ModuleName)" + Write-Host "##vso[artifact.upload containerfolder=$artifactName;artifactname=$artifactName;]$srcModulePath" + displayName: Create module artifact + +- stage: Compliance + displayName: Compliance + dependsOn: Build + jobs: + - job: ComplianceJob + pool: + name: 1ES + demands: + - ImageOverride -equals MMS2019 + + steps: + - checkout: self + clean: true + - checkout: ComplianceRepo + clean: true + - download: current + artifact: 'Microsoft.PowerShell.SecretStore' + - template: assembly-module-compliance.yml@ComplianceRepo + parameters: + # binskim + AnalyzeTarget: '$(Pipeline.Workspace)/Microsoft.PowerShell.SecretStore/*.dll' + AnalyzeSymPath: 'SRV*' + # component-governance + sourceScanPath: '$(Build.SourcesDirectory)' + # credscan + suppressionsFile: '' + # TermCheck + optionsRulesDBPath: '' + optionsFTPath: '' + # tsa-upload + codeBaseName: 'PSSecretStore_201508' + # selections + APIScan: false # set to false when not using Windows APIs + +- stage: Test + displayName: Test Package + dependsOn: Build + jobs: + - template: test.yml + parameters: + jobName: TestPkgWin + displayName: PowerShell Core on Windows + imageName: windows-2019 + + - template: test.yml + parameters: + jobName: TestPkgWinPS + displayName: Windows PowerShell on Windows + imageName: windows-2019 + powershellExecutable: powershell + + - template: test.yml + parameters: + jobName: TestPkgUbuntu16 + displayName: PowerShell Core on Ubuntu 16.04 + imageName: ubuntu-latest + + - template: test.yml + parameters: + jobName: TestPkgWinMacOS + displayName: PowerShell Core on macOS + imageName: macOS-latest + +- stage: Release + displayName: Release Package + condition: and(and(succeeded(), eq(variables['Build.Reason'], 'Manual')), eq(variables['Publish'], 'True')) + jobs: + - template: release.yml diff --git a/.ci/mirror.yml b/.ci/mirror.yml new file mode 100644 index 0000000..85e2902 --- /dev/null +++ b/.ci/mirror.yml @@ -0,0 +1,31 @@ +# Mirror github SecretStore repo to this release pipeline repo at the provided schedule +# + +trigger: none +pr: none + +schedules: +# You can use https://crontab.guru/#0_8_*_*_* to figure out your crontab expression +# Mirror repo every day at 8 am +- cron: 0 8 * * * + branches: + include: + - refs/heads/master + always: true + +resources: + repositories: + - repository: SecretStore + type: git + name: SecretStore + ref: master + - repository: SecretStore-gh + ref: master + type: github + endpoint: ComplianceGHRepo + name: PowerShell/SecretStore + +stages: + - template: ./mirrorTemplates/githubMirror.yml + parameters: + repoName: SecretStore diff --git a/.ci/mirrorTemplates/githubMirror.yml b/.ci/mirrorTemplates/githubMirror.yml new file mode 100644 index 0000000..a0c7dae --- /dev/null +++ b/.ci/mirrorTemplates/githubMirror.yml @@ -0,0 +1,107 @@ +parameters: + - name: repoName + default: '' + - name: organization + default: powershell + +stages: + - stage: Mirror_${{ replace(parameters.reponame,'-','_') }} + displayName: Mirror ${{ parameters.reponame }} + jobs: + - job: Mirror_${{ replace(parameters.reponame,'-','_') }} + displayName: Mirror ${{ parameters.reponame }} + cancelTimeoutInMinutes: 1 + + pool: + name: 1ES + demands: + - ImageOverride -equals MMS2019 + + variables: + # AzDO intercepts some git cli calls and turns them into API calls + # prefer git says to always use the cli + - name: system.prefergit + value: true + # We are only mirroring and not building, so ignore nuget + - name: NugetSecurityAnalysisWarningLevel + value: none + - name: repoFolder + value: ${{ parameters.reponame }} + - name: ghRepoFolder + value: ${{ parameters.reponame }}-gh + - name: repoPath + value: $(Agent.BuildDirectory)\$(repoFolder) + - name: ghRepoPath + value: $(Agent.BuildDirectory)\$(ghRepoFolder) + + steps: + - checkout: ${{ parameters.reponame }} + clean: true + path: $(repoFolder) + # We need the credentials to push back to the AzDO repo + persistCredentials: True + + # using multi checkout because sometimes the GitHub repo is private + # this makes the template the same, + # even if a private repo requires authentication + - checkout: ${{ parameters.reponame }}-gh + clean: true + path: $(ghRepoFolder) + + - pwsh: | + $commitId = git rev-parse --verify HEAD + + $vstsCommandString = "vso[task.setvariable variable=CommitId]$commitId" + + Write-Host "sending " + $vstsCommandString + + Write-Host "##$vstsCommandString" + displayName: Saving AzDO commitid + workingDirectory: '$(repoPath)' + + - pwsh: | + Write-verbose -message 'creating master from HEAD' -verbose + git branch master + + Write-verbose -message 'checking out master' -verbose + git checkout master + + Write-verbose -message 'getting git status' -verbose + git status + displayName: Set branch to master on GitHub repo + workingDirectory: '$(ghRepoPath)' + + - pwsh: | + Write-verbose -message 'adding github remote' -verbose + git remote add github $(ghRepoPath) + + Write-verbose -message 'listing remotes' -verbose + git remote -v + + Write-verbose -message 'fetching github master' -verbose + git fetch --quiet github master + + Write-verbose -message 'Checkout master branch as github master' -verbose + git checkout --quiet -b master github/master + displayName: Checkout GitHub master branch as master + workingDirectory: '$(repoPath)' + + - pwsh: | + $commitId = git rev-parse --verify HEAD + + Write-verbose -message "$commitId -ne $env:commitId" -verbose + + if ($commitId -ne $env:commitId) + { + Write-verbose -message 'pushing (quiet)...' -verbose + git branch + git push --quiet origin master + } + else + { + Write-verbose -message 'Nothing to update' -verbose + } + displayName: Push to AzDO if needed + workingDirectory: '$(repoPath)' + env: + MY_ACCESS_TOKEN: $(System.AccessToken) diff --git a/.ci/release.yml b/.ci/release.yml new file mode 100644 index 0000000..50c4d96 --- /dev/null +++ b/.ci/release.yml @@ -0,0 +1,47 @@ +parameters: + jobName: release + imageName: windows-2019 + displayName: 'Release Microsoft.PowerShell.SecretStore to NuGet' + +jobs: +- job: ${{ parameters.jobName }} + pool: + vmImage: ${{ parameters.imageName }} + displayName: ${{ parameters.displayName }} + + steps: + - task: NuGetToolInstaller@1 + displayName: 'Install NuGet 5.6.0' + inputs: + checkLatest: false + version: 5.6.0 + + - task: DownloadBuildArtifacts@0 + displayName: 'Download SecretSTore module artifacts' + inputs: + buildType: current + downloadType: specific + artifactName: '**/*.nupkg' + downloadPath: '$(System.ArtifactsDirectory)' + + - powershell: | + Get-ChildItem '$(System.ArtifactsDirectory)/nupkg/Microsoft.PowerShell.SecretStore.*.nupkg' -ErrorAction SilentlyContinue + # Get-ChildItem '$(System.ArtifactsDirectory)' -Recurse + displayName: 'Capture SecretStore module NuGet package' + + # TODO: Need to create NuGet service connection + #- task: NuGetCommand@2 + # displayName: 'Push Microsoft.PowerShell.Store module artifacts to AzArtifactsFeed' + # inputs: + # command: push + # packagesToPush: '$(System.ArtifactsDirectory)/nupkg/Microsoft.PowerShell.SecretStore.*.nupkg' + # nuGetFeedType: external + # publishFeedCredentials: AzArtifactFeed + + #- task: NuGetCommand@2 + # displayName: 'Push Microsoft.PowerShell.Store module artifacts to PSGallery feed' + # inputs: + # command: push + # packagesToPush: '$(System.ArtifactsDirectory)/nupkg/Microsoft.PowerShell.SecretStore.*.nupkg' + # nuGetFeedType: external + # publishFeedCredentials: PHPowerShellGalleryFeed diff --git a/nuget.config b/nuget.config index 760e780..6548586 100644 --- a/nuget.config +++ b/nuget.config @@ -2,7 +2,6 @@ -