Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…into azure_purview_catalog

* 'master' of https://github.com/Azure/azure-sdk-for-python:
  [Tables] hot fix for pipelines (Azure#18273)
  [Tables] Updates for apiview & sphinx docs (Azure#18134)
  override purview deps in shared reqs (Azure#18270)
  [Service Bus] fix deadletter sample + update README (Azure#18261)
  Update credential docstrings (Azure#18205)
  Refactor ImdsCredential to use ManagedIdentityClient (Azure#18120)
  [Key Vault] Target multiple API versions with tests (keys) (Azure#18149)
  Initial ModelsRepositoryClient (Azure#17180)
  [Communication]: Enabled Phone Number Search Test (Azure#18247)
  [Key Vault] Update default MHSM location for tests
  Update identity migration guide (Azure#18239)
  [AutoRelease] t2-managedservices-2021-04-22-08436(wave4) (Azure#18224)
  [AutoRelease] t2-hybridnetwork-2021-04-20-93742 (Azure#18169)
  Add Key Vault cert suppression (Azure#18245)
  update to aab1fb9 (Azure#18246)
  Enable retain runs. (Azure#18200)
  [formrecognizer] add testcases for labeled tables - fixed/variable rows (Azure#18214)
  Add caching support to verify-links (Azure#18231)
  add reading order for logging (Azure#18233)
  [purview] allow purview pylint failures (Azure#18237)
  • Loading branch information
iscai-msft committed Apr 23, 2021
2 parents 9191859 + e2b5a4a commit 52d0341
Show file tree
Hide file tree
Showing 513 changed files with 215,316 additions and 28,586 deletions.
3 changes: 3 additions & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@
# PRLabel: %HDInsight
/sdk/hdinsight/ @idear1203

# PRLabel: %Models repository
/sdk/modelsrepository/ @cartertinney @digimaun

# PRLabel: %Machine Learning Compute
/sdk/machinelearningcompute/ @shutchings

Expand Down
3 changes: 2 additions & 1 deletion eng/CredScanSuppression.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"p@55wOrd",
"pass$w0rd",
"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",
],
"_justification": "Secret used by test code, it is fake."
},
Expand All @@ -45,4 +46,4 @@
"_justification": "File contains private key used by test code."
}
]
}
}
5 changes: 3 additions & 2 deletions eng/common/pipelines/templates/steps/verify-links.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ steps:
arguments: >
-urls ${{ parameters.Urls }}
-rootUrl "file://${{ parameters.WorkingDirectory }}/${{ parameters.Directory }}"
-recursive: ${{ parameters.Recursive }}
-recursive: ${{ parameters.Recursive }}
-ignoreLinksFile ${{ parameters.IgnoreLinksFile }}
-branchReplaceRegex "${{ parameters.BranchReplaceRegex }}"
-branchReplacementName ${{ parameters.BranchReplacementName }}
-devOpsLogging: $true
-checkLinkGuidance: ${{ parameters.CheckLinkGuidance }}
-checkLinkGuidance: ${{ parameters.CheckLinkGuidance }}
-inputCacheFile "https://azuresdkartifacts.blob.core.windows.net/verify-links-cache/verify-links-cache.txt"
182 changes: 131 additions & 51 deletions eng/common/scripts/Verify-Links.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -12,47 +12,48 @@
Specifies the file that contains a set of links to ignore when verifying.
.PARAMETER devOpsLogging
Switch that will enable devops specific logging for warnings
Switch that will enable devops specific logging for warnings
.PARAMETER recursive
Check the links recurisvely based on recursivePattern.
Check the links recurisvely based on recursivePattern.
.PARAMETER baseUrl
Recursively check links for all links verified that begin with this baseUrl, defaults to the folder the url is contained in.
.PARAMETER rootUrl
Path to the root of the site for resolving rooted relative links, defaults to host root for http and file directory for local files.
Path to the root of the site for resolving rooted relative links, defaults to host root for http and file directory for local files.
.PARAMETER errorStatusCodes
List of http status codes that count as broken links. Defaults to 400, 401, 404, SocketError.HostNotFound = 11001, SocketError.NoData = 11004.
List of http status codes that count as broken links. Defaults to 400, 401, 404, SocketError.HostNotFound = 11001, SocketError.NoData = 11004.
.PARAMETER branchReplaceRegex
Regex to check if the link needs to be replaced. E.g. ^(https://github.com/.*/(?:blob|tree)/)master(/.*)$
.PARAMETER branchReplacementName
The substitute branch name or SHA commit.
The substitute branch name or SHA commit.
.PARAMETER checkLinkGuidance
Flag to allow checking against azure sdk link guidance. Check link guidance here: https://aka.ms/azsdk/guideline/links.
Flag to allow checking against azure sdk link guidance. Check link guidance here: https://aka.ms/azsdk/guideline/links.
.PARAMETER userAgent
UserAgent to be configured for web requests. Defaults to current Chrome version.
.INPUTS
None. No required inputs.
.PARAMETER inputCacheFile
Path to a file that contains a list of links that are known valid so we can skip checking them.
.OUTPUTS
None. Verify-Links.ps1 does not generate any output.
.PARAMETER outputCacheFile
Path to a file that the script will output all the validated links after running all checks.
.EXAMPLE
PS> .\Verify-Links.ps1
PS> .\Verify-Links.ps1 C:\README.md
.EXAMPLE
PS> .\Verify-Links.ps1 -urls C:\README.md
PS> .\Verify-Links.ps1 https://azure.github.io/azure-sdk/index.html
.EXAMPLE
PS> .\Verify-Links -urls C:\README.md -checkLinkGuidance $true
PS> .\Verify-Links C:\README.md -checkLinkGuidance $true
#>
[CmdletBinding()]
param (
[string[]] $urls,
[string] $ignoreLinksFile = "$PSScriptRoot/ignore-links.txt",
Expand All @@ -64,7 +65,9 @@ param (
[string] $branchReplaceRegex = "",
[string] $branchReplacementName = "",
[bool] $checkLinkGuidance = $false,
[string] $userAgent
[string] $userAgent,
[string] $inputCacheFile,
[string] $outputCacheFile
)

$ProgressPreference = "SilentlyContinue"; # Disable invoke-webrequest progress dialog
Expand All @@ -88,7 +91,7 @@ function NormalizeUrl([string]$url){
}

if ($script:rootUrl -eq "") {
if ($uri.IsFile) {
if ($uri.IsFile) {
# for files default to the containing directory
$script:rootUrl = $script:baseUrl;
}
Expand Down Expand Up @@ -129,7 +132,7 @@ function ResolveUri ([System.Uri]$referralUri, [string]$link)
# If the link is mailto, skip it.
if ($link.StartsWith("mailto:")) {
Write-Verbose "Skipping $link because it is a mailto link."
return $null
return
}

$linkUri = [System.Uri]$link;
Expand All @@ -156,12 +159,12 @@ function ResolveUri ([System.Uri]$referralUri, [string]$link)
# If the link is not a web request, like mailto, skip it.
if (!$linkUri.Scheme.StartsWith("http") -and !$linkUri.IsFile) {
Write-Verbose "Skipping $linkUri because it is not http or file based."
return $null
return
}

if ($null -ne $ignoreLinks -and ($ignoreLinks.Contains($link) -or $ignoreLinks.Contains($linkUri.ToString()))) {
Write-Verbose "Ignoring invalid link $linkUri because it is in the ignore file."
return $null
return
}

return $linkUri;
Expand All @@ -177,28 +180,34 @@ function ParseLinks([string]$baseUri, [string]$htmlContent)
#$hrefs | Foreach-Object { Write-Host $_ }

Write-Verbose "Found $($hrefs.Count) raw href's in page $baseUri";
$links = $hrefs | ForEach-Object { ResolveUri $baseUri $_.Groups["href"].Value } | Sort-Object -Unique
$links = $hrefs | ForEach-Object { ResolveUri $baseUri $_.Groups["href"].Value }

#$links | Foreach-Object { Write-Host $_ }

return $links
}

function CheckLink ([System.Uri]$linkUri)
function CheckLink ([System.Uri]$linkUri, $allowRetry=$true)
{
if(!$linkUri.ToString().Trim()) {
LogWarning "Found Empty link. Please use absolute link instead. Check here for more information: https://aka.ms/azsdk/guideline/links"
return $false
}
if ($checkedLinks.ContainsKey($linkUri)) {
if (!$checkedLinks[$linkUri]) {
LogWarning "broken link $linkUri"

$originalLinkUri = $linkUri
$linkUri = ReplaceGithubLink $linkUri

$link = $linkUri.ToString()

if ($checkedLinks.ContainsKey($link)) {
if (!$checkedLinks[$link]) {
LogWarning "broken link $link"
}
return $checkedLinks[$linkUri]
return $checkedLinks[$link]
}

$linkValid = $true
Write-Verbose "Checking link $linkUri..."
Write-Verbose "Checking link $linkUri..."

if ($linkUri.IsFile) {
if (!(Test-Path $linkUri.LocalPath)) {
Expand Down Expand Up @@ -234,27 +243,58 @@ function CheckLink ([System.Uri]$linkUri)
}

if ($statusCode -in $errorStatusCodes) {
LogWarning "[$statusCode] broken link $linkUri"
if ($originalLinkUri -ne $linkUri) {
LogWarning "[$statusCode] broken link $originalLinkUri (resolved to $linkUri)"
}
else {
LogWarning "[$statusCode] broken link $linkUri"
}

$linkValid = $false
}
else {
if ($null -ne $statusCode) {
Write-Host "[$statusCode] while requesting $linkUri"
# For 429 rate-limiting try to pause if possible
if ($allowRetry -and $_.Exception.Response -and $statusCode -eq 429) {
$retryAfter = $_.Exception.Response.Headers.RetryAfter.Delta.TotalSeconds

# Default retry after 60 (arbitrary) seconds if no header given
if (!$retryAfter -or $retryAfter -gt 60) { $retryAfter = 60 }
Write-Host "Rate-Limited for $retryAfter seconds while requesting $linkUri"

Start-Sleep -Seconds $retryAfter
$linkValid = CheckLink $originalLinkUri -allowRetry $false
}
else {
Write-Host "[$statusCode] handled while requesting $linkUri"
# Override and set status code in the cache so it is truthy
# so we don't keep checking but we don't think it is valid either
$linkValid = $statusCode
}
}
else {
Write-Host "Exception while requesting $linkUri"
Write-Host $_.Exception.ToString()
# Override and set exception in the cache so it is truthy
# so we don't keep checking but we don't think it is valid either
$linkValid = "Exception"
}
}
}
}

elseif ($link.StartsWith("#")) {
# Ignore anchor links as we don't have a great way to check them.
}
else {
LogWarning "Link has invalid format $linkUri"
$linkValid = $false
}

if ($checkLinkGuidance) {
if ($linkUri.Scheme -eq 'http') {
LogWarning "DO NOT use 'http' in $linkUri. Please use secure link with https instead. Check here for more information: https://aka.ms/azsdk/guideline/links"
$linkValid = $false
}
$link = $linkUri.ToString()
# Check if the url is relative links, suppress the archor link validation.
if (!$linkUri.IsAbsoluteUri -and !$link.StartsWith("#")) {
LogWarning "DO NOT use relative link $linkUri. Please use absolute link instead. Check here for more information: https://aka.ms/azsdk/guideline/links"
Expand All @@ -272,16 +312,16 @@ function CheckLink ([System.Uri]$linkUri)
}
}

$checkedLinks[$linkUri] = $linkValid
$checkedLinks[$link] = $linkValid
return $linkValid
}

function ReplaceGithubLink([string]$originLink) {
if (!$branchReplacementName) {
if (!$branchReplacementName -or !$branchReplaceRegex) {
return $originLink
}
$ReplacementPattern = "`${1}$branchReplacementName`$2"
return $originLink -replace $branchReplaceRegex, $ReplacementPattern
return $originLink -replace $branchReplaceRegex, $ReplacementPattern
}

function GetLinks([System.Uri]$pageUri)
Expand Down Expand Up @@ -327,25 +367,55 @@ if ($urls) {
if ($urls.Count -eq 0) {
Write-Host "Usage $($MyInvocation.MyCommand.Name) <urls>";
exit 1;
}
}
}

if ($PSVersionTable.PSVersion.Major -lt 6)
{
LogWarning "Some web requests will not work in versions of PS earlier then 6. You are running version $($PSVersionTable.PSVersion)."
}
$ignoreLinks = @();
if (Test-Path $ignoreLinksFile)
if (Test-Path $ignoreLinksFile) {
$ignoreLinks = (Get-Content $ignoreLinksFile).Where({ $_.Trim() -ne "" -and !$_.StartsWith("#") })
}

# Use default hashtable constructor instead of @{} because we need them to be case sensitive
$checkedPages = New-Object Hashtable
$checkedLinks = New-Object Hashtable

if ($inputCacheFile)
{
$ignoreLinks = [Array](Get-Content $ignoreLinksFile | ForEach-Object { ($_ -replace "#.*", "").Trim() } | Where-Object { $_ -ne "" })
$cacheContent = ""
if ($inputCacheFile.StartsWith("http")) {
try {
$response = Invoke-WebRequest -Uri $inputCacheFile
$cacheContent = $response.Content
}
catch {
$statusCode = $_.Exception.Response.StatusCode.value__
Write-Error "Failed to read cache file from page [$statusCode] $inputCacheFile"
}
}
elseif (Test-Path $inputCacheFile) {
$cacheContent = Get-Content $inputCacheFile -Raw
}
$goodLinks = $cacheContent.Split("`n").Where({ $_.Trim() -ne "" -and !$_.StartsWith("#") })

foreach ($goodLink in $goodLinks) {
$checkedLinks[$goodLink] = $true
}
}

$checkedPages = @{};
$checkedLinks = @{};
$badLinks = @{};
$cachedLinksCount = $checkedLinks.Count

if ($cachedLinksCount) {
Write-Host "Skipping checks on $cachedLinksCount links found in the given cache of known good links."
}

$badLinks = New-Object Hashtable
$pageUrisToCheck = new-object System.Collections.Queue
foreach ($url in $urls) {
$uri = NormalizeUrl $url
$uri = NormalizeUrl $url
$pageUrisToCheck.Enqueue($uri);
}

Expand All @@ -359,8 +429,7 @@ while ($pageUrisToCheck.Count -ne 0)
Write-Host "Found $($linkUris.Count) links on page $pageUri";
$badLinksPerPage = @();
foreach ($linkUri in $linkUris) {
$replacedLink = ReplaceGithubLink $linkUri
$isLinkValid = CheckLink $replacedLink
$isLinkValid = CheckLink $linkUri
if (!$isLinkValid -and !$badLinksPerPage.Contains($linkUri)) {
if (!$linkUri.ToString().Trim()) {
$linkUri = $emptyLinkMessage
Expand Down Expand Up @@ -388,10 +457,21 @@ foreach ($pageLink in $badLinks.Keys) {
}
}

$linksChecked = $checkedLinks.Count - $cachedLinksCount

if ($badLinks.Count -gt 0) {
LogError "Found $($checkedLinks.Count) links with $($badLinks.Count) page(s) broken."
}
LogError "Checked $linksChecked links with $($badLinks.Count) page(s) broken."
}
else {
Write-Host "Found $($checkedLinks.Count) links. No broken links found."
Write-Host "Checked $linksChecked links. No broken links found."
}

if ($outputCacheFile)
{
$goodLinks = $checkedLinks.Keys.Where({ "True" -eq $checkedLinks[$_].ToString() }) | Sort-Object

Write-Host "Writing the list of validated links to $outputCacheFile"
$goodLinks | Set-Content $outputCacheFile
}

exit $badLinks.Count
Loading

0 comments on commit 52d0341

Please sign in to comment.