Skip to content

Commit

Permalink
Create a single SHA for patch releases (Azure#28551)
Browse files Browse the repository at this point in the history
1. This script generates a single SHA for patch releases - with the changelog, readme and other sources in the releasable state
2. Creates a separate branch for the BOM releases - with the snapshot of the version_client.txt file.
3. Generates a report containing the name of the branches (one for BOM and other for artifacts) and the name of each artifact that needs to be patched.

Fixes Azure#28535
  • Loading branch information
pallavit authored Jun 27, 2022
1 parent 597dfce commit 513c87e
Show file tree
Hide file tree
Showing 3 changed files with 400 additions and 168 deletions.
24 changes: 24 additions & 0 deletions eng/pipelines/bompreparation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
trigger: none

pr: none

stages:
- stage: AnalyzeAndGeneratePatches

jobs:
- job: PatchGeneration
timeoutInMinutes: 180

pool:
vmImage: 'windows-2019'

steps:
- pwsh: |
$(Build.SourcesDirectory)/eng/scripts/patchreleases.ps1
Copy-Item eng/scripts/patchreport.html $(Build.ArtifactStagingDirectory)/staging
Copy-Item eng/scripts/bompom.html $(Build.ArtifactStagingDirectory)/staging
displayName: 'Analyze and generate patches'
- publish: $(Build.ArtifactStagingDirectory)
displayName: 'Publish Report Artifacts'
artifact: patchreport
118 changes: 82 additions & 36 deletions eng/scripts/bomhelpers.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -19,31 +19,36 @@ $RepoRoot = Resolve-Path "${PSScriptRoot}../../.."
$CommonScriptFilePath = Join-Path $RepoRoot "eng" "common" "scripts" "common.ps1"
. $CommonScriptFilePath

# Set the dependency version of an artifact in the version_client.txt file.
function SetDependencyVersion($GroupId = "com.azure", $ArtifactId, $Version) {
$repoRoot = Resolve-Path "${PSScriptRoot}../../.."
$setVersionFilePath = Join-Path $repoRoot "eng" "versioning" "set_versions.py"
$cmdOutput = python $setVersionFilePath --bt client --new-version $Version --ar $ArtifactId --gi $GroupId
$cmdOutput = python $setVersionFilePath --bt client --ar $ArtifactId --gi $GroupId --increment-version
}

# Set the current version of an artifact in the version_client.txt file
function SetCurrentVersion($GroupId, $ArtifactId, $Version) {
$repoRoot = Resolve-Path "${PSScriptRoot}../../.."
$setVersionFilePath = Join-Path $repoRoot "eng" "versioning" "set_versions.py"
$cmdOutput = python $setVersionFilePath --bt client --new-version $Version --ar $ArtifactId --gi $GroupId
}

# Update dependencies of the artifact.
function UpdateDependencyOfClientSDK() {
$repoRoot = Resolve-Path "${PSScriptRoot}../../.."
$updateVersionFilePath = Join-Path $repoRoot "eng" "versioning" "update_versions.py"
$cmdOutput = python $updateVersionFilePath --ut all --bt client --sr
}

# Get all azure com client artifacts from maven.
function GetAllAzComClientArtifactsFromMaven() {
$webResponseObj = Invoke-WebRequest -Uri "https://repo1.maven.org/maven2/com/azure"
$azureComArtifactIds = $webResponseObj.Links.HRef | Where-Object { ($_ -like 'azure-*') -and ($IgnoreList -notcontains $_) } | ForEach-Object { $_.substring(0, $_.length - 1) }
return $azureComArtifactIds | Where-Object { ($_ -like "azure-*") -and !($_ -like "azure-spring") }
}

# Get version info for an artifact.
function GetVersionInfoForAnArtifactId([String]$ArtifactId) {
$mavenMetadataUrl = "https://repo1.maven.org/maven2/com/azure/$($ArtifactId)/maven-metadata.xml"
$webResponseObj = Invoke-WebRequest -Uri $mavenMetadataUrl
Expand All @@ -58,6 +63,7 @@ function GetVersionInfoForAnArtifactId([String]$ArtifactId) {
return $mavenArtifactInfo
}

# Get patch version for a given release version.
function GetPatchVersion([String]$ReleaseVersion) {
$ParsedSemver = [AzureEngSemanticVersion]::new($ReleaseVersion)
if (!$ParsedSemver) {
Expand All @@ -68,18 +74,25 @@ function GetPatchVersion([String]$ReleaseVersion) {
return "$($ParsedSemver.Major).$($ParsedSemver.Minor).$($ParsedSemver.Patch + 1)"
}

# Get remote name
function GetRemoteName() {
$mainRemoteUrl = 'https://github.com/Azure/azure-sdk-for-java.git'
foreach ($rem in git remote show) {
$mainRemoteUrl = 'https://github.com/Azure/azure-sdk-for-java'
$remoteName = 'origin'
Write-Host 'git remote show'
$remoteNames = git remote show
foreach ($rem in $remoteNames) {
Write-Host 'git remote get-url $rem'
$remoteUrl = git remote get-url $rem
if ($remoteUrl -eq $mainRemoteUrl) {
return $rem
$remoteString = [string]$remoteUrl
if ($remoteString -Match $mainRemoteUrl) {
$remoteName = $rem
break;
}
}
LogError "Could not compute the remote name."
return $null
return $remoteName
}

# Find the pipeline name for a given artifact by parsing the ci.yml file.
function GetPipelineName([string]$ArtifactId, [string]$ArtifactDirPath) {
$ciYmlFilePath = Join-Path $ArtifactDirPath "ci.yml"
if (Test-Path $ciYmlFilePath) {
Expand Down Expand Up @@ -107,6 +120,7 @@ function TriggerPipeline($PatchInfos, $BranchName) {
# }
}

# Create a unique branch name.
function GetBranchName($ArtifactId) {
$artifactNameToLower = $ArtifactId.ToLower()
$guid = [guid]::NewGuid().Guid
Expand All @@ -125,6 +139,7 @@ class ArtifactPatchInfo {
[string]$PipelineName
}

# Parse dependencies from a given pom file.
function GetDependencyToVersion($PomFilePath) {
$dependencyNameToVersion = @{}
$pomFileContent = [xml](Get-Content -Path $PomFilePath)
Expand All @@ -138,14 +153,32 @@ function GetDependencyToVersion($PomFilePath) {
return $dependencyNameToVersion
}

function GetChangeLogContent($NewDependencyNameToVersion, $OldDependencyNameToVersion) {
# Create the changelog content from a message.
function GetChangeLogContentFromMessage($ContentMessage) {
$content = @()
$content += ""
$content += "### Other Changes"
$content += ""
$content += "#### Dependency Updates"
$content += ""


$content += $ContentMessage
$content += ""

return $content
}

# Get change log entry for a patch.
function GetChangeLogEntryForPatch($NewDependencyNameToVersion, $OldDependencyNameToVersion) {
$content = GetDependencyUpgradeChangeLogMessage -NewDependencyNameToVersion $NewDependencyNameToVersion -OldDependencyNameToVersion $OldDependencyNameToVersion

$content = GetChangeLogContentFromMessage($content)
return $content
}

# Get a dependency upgrade changelog message.
function GetDependencyUpgradeChangeLogMessage($NewDependencyNameToVersion, $OldDependencyNameToVersion) {
$content = @()
foreach ($key in $OldDependencyNameToVersion.Keys) {
$oldVersion = $($OldDependencyNameToVersion[$key]).Trim()
$newVersion = $($NewDependencyNameToVersion[$key]).Trim()
Expand All @@ -155,18 +188,40 @@ function GetChangeLogContent($NewDependencyNameToVersion, $OldDependencyNameToVe
}

$content += ""

return $content
}


# Update the change log entry for a given changelog.
function UpdateChangeLogEntry($ChangeLogPath, $PatchVersion, $ArtifactId, $Content) {
$releaseStatus = "$(Get-Date -Format $CHANGELOG_DATE_FORMAT)"
$releaseStatus = "($releaseStatus)"
$changeLogEntries = Get-ChangeLogEntries -ChangeLogLocation $ChangeLogPath
$newChangeLogEntry = New-ChangeLogEntry -Version $PatchVersion -Status $releaseStatus -Content $Content
if ($newChangeLogEntry) {
$changeLogEntries.Insert(0, $PatchVersion, $newChangeLogEntry)
}
else {
LogError "Failed to create new changelog entry for $ArtifactId"
exit 1
}

$cmdOutput = Set-ChangeLogContent -ChangeLogLocation $ChangeLogPath -ChangeLogEntries $changeLogEntries
if ($LASTEXITCODE -ne 0) {
LogError "Could not update the changelog at $ChangeLogPath). Exiting..."
exit $LASTEXITCODE
}
}

function GitCommit($Message) {
$cmdOutput = git commit -a -m $Message
Write-Host 'git -c user.name="azure-sdk" -c user.email="azuresdk@microsoft.com" commit -am $Message'
$cmdOutput = git -c user.name="azure-sdk" -c user.email="azuresdk@microsoft.com" commit -am $Message
if ($LASTEXITCODE -ne 0) {
LogError "Could not commit the changes locally.Exiting..."
exit $LASTEXITCODE
}
}

# Generate patches for given artifact patch infos.
function GeneratePatches($ArtifactPatchInfos, [string]$BranchName, [string]$RemoteName, [string]$GroupId = "com.azure") {
foreach ($patchInfo in $ArtifactPatchInfos) {
GeneratePatch -PatchInfo $patchInfo -BranchName $BranchName -RemoteName $RemoteName -GroupId $GroupId
Expand All @@ -175,10 +230,18 @@ function GeneratePatches($ArtifactPatchInfos, [string]$BranchName, [string]$Remo
TriggerPipeline -PatchInfos $ArtifactPatchInfos -BranchName $BranchName
}


function GetCurrentBranchName() {
Write-Host 'git rev-parse --abbrev-ref HEAD'
return git rev-parse --abbrev-ref HEAD
}

<# This method generates the patch for a given artifact by doing the following
1. Reset the sources to the last release version for the given artifact.
2. Updating the dependencies of the artifact to what they should be in the current set.
3. Updating the changelog and readme's to update the dependency information.
4. Committing these changes.
#>
function GeneratePatch($PatchInfo, [string]$BranchName, [string]$RemoteName, [string]$GroupId = "com.azure") {
$artifactId = $PatchInfo.ArtifactId
$releaseVersion = $PatchInfo.LatestGAOrPatchVersion
Expand Down Expand Up @@ -206,6 +269,7 @@ function GeneratePatch($PatchInfo, [string]$BranchName, [string]$RemoteName, [st
$currentBranchName = GetCurrentBranchName

if ($currentBranchName -ne $BranchName) {
Write-Host 'git checkout -b $BranchName $RemoteName/main'
$cmdOutput = git checkout -b $BranchName $RemoteName/main
if ($LASTEXITCODE -ne 0) {
LogError "Could not checkout branch $BranchName, please check if it already exists and delete as necessary. Exiting..."
Expand Down Expand Up @@ -253,13 +317,15 @@ function GeneratePatch($PatchInfo, [string]$BranchName, [string]$RemoteName, [st
if ($currentPomFileVersion -ne $releaseVersion) {
Write-Output "Hard reseting the sources for $artifactId to version $releaseVersion using release tag: $releaseTag."
Write-Output "Fetching all the tags from $RemoteName"
Write-Host 'git fetch $RemoteName $releaseTag'
$cmdOutput = git fetch $RemoteName $releaseTag

if ($LASTEXITCODE -ne 0) {
LogError "Could not restore the tags for release tag $releaseTag"
exit $LASTEXITCODE
}


Write-Host 'git restore --source $releaseTag -W -S $artifactDirPath'
$cmdOutput = git restore --source $releaseTag -W -S $artifactDirPath
if ($LASTEXITCODE -ne 0) {
LogError "Could not reset sources for $artifactId) to the release version $releaseVersion"
Expand All @@ -280,39 +346,19 @@ function GeneratePatch($PatchInfo, [string]$BranchName, [string]$RemoteName, [st

$cmdOutput = UpdateDependencyOfClientSDK
if ($LASTEXITCODE -ne 0) {
LogError LogError "Could not update all references for for $artifactId"
LogError "Could not update all references for for $artifactId"
exit $LASTEXITCODE
}

$newDependenciesToVersion = GetDependencyToVersion -PomFilePath $pomFilePath
$releaseStatus = "$(Get-Date -Format $CHANGELOG_DATE_FORMAT)"
$releaseStatus = "($releaseStatus)"
$changeLogEntries = Get-ChangeLogEntries -ChangeLogLocation $changelogPath

$Content = GetChangeLogContent -NewDependencyNameToVersion $newDependenciesToVersion -OldDependencyNameToVersion $oldDependencyNameToVersion
$newChangeLogEntry = New-ChangeLogEntry -Version $patchVersion -Status $releaseStatus -Content $Content
if ($newChangeLogEntry) {
$changeLogEntries.Insert(0, $patchVersion, $newChangeLogEntry)
}
else {
LogError "Failed to create new changelog entry for $artifactId"
exit 1
}

$cmdOutput = Set-ChangeLogContent -ChangeLogLocation $changelogPath -ChangeLogEntries $changeLogEntries
if ($LASTEXITCODE -ne 0) {
LogError "Could not update the changelog at $changelogPath). Exiting..."
exit $LASTEXITCODE
}


$content = GetChangeLogEntryForPatch -NewDependencyNameToVersion $newDependenciesToVersion -OldDependencyNameToVersion $oldDependencyNameToVersion
UpdateChangeLogEntry -ChangeLogPath $changelogPath -PatchVersion $patchVersion -ArtifactId $artifactId -Content $content
GitCommit -Message "Prepare $artifactId for $patchVersion patch release."
Write-Output "Pushing changes to the upstream branch: $RemoteName/$BranchName"
$cmdOutput = git push $RemoteName $BranchName
if ($LASTEXITCODE -ne 0) {
LogError "Could not push the changes to $RemoteName/$BranchName. Exiting..."
exit $LASTEXITCODE
}
Write-Output "Pushed the changes to remote:$RemoteName, Branch:$BranchName"

if (!$PatchInfo.PipelineName) {
$PatchInfo.PipelineName = GetPipelineName -ArtifactId $artifactId -ArtifactDirPath $artifactDirPath
Expand Down
Loading

0 comments on commit 513c87e

Please sign in to comment.