Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
45 changes: 44 additions & 1 deletion .pipelines/PowerShell-Release-Official.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ resources:
type: git
name: OneBranch.Pipelines/GovernedTemplates
ref: refs/heads/main
- repository: PSInternalTools
type: git
name: PowerShellCore/Internal-PowerShellTeam-Tools
ref: refs/heads/master

pipelines:
- pipeline: CoOrdinatedBuildPipeline
Expand Down Expand Up @@ -110,8 +114,14 @@ extends:
tsaOptionsFile: .config\tsaoptions.json

stages:
- stage: setReleaseTagAndUploadTools
displayName: 'Set Release Tag and Upload Tools'
jobs:
- template: /.pipelines/templates/release-SetTagAndTools.yml@self

- stage: msixbundle
displayName: 'Create MSIX Bundle'
dependsOn: []
jobs:
- template: /.pipelines/templates/release-create-msix.yml@self

Expand Down Expand Up @@ -262,6 +272,35 @@ extends:
Update and merge the changelog for the release.
This step is required for creating GitHub draft release.

- stage: PublishGitHubRelease
displayName: Publish GitHub Release
dependsOn:
- setReleaseTagAndUploadTools
- UpdateChangeLog
variables:
ob_release_environment: Production
jobs:
- template: /.pipelines/templates/release-githubtasks.yml@self

- stage: PushGitTagAndMakeDraftPublic
displayName: Push Git Tag and Make Draft Public
dependsOn: PublishGitHubRelease
jobs:
- template: /.pipelines/templates/approvalJob.yml@self
parameters:
displayName: Push Git Tag
jobName: PushGitTag
instructions: |
Push the git tag to upstream

- template: /.pipelines/templates/approvalJob.yml@self
parameters:
displayName: Make Draft Public
dependsOnJob: PushGitTag
jobName: DraftPublic
instructions: |
Make the GitHub Release Draft Public

- stage: BlobPublic
displayName: Make Blob Public
dependsOn: UpdateChangeLog
Expand All @@ -278,7 +317,11 @@ extends:

- stage: PublishNuGet
displayName: Publish NuGet
dependsOn: PublishGitHubRelease
dependsOn:
- setReleaseTagAndUploadTools
- PushGitTagAndMakeDraftPublic
variables:
ob_release_environment: Production
jobs:
- template: /.pipelines/templates/release-publish-nuget.yml@self
parameters:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ steps:
}

$releaseTag = $Branch -replace '^.*((release|rebuild)/)'
$vstsCommandString = "vso[task.setvariable variable=$Variable]$releaseTag"
$vstsCommandString = "vso[task.setvariable variable=$Variable;isOutput=true]$releaseTag"
Write-Verbose -Message "setting $Variable to $releaseTag" -Verbose
Write-Host -Object "##$vstsCommandString"
name: OutputReleaseTag
displayName: Set Release Tag

- pwsh: |
Expand All @@ -20,7 +21,8 @@ steps:
Write-Host "##$vstsCommandString"

$version = '$(ReleaseTag)'.ToLowerInvariant().Substring(1)
$vstsCommandString = "vso[task.setvariable variable=Version]$version"
$vstsCommandString = "vso[task.setvariable variable=Version;isOutput=true]$version"
Write-Host ("sending " + $vstsCommandString)
Write-Host "##$vstsCommandString"
name: OutputVersion
displayName: Set container name
75 changes: 75 additions & 0 deletions .pipelines/templates/release-SetTagAndTools.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
jobs:
- job: SetTagAndTools
displayName: Set Tag and Tools
condition: succeeded()
pool:
type: windows
variables:
- group: 'mscodehub-code-read-akv'
- name: ob_outputDirectory
value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT'
- name: ob_sdl_credscan_suppressionsFile
value: $(Build.SourcesDirectory)\PowerShell\.config\suppress.json
- name: ob_sdl_tsa_configFile
value: $(Build.SourcesDirectory)\PowerShell\.config\tsaoptions.json
steps:
- template: release-SetReleaseTagandContainerName.yml@self

