...
1. (Join-Path $EngCommonScriptsDir SemVer.ps1)
2
3$SDIST_PACKAGE_REGEX = "^(?<package>.*)\-(?<versionstring>$([AzureEngSemanticVersion]::SEMVER_REGEX))"
4
5# Posts a github release for each item of the pkgList variable. SilentlyContinue
6function CreateReleases($pkgList, $releaseApiUrl, $releaseSha) {
7 foreach ($pkgInfo in $pkgList) {
8 Write-Host "Creating release $($pkgInfo.Tag)"
9
10 $releaseNotes = ""
11 if ($pkgInfo.ReleaseNotes -ne $null) {
12 $releaseNotes = $pkgInfo.ReleaseNotes
13 }
14 # As github api limit the body param length with 125000 characters, we have to truncate the release note if needed.
15 if ($releaseNotes.Length -gt 124996) {
16 $releaseNotes = $releaseNotes.SubString(0, 124996) + " ..."
17 }
18
19 $isPrerelease = $False
20
21 $parsedSemver = [AzureEngSemanticVersion]::ParseVersionString($pkgInfo.PackageVersion)
22
23 if ($parsedSemver) {
24 $isPrerelease = $parsedSemver.IsPrerelease
25 }
26
27 $url = $releaseApiUrl
28 $body = ConvertTo-Json @{
29 tag_name = $pkgInfo.Tag
30 target_commitish = $releaseSha
31 name = $pkgInfo.Tag
32 draft = $False
33 prerelease = $isPrerelease
34 body = $releaseNotes
35 }
36
37 $headers = @{
38 "Content-Type" = "application/json"
39 "Authorization" = "token $($env:GH_TOKEN)"
40 }
41
42 Invoke-RestMethod -Uri $url -Body $body -Headers $headers -Method "Post" -MaximumRetryCount 3 -RetryIntervalSec 10
43 }
44}
45
46# Retrieves the list of all tags that exist on the target repository
47function GetExistingTags($apiUrl) {
48 try {
49 $headers = @{
50 "Authorization" = "token $($env:GH_TOKEN)"
51 }
52 return (Invoke-RestMethod -Method "GET" -Uri "$apiUrl/git/refs/tags" -Headers $headers -MaximumRetryCount 3 -RetryIntervalSec 10) | % { $_.ref.Replace("refs/tags/", "") }
53 }
54 catch {
55 Write-Host $_
56 $statusCode = $_.Exception.Response.StatusCode.value__
57 $statusDescription = $_.Exception.Response.StatusDescription
58
59 Write-Host "Failed to retrieve tags from repository."
60 Write-Host "StatusCode:" $statusCode
61 Write-Host "StatusDescription:" $statusDescription
62
63 # Return an empty list if there are no tags in the repo
64 if ($statusCode -eq 404) {
65 return ,@()
66 }
67
68 exit(1)
69 }
70}
71
72# Retrieve release tag for artiface package. If multiple packages, then output the first one.
73function RetrieveReleaseTag($artifactLocation, $continueOnError = $true) {
74 if (!$artifactLocation) {
75 return ""
76 }
77 try {
78 $pkgs, $parsePkgInfoFn = RetrievePackages -artifactLocation $artifactLocation
79 if (!$pkgs -or !$pkgs[0]) {
80 Write-Host "No packages retrieved from artifact location."
81 return ""
82 }
83 if ($pkgs.Count -gt 1) {
84 Write-Host "There are more than 1 packages retieved from artifact location."
85 foreach ($pkg in $pkgs) {
86 Write-Host "The package name is $($pkg.BaseName)"
87 }
88 return ""
89 }
90 $parsedPackage = &$parsePkgInfoFn -pkg $pkgs[0] -workingDirectory $artifactLocation
91 return $parsedPackage.ReleaseTag
92 }
93 catch {
94 if ($continueOnError) {
95 return ""
96 }
97 Write-Error "No release tag retrieved from $artifactLocation"
98 }
99}
100
101function RetrievePackages($artifactLocation) {
102 $pkgs = Get-ChildItem -Path $artifactLocation -Include $packagePattern -Recurse -File
103 if ($GetPackageInfoFromPackageFileFn -and (Test-Path "Function:$GetPackageInfoFromPackageFileFn"))
104 {
105 return $pkgs, $GetPackageInfoFromPackageFileFn
106 }
107 else
108 {
109 LogError "The function for '$GetPackageInfoFromPackageFileFn' was not found.`
110 Make sure it is present in eng/scripts/Language-Settings.ps1 and referenced in eng/common/scripts/common.ps1.`
111 See https://github.com/Azure/azure-sdk-tools/blob/main/doc/common/common_engsys.md#code-structure"
112 }
113}
114
115# Walk across all build artifacts, check them against the appropriate repository, return a list of tags/releases
116function VerifyPackages($artifactLocation, $workingDirectory, $apiUrl, $releaseSha, $continueOnError = $false) {
117 $pkgList = [array]@()
118 $pkgs, $parsePkgInfoFn = RetrievePackages -artifactLocation $artifactLocation
119
120 foreach ($pkg in $pkgs) {
121 try {
122 $parsedPackage = &$parsePkgInfoFn -pkg $pkg -workingDirectory $workingDirectory
123
124 if ($parsedPackage -eq $null) {
125 continue
126 }
127
128 if ($parsedPackage.Deployable -ne $True -and !$continueOnError) {
129 Write-Host "Package $($parsedPackage.PackageId) is marked with version $($parsedPackage.PackageVersion), the version $($parsedPackage.PackageVersion) has already been deployed to the target repository."
130 Write-Host "Maybe a pkg version wasn't updated properly?"
131 exit(1)
132 }
133 $docsReadMeName = $parsedPackage.PackageId
134 if ($parsedPackage.DocsReadMeName) {
135 $docsReadMeName = $parsedPackage.DocsReadMeName
136 }
137 $pkgList += New-Object PSObject -Property @{
138 PackageId = $parsedPackage.PackageId
139 PackageVersion = $parsedPackage.PackageVersion
140 GroupId = $parsedPackage.GroupId
141 Tag = $parsedPackage.ReleaseTag
142 ReleaseNotes = $parsedPackage.ReleaseNotes
143 ReadmeContent = $parsedPackage.ReadmeContent
144 DocsReadMeName = $docsReadMeName
145 IsPrerelease = [AzureEngSemanticVersion]::ParseVersionString($parsedPackage.PackageVersion).IsPrerelease
146 }
147 }
148 catch {
149 Write-Host $_.Exception.Message
150 exit(1)
151 }
152 }
153
154 $results = @([array]$pkgList | Sort-Object -Property Tag -uniq)
155
156 $existingTags = GetExistingTags($apiUrl)
157
158 $intersect = $results | % { $_.Tag } | ? { $existingTags -contains $_ }
159
160 if ($intersect.Length -gt 0 -and !$continueOnError) {
161 CheckArtifactShaAgainstTagsList -priorExistingTagList $intersect -releaseSha $releaseSha -apiUrl $apiUrl -continueOnError $continueOnError
162
163 # all the tags are clean. remove them from the list of releases we will publish.
164 $results = $results | ? { -not ($intersect -contains $_.Tag ) }
165 }
166
167 return $results
168}
169
170# given a set of tags that we want to release, we need to ensure that if they already DO exist.
171# if they DO exist, quietly exit if the commit sha of the artifact matches that of the tag
172# if the commit sha does not match, exit with error and report both problem shas
173function CheckArtifactShaAgainstTagsList($priorExistingTagList, $releaseSha, $apiUrl, $continueOnError) {
174 $headers = @{
175 "Content-Type" = "application/json"
176 "Authorization" = "token $($env:GH_TOKEN)"
177 }
178
179 $unmatchedTags = @()
180
181 foreach ($tag in $priorExistingTagList) {
182 $tagSha = (Invoke-RestMethod -Method "Get" -Uri "$apiUrl/git/refs/tags/$tag" -Headers $headers -MaximumRetryCount 3 -RetryIntervalSec 10)."object".sha
183
184 if ($tagSha -eq $releaseSha) {
185 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."
186 }
187 else {
188 Write-Host "The artifact SHA $releaseSha does not match that of the currently existing tag."
189 Write-Host "Tag with issues is $tag with commit SHA $tagSha"
190
191 $unmatchedTags += $tag
192 }
193 }
194
195 if ($unmatchedTags.Length -gt 0 -and !$continueOnError) {
196 Write-Host "Tags already existing with different SHA versions. Exiting."
197 exit(1)
198 }
199}
View as plain text