Skip to content
Open
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
127 changes: 119 additions & 8 deletions .github/workflows/vendor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -183,12 +183,112 @@ jobs:
return Invoke-RestMethod @params
}

function Set-UrlQueryParameter {
param(
[Parameter(Mandatory = $true)]
[string]$Url,

[Parameter(Mandatory = $true)]
[string]$Name,

[AllowEmptyString()]
[string]$Value
)

$encodedName = [System.Uri]::EscapeDataString($Name)
$encodedValue = [System.Uri]::EscapeDataString($Value)
$pattern = "([?&])$([regex]::Escape($encodedName))=[^&]*"
$match = [regex]::Match($Url, $pattern)
if ($match.Success) {
return $Url.Substring(0, $match.Index) + $match.Groups[1].Value + "$encodedName=$encodedValue" + $Url.Substring($match.Index + $match.Length)
}

$separator = if ($Url.Contains('?')) { '&' } else { '?' }
return "$Url$separator$encodedName=$encodedValue"
}

function ConvertTo-ReleaseBuildStatusBadge {
param(
[Parameter(Mandatory = $true)]
[string]$BadgeMarkdown,

[Parameter(Mandatory = $true)]
[hashtable]$ReleaseInfo
)

$match = [regex]::Match($BadgeMarkdown, '\[!\[(?<alt>[^\]]*)\]\((?<image>[^)]*)\)\]\((?<target>[^)]*)\)')
if (-not $match.Success) {
return '—'
}

$image = $match.Groups['image'].Value
$target = $match.Groups['target'].Value
$tagName = $ReleaseInfo.TagName
$retargeted = $false

if ($image -match '(?i)^https://dev\.azure\.com/.+/_apis/build/status' -or $target -match '(?i)^https://dev\.azure\.com/.+/_build/') {
if ($image -match '(?i)^https://dev\.azure\.com/.+/_apis/build/status') {
$image = Set-UrlQueryParameter -Url $image -Name 'branchName' -Value $tagName
$retargeted = $true
}
if ($target -match '(?i)^https://dev\.azure\.com/.+/_build/') {
$target = Set-UrlQueryParameter -Url $target -Name 'branchName' -Value $tagName
}
} elseif ($image -match '(?i)^https://github\.com/[^/]+/[^/]+/actions/workflows/[^?#]+/badge\.svg') {
$image = Set-UrlQueryParameter -Url $image -Name 'branch' -Value $tagName
if ($target -match '(?i)^https://github\.com/[^/]+/[^/]+/actions/workflows/[^?#]+') {
$target = Set-UrlQueryParameter -Url $target -Name 'query' -Value "branch:$tagName"
} else {
$target = Set-UrlQueryParameter -Url "$($ReleaseInfo.RepoUrl)/actions" -Name 'query' -Value "branch:$tagName"
}
$retargeted = $true
} elseif ($image -match '(?i)^https://github\.com/[^/]+/[^/]+/workflows/[^/]+/badge\.svg') {
$image = Set-UrlQueryParameter -Url $image -Name 'branch' -Value $tagName
if ($target -match '(?i)^https://github\.com/[^/]+/[^/]+/actions') {
$target = Set-UrlQueryParameter -Url $target -Name 'query' -Value "branch:$tagName"
} else {
$target = Set-UrlQueryParameter -Url "$($ReleaseInfo.RepoUrl)/actions" -Name 'query' -Value "branch:$tagName"
}
$retargeted = $true
}

if (-not $retargeted) {
return '—'
}

$alt = "Build status for release $tagName"
return "[![$alt]($image)]($target)"
}

function Test-BuildStatusBadgeHasReleaseStatus {
param(
[Parameter(Mandatory = $true)]
[string]$BadgeMarkdown
)

$match = [regex]::Match($BadgeMarkdown, '\[!\[(?<alt>[^\]]*)\]\((?<image>[^)]*)\)\]\((?<target>[^)]*)\)')
if (-not $match.Success) {
return $false
}

try {
$response = Invoke-WebRequest -Uri $match.Groups['image'].Value -UseBasicParsing -TimeoutSec 20
$badgeText = $response.Content.ToLowerInvariant()
return $badgeText -notmatch 'no status|never built|not found|unknown|invalid'
} catch {
Write-Verbose "Unable to verify release build badge $($match.Groups['image'].Value): $($_.Exception.Message)" -Verbose
return $false
}
}

function Get-ReadmeBuildStatusBadge {
param(
[Parameter(Mandatory = $true)]
[string]$RepoPath
[hashtable]$ReleaseInfo
)

$RepoPath = $ReleaseInfo.RepoPath

try {
$readme = Invoke-GitHubApi -Uri "https://api.github.com/repos/$RepoPath/readme"
if ([string]::IsNullOrWhiteSpace($readme.content)) {
Comment on lines +290 to 294
Expand Down Expand Up @@ -228,7 +328,10 @@ jobs:
}

if ($bestScore -gt 0 -and -not [string]::IsNullOrWhiteSpace($bestBadge)) {
return $bestBadge
$releaseBadge = ConvertTo-ReleaseBuildStatusBadge -BadgeMarkdown $bestBadge -ReleaseInfo $ReleaseInfo
if ($releaseBadge -ne '—' -and (Test-BuildStatusBadgeHasReleaseStatus -BadgeMarkdown $releaseBadge)) {
return $releaseBadge
}
}
} catch {
Write-Verbose "Unable to fetch README build badge for ${RepoPath}: $($_.Exception.Message)" -Verbose
Expand Down Expand Up @@ -306,15 +409,15 @@ jobs:
} else {
$releaseBody = $release.body.Trim()
if ($releaseBody.Length -gt 1200) {
$releaseBody = $releaseBody.Substring(0, 1200).TrimEnd() + "...`n`n_Release notes truncated; open the release link for the full text._"
$releaseBody = $releaseBody.Substring(0, 1200).TrimEnd() + "...`n`n---`n`n[!TIP]`nRelease notes truncated; [open the release notes]($releaseUrl) for the full text."
}

$notes += $releaseBody + "`n"
}
}

if ($omittedReleaseCount -gt 0) {
$notes += "`n...and $omittedReleaseCount more releases. Open the compare link for the full range.`n"
$notes += "`n...and $omittedReleaseCount more releases. [Compare changes]($($ReleaseInfo.CompareUrl)) for the full range.`n"
}

return $notes.Trim()
Expand Down Expand Up @@ -342,7 +445,9 @@ jobs:
[AllowEmptyString()]
[string]$Markdown,

[int]$MaxLength = 2500
[int]$MaxLength = 2500,

[string]$FullTextUrl
)

$text = if ([string]::IsNullOrWhiteSpace($Markdown)) {
Expand All @@ -352,7 +457,13 @@ jobs:
}

if ($text.Length -gt $MaxLength) {
$text = $text.Substring(0, $MaxLength).TrimEnd() + "...`n`n_Release notes truncated; open the release links for the full text._"
$linkedText = if ([string]::IsNullOrWhiteSpace($FullTextUrl)) {
"Release notes truncated."
} else {
"Release notes truncated; [open the release notes]($FullTextUrl) for the full text."
}

$text = $text.Substring(0, $MaxLength).TrimEnd() + "...`n`n---`n`n[!TIP]`n$linkedText"
}

return (($text -split "`r?`n") | ForEach-Object { "> $_" }) -join "`n"
Expand Down Expand Up @@ -403,7 +514,7 @@ jobs:
if ($null -ne $releaseInfo) {
$repoUrl = $releaseInfo.ReleasesUrl
$releaseUrl = $releaseInfo.ReleaseUrl
$statusBadge = Get-ReadmeBuildStatusBadge -RepoPath $releaseInfo.RepoPath
$statusBadge = Get-ReadmeBuildStatusBadge -ReleaseInfo $releaseInfo
} else {
$repoUrl = ($repoUrl = $s.Url.Replace("/archive/", "/releases/")).Substring(0, $repoUrl.IndexOf("/releases/")) + "/releases"
$releaseUrl = $repoUrl
Expand Down Expand Up @@ -444,7 +555,7 @@ jobs:
$changelogSection += "<details>`n"
$changelogSection += "<summary>$($s.name)</summary>`n`n"
$changelogSection += "[Release notes]($($releaseInfo.ReleaseUrl)) · [Compare changes]($($releaseInfo.CompareUrl))`n`n"
$changelogSection += (ConvertTo-BlockQuote -Markdown $releaseNotes -MaxLength 6000) + "`n`n"
$changelogSection += (ConvertTo-BlockQuote -Markdown $releaseNotes -MaxLength 6000 -FullTextUrl $releaseInfo.ReleaseUrl) + "`n`n"
$changelogSection += "</details>`n`n"
}

Expand Down
Loading