- checkout: self
clean: true
env:
ob_restore_phase: true

- checkout: PSInternalTools
clean: true
env:
ob_restore_phase: true

- pwsh: |
New-Item -ItemType Directory -Path '$(Pipeline.Workspace)/ToolArtifact'
Get-ChildItem -Path '$(Build.SourcesDirectory)/Internal-PowerShellTeam-Tools/Scripts' -Filter 'GitHubRelease.psm1' -ErrorAction SilentlyContinue |
Copy-Item -Destination '$(Pipeline.Workspace)/ToolArtifact' -Verbose
displayName: Move GitHub Tool

- task: onebranch.pipeline.signing@1
displayName: Sign Tools
inputs:
command: 'sign'
signing_profile: internal_azure_service
files_to_sign: '*.ps1;*.psm1'
search_root: '$(Pipeline.Workspace)/ToolArtifact'

- pwsh: |
Write-Verbose -Verbose "Creating output directory for release tools: $(ob_outputDirectory)/ToolArtifact"
New-Item -Path $(ob_outputDirectory)/ToolArtifact -ItemType Directory -Force
Get-ChildItem -Path "$(Pipeline.Workspace)/ToolArtifact/*" -Recurse |
Copy-Item -Destination $(ob_outputDirectory)/ToolArtifact -Recurse -Verbose
displayName: Upload Tools

- pwsh: |
Write-Verbose -Verbose "Release Tag: $(OutputReleaseTag.releaseTag)"
$releaseVersion = '$(OutputReleaseTag.releaseTag)' -replace '^v',''
Write-Verbose -Verbose "Release Version: $releaseVersion"
$semanticVersion = [System.Management.Automation.SemanticVersion]$releaseVersion

$isPreview = $semanticVersion.PreReleaseLabel -ne $null

$fileName = if ($isPreview) {
"preview.md"
}
else {
$semanticVersion.Major.ToString() + "." + $semanticVersion.Minor.ToString() + ".md"
}

$filePath = "$(Build.SourcesDirectory)/PowerShell/CHANGELOG/$fileName"
Write-Verbose -Verbose "Selected Log file: $filePath"

if (-not (Test-Path -Path $filePath)) {
Write-Error "Changelog file not found: $filePath"
exit 1
}

Write-Verbose -Verbose "Creating output directory for CHANGELOG: $(ob_outputDirectory)/CHANGELOG"
New-Item -Path $(ob_outputDirectory)/CHANGELOG -ItemType Directory -Force
Copy-Item -Path $filePath -Destination $(ob_outputDirectory)/CHANGELOG
displayName: Upload Changelog
189 changes: 65 additions & 124 deletions .pipelines/templates/release-githubtasks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,148 +3,89 @@ jobs:
displayName: Create GitHub Release Draft
condition: succeeded()
pool:
type: windows
type: release
os: windows
templateContext:
inputs:
- input: pipelineArtifact
artifactName: drop_setReleaseTagAndUploadTools_SetTagAndTools
- input: pipelineArtifact
pipeline: PSPackagesOfficial
artifactName: drop_upload_upload_packages
variables:
- name: runCodesignValidationInjection
value: false
- name: NugetSecurityAnalysisWarningLevel
value: none
- name: DOTNET_SKIP_FIRST_TIME_EXPERIENCE
value: 1
- group: 'mscodehub-code-read-akv'
- group: 'Azure Blob variable group'
- group: 'GitHubTokens'
- name: ob_outputDirectory
value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT'
- name: ob_sdl_codeSignValidation_enabled
value: false
- name: ob_sdl_binskim_enabled
value: false
- name: ob_sdl_tsa_configFile
value: $(Build.SourcesDirectory)\PowerShell\.config\tsaoptions.json
- name: ob_sdl_credscan_suppressionsFile
value: $(Build.SourcesDirectory)\PowerShell\.config\suppress.json
- template: ./variable/release-shared.yml@self
parameters:
RELEASETAG: $[ stageDependencies.setReleaseTagAndUploadTools.SetTagAndTools.outputs['OutputReleaseTag.releaseTag'] ]

steps:
- checkout: self
clean: true
env:
ob_restore_phase: true # This ensures checkout is done at the beginning of the restore phase

- template: release-SetReleaseTagAndContainerName.yml

- pwsh: |
Get-ChildItem Env: | Out-String -width 9999 -Stream | write-Verbose -Verbose
- task: PowerShell@2
inputs:
targetType: inline
script: |
Write-Verbose -Verbose "Release Tag: $(ReleaseTag)"
Get-ChildItem Env: | Out-String -Stream | Write-Verbose -Verbose
displayName: 'Capture Environment Variables'

- pwsh: |
# Uninstall Azure RM modules
$azRmModules = Get-Module -Name AzureRM* -ListAvailable
if ($azRmModules) {
$azRmModules | Remove-Module -Force
}

# Install Az.Storage module if not already installed
if (-not (Get-Module -Name Az.Storage -ListAvailable)) {
Install-Module -Name Az.Storage -Force -AllowClobber -Scope CurrentUser -Verbose
}
displayName: Install Az.Storage module
- template: release-install-pwsh.yml

- task: AzurePowerShell@5
displayName: Download packages from Azure Storage
- task: PowerShell@2
inputs:
azureSubscription: az-blob-cicd-infra
scriptType: inlineScript
azurePowerShellVersion: LatestVersion
targetType: inline
pwsh: true
inline: |
$storageAccount = "$(StorageAccount)"
$containerName = "$(AzureVersion)"
$destinationPath = "$(System.ArtifactsDirectory)"

# Get storage account context
$storageContext = New-AzStorageContext -StorageAccountName $storageAccount

$blobList = Get-AzStorageBlob -Container $containerName -Context $storageContext
foreach ($blob in $blobList) {
$blobName = $blob.Name
$destinationFile = Join-Path -Path $destinationPath -ChildPath $blobName
Get-AzStorageBlobContent -Container $containerName -Blob $blobName -Destination $destinationFile -Context $storageContext -Force
Write-Output "Downloaded $blobName to $destinationFile"
}

$packagesPath = Get-ChildItem -Path $destinationPath\*.deb -Recurse -File | Select-Object -First 1 -ExpandProperty DirectoryName
Write-Host "sending -- vso[task.setvariable variable=PackagesRoot]$packagesPath"
Write-Host "##vso[task.setvariable variable=PackagesRoot]$packagesPath"

- pwsh: |
Get-ChildItem $(System.ArtifactsDirectory)\* -recurse | Select-Object -ExpandProperty FullName
displayName: Capture downloaded artifacts

- pwsh: |
git clone https://$(mscodehubCodeReadPat)@mscodehub.visualstudio.com/PowerShellCore/_git/Internal-PowerShellTeam-Tools '$(Pipeline.Workspace)/tools'
displayName: Clone Internal-Tools repository

- pwsh: |
$Path = "$(System.ArtifactsDirectory)"
$OutputPath = Join-Path $Path 'hashes.sha256'
$srcPaths = @($Path)
$packages = Get-ChildItem -Path $srcPaths -Include * -Recurse -File
$checksums = $packages |
ForEach-Object {
Write-Verbose -Verbose "Generating checksum file for $($_.FullName)"
$packageName = $_.Name
$hash = (Get-FileHash -Path $_.FullName -Algorithm SHA256).Hash.ToLower()
# the '*' before the packagename signifies it is a binary
"$hash *$packageName"
}
$checksums | Out-File -FilePath $OutputPath -Force
$fileContent = Get-Content -Path $OutputPath -Raw | Out-String
Write-Verbose -Verbose -Message $fileContent
script: |
$Path = "$(Pipeline.Workspace)/GitHubPackages"
$OutputPath = Join-Path $Path 'hashes.sha256'
$packages = Get-ChildItem -Path $Path -Include * -Recurse -File
$checksums = $packages |
ForEach-Object {
Write-Verbose -Verbose "Generating checksum file for $($_.FullName)"
$packageName = $_.Name
$hash = (Get-FileHash -Path $_.FullName -Algorithm SHA256).Hash.ToLower()
# the '*' before the packagename signifies it is a binary
"$hash *$packageName"
}
$checksums | Out-File -FilePath $OutputPath -Force
$fileContent = Get-Content -Path $OutputPath -Raw | Out-String
Write-Verbose -Verbose -Message $fileContent
displayName: Add sha256 hashes

- pwsh: |
$releaseVersion = '$(ReleaseTag)' -replace '^v',''
$vstsCommandString = "vso[task.setvariable variable=ReleaseVersion]$releaseVersion"
Write-Host "sending " + $vstsCommandString
Write-Host "##$vstsCommandString"
displayName: 'Set release version'

- pwsh: |
Import-module '$(Pipeline.Workspace)/tools/Scripts/GitHubRelease.psm1'
$releaseVersion = '$(ReleaseTag)' -replace '^v',''
$semanticVersion = [System.Management.Automation.SemanticVersion]$releaseVersion

$isPreview = $semanticVersion.PreReleaseLabel -ne $null
- task: PowerShell@2
inputs:
targetType: inline
pwsh: true
script: |
Get-ChildItem $(Pipeline.Workspace) -recurse | Select-Object -ExpandProperty FullName
displayName: List all files in the workspace

$fileName = if ($isPreview) {
"preview.md"
}
else {
$semanticVersion.Major.ToString() + "." + $semanticVersion.Minor.ToString() + ".md"
}
- task: PowerShell@2
inputs:
targetType: inline
pwsh: true
script: |
Import-module '$(Pipeline.Workspace)/ToolArtifact/GitHubRelease.psm1'
Write-Verbose -Verbose "Available modules: "
Get-Module | Write-Verbose -Verbose

$filePath = "$env:BUILD_SOURCESDIRECTORY/PowerShell/CHANGELOG/$fileName"
Write-Verbose -Verbose "Selected Log file: $filePath"
$filePath = Get-ChildItem -Path "$(Pipeline.Workspace)/CHANGELOG" -Filter '*.md' | Select-Object -First 1 -ExpandProperty FullName

if (-not (Test-Path $filePath)) {
throw "$filePath not found"
}
if (-not (Test-Path $filePath)) {
throw "$filePath not found"
}

$changelog = Get-Content -Path $filePath
$changelog = Get-Content -Path $filePath

$startPattern = "^## \[" + ([regex]::Escape($releaseVersion)) + "\]"
$endPattern = "^## \[{0}\.{1}\.{2}*" -f $semanticVersion.Major, $semanticVersion.Minor, $semanticVersion.Patch
$startPattern = "^## \[" + ([regex]::Escape($releaseVersion)) + "\]"
$endPattern = "^## \[{0}\.{1}\.{2}*" -f $semanticVersion.Major, $semanticVersion.Minor, $semanticVersion.Patch

$clContent = $changelog | ForEach-Object {
if ($_ -match $startPattern) { $outputLine = $true }
elseif ($_ -match $endPattern) { $outputLine = $false }
if ($outputLine) { $_}
} | Out-String
$clContent = $changelog | ForEach-Object {
if ($_ -match $startPattern) { $outputLine = $true }
elseif ($_ -match $endPattern) { $outputLine = $false }
if ($outputLine) { $_}
} | Out-String

Write-Verbose -Verbose "Selected content: `n$clContent"
Write-Verbose -Verbose "Selected content: `n$clContent"

Publish-ReleaseDraft -Tag '$(ReleaseTag)' -Name '$(ReleaseTag) Release of PowerShell' -Description $clContent -User PowerShell -Repository PowerShell -PackageFolder $(PackagesRoot) -Token $(GitHubReleasePat)
Publish-ReleaseDraft -Tag '$(ReleaseTag)' -Name '$(ReleaseTag) Release of PowerShell' -Description $clContent -User PowerShell -Repository PowerShell -PackageFolder "$(Pipeline.Workspace)/GitHubPackages" -Token $(GitHubReleasePat)
displayName: Publish Release Draft

- template: /.pipelines/templates/approvalJob.yml@self
Expand Down
Loading
Loading