eng/common/scripts/artifact-metadata-parsing.ps1 (174 lines of code) (raw):

. (Join-Path $EngCommonScriptsDir SemVer.ps1) $SDIST_PACKAGE_REGEX = "^(?<package>.*)\-(?<versionstring>$([AzureEngSemanticVersion]::SEMVER_REGEX))" # Posts a github release for each item of the pkgList variable. Silently continue function CreateReleases($pkgList, $releaseApiUrl, $releaseSha) { foreach ($pkgInfo in $pkgList) { Write-Host "Creating release $($pkgInfo.Tag)" $releaseNotes = "" if ($pkgInfo.ReleaseNotes -ne $null) { $releaseNotes = $pkgInfo.ReleaseNotes } # As github api limits the body param length to 125000 characters, we have to truncate the release note if needed. if ($releaseNotes.Length -gt 124996) { $releaseNotes = $releaseNotes.SubString(0, 124996) + " ..." } $isPrerelease = $False $parsedSemver = [AzureEngSemanticVersion]::ParseVersionString($pkgInfo.PackageVersion) if ($parsedSemver) { $isPrerelease = $parsedSemver.IsPrerelease } $url = $releaseApiUrl $body = ConvertTo-Json @{ tag_name = $pkgInfo.Tag target_commitish = $releaseSha name = $pkgInfo.Tag draft = $False prerelease = $isPrerelease body = $releaseNotes } Write-Host "Post Request Body:" Write-Host $body $headers = @{ "Content-Type" = "application/json" "Authorization" = "token $($env:GH_TOKEN)" } Invoke-RestMethod -Uri $url -Body $body -Headers $headers -Method "Post" -MaximumRetryCount 3 -RetryIntervalSec 10 } } # Retrieves the list of all tags that exist on the target repository function GetExistingTags($apiUrl) { try { $headers = @{ "Authorization" = "token $($env:GH_TOKEN)" } return (Invoke-RestMethod -Method "GET" -Uri "$apiUrl/git/refs/tags" -Headers $headers -MaximumRetryCount 3 -RetryIntervalSec 10) | % { $_.ref.Replace("refs/tags/", "") } } catch { Write-Host $_ $statusCode = $_.Exception.Response.StatusCode.value__ $statusDescription = $_.Exception.Response.StatusDescription Write-Host "Failed to retrieve tags from repository." Write-Host "StatusCode:" $statusCode Write-Host "StatusDescription:" $statusDescription # Return an empty list if there are no tags in the repo if ($statusCode -eq 404) { return ,@() } exit 1 } } # Retrieve release tag for artiface package. If multiple packages, then output the first one. function RetrieveReleaseTag($artifactLocation, $continueOnError = $true) { if (!$artifactLocation) { return "" } try { $pkgs, $parsePkgInfoFn = RetrievePackages -artifactLocation $artifactLocation if (!$pkgs -or !$pkgs[0]) { Write-Host "No packages retrieved from artifact location." return "" } if ($pkgs.Count -gt 1) { Write-Host "There are more than 1 packages retieved from artifact location." foreach ($pkg in $pkgs) { Write-Host "The package name is $($pkg.BaseName)" } return "" } $parsedPackage = &$parsePkgInfoFn -pkg $pkgs[0] -workingDirectory $artifactLocation return $parsedPackage.ReleaseTag } catch { if ($continueOnError) { return "" } Write-Error "No release tag retrieved from $artifactLocation" } } function RetrievePackages($artifactLocation) { $pkgs = Get-ChildItem -Path $artifactLocation -Include $packagePattern -Recurse -File if ($GetPackageInfoFromPackageFileFn -and (Test-Path "Function:$GetPackageInfoFromPackageFileFn")) { return $pkgs, $GetPackageInfoFromPackageFileFn } else { LogError "The function for '$GetPackageInfoFromPackageFileFn' was not found.` Make sure it is present in eng/scripts/Language-Settings.ps1 and referenced in eng/common/scripts/common.ps1.` See https://github.com/Azure/azure-sdk-tools/blob/main/doc/common/common_engsys.md#code-structure" } } # Walk across all build artifacts, check them against the appropriate repository, return a list of tags/releases function VerifyPackages($artifactLocation, $workingDirectory, $apiUrl, $releaseSha, $packageFilter, $continueOnError = $false) { $pkgList = [array]@() $pkgs, $parsePkgInfoFn = RetrievePackages -artifactLocation $artifactLocation foreach ($pkg in $pkgs) { try { $parsedPackage = &$parsePkgInfoFn -pkg $pkg -workingDirectory $workingDirectory if ($parsedPackage -eq $null) { continue } if ($packageFilter -and $parsedPackage.PackageId -notlike $packageFilter) { Write-Host "Skipping package $($parsedPackage.PackageId) not matching filter $packageFilter" continue } if ($parsedPackage.Deployable -ne $True -and !$continueOnError) { Write-Host "Package $($parsedPackage.PackageId) is marked with version $($parsedPackage.PackageVersion), the version $($parsedPackage.PackageVersion) has already been deployed to the target repository." Write-Host "Maybe a pkg version wasn't updated properly?" exit 1 } $docsReadMeName = $parsedPackage.PackageId if ($parsedPackage.DocsReadMeName) { $docsReadMeName = $parsedPackage.DocsReadMeName } $pkgList += New-Object PSObject -Property @{ PackageId = $parsedPackage.PackageId PackageVersion = $parsedPackage.PackageVersion GroupId = $parsedPackage.GroupId Tag = $parsedPackage.ReleaseTag ReleaseNotes = $parsedPackage.ReleaseNotes ReadmeContent = $parsedPackage.ReadmeContent DocsReadMeName = $docsReadMeName IsPrerelease = [AzureEngSemanticVersion]::ParseVersionString($parsedPackage.PackageVersion).IsPrerelease } } catch { Write-Host $_.Exception.Message exit 1 } } $results = @([array]$pkgList | Sort-Object -Property Tag -uniq) $existingTags = GetExistingTags($apiUrl) $intersect = $results | % { $_.Tag } | ? { $existingTags -contains $_ } if ($intersect.Length -gt 0 -and !$continueOnError) { CheckArtifactShaAgainstTagsList -priorExistingTagList $intersect -releaseSha $releaseSha -apiUrl $apiUrl -continueOnError $continueOnError # all the tags are clean. remove them from the list of releases we will publish. $results = $results | ? { -not ($intersect -contains $_.Tag ) } } return $results } # given a set of tags that we want to release, we need to ensure they DO already exist. # if they DO exist, quietly exit if the commit sha of the artifact matches that of the tag # if the commit sha does not match, exit with error and report both problem shas function CheckArtifactShaAgainstTagsList($priorExistingTagList, $releaseSha, $apiUrl, $continueOnError) { $headers = @{ "Content-Type" = "application/json" "Authorization" = "token $($env:GH_TOKEN)" } $unmatchedTags = @() foreach ($tag in $priorExistingTagList) { $tagSha = (Invoke-RestMethod -Method "Get" -Uri "$apiUrl/git/refs/tags/$tag" -Headers $headers -MaximumRetryCount 3 -RetryIntervalSec 10)."object".sha if ($tagSha -eq $releaseSha) { Write-Host "This package has already been released. The existing tag commit SHA $releaseSha matches the artifact SHA being processed. Skipping release step for this tag." } else { Write-Host "The artifact SHA $releaseSha does not match that of the currently existing tag." Write-Host "Tag with issues is $tag with commit SHA $tagSha" $unmatchedTags += $tag } } if ($unmatchedTags.Length -gt 0 -and !$continueOnError) { Write-Host "Tags already existing with different SHA versions. Exiting." exit 1 } }