azure-sdk-for-cpp/eng/common/scripts/Verify-Links.ps1
Larry Osterman 7c52924288
Sync Main branch with WebSockets branch. (#4072)
* Stress test (#3820)

* mem leak fix

* PR comments fix

* PR comments

* seems to work?

* clang

* curl again

* add first stress test

* also update gitignore

* missing line

* only linux

* clang typo format

* typo 2

* PR comments

* cspell

* remove terminator

* Fixed the metadata for better handling (#3824)

Co-authored-by: sima-zhu <sizhu@microsoft.com>

* Update attestation core vcpkg dependency to latest GA version that is required. (#3830)

* Update attestation core vcpkg dependency to latest GA version that is required.

* Update vcpkg config.cmake to match the dependency version needed.

* Remove winhttp (#3832)

* remove refs to winhttp

* this tsst only curl

* Move perf.yml to eng/common (#3833)

Co-authored-by: Mike Harder <mharder@microsoft.com>

* Sync eng/common directory with azure-sdk-tools for PR 3656 (#3834)

* someone wants to reference the test-proxy startup scripts externally. to make this easy on them we're parameterizing the root of the eng/common for easy use in that scenario
* two leading $ signs on the definition of the certificate path was causing some issues!

Co-authored-by: scbedd <45376673+scbedd@users.noreply.github.com>

* Update casing for 'verison' (#3821)

Co-authored-by: Daniel Jurek <djurek@microsoft.com>

* Print additional result summary formats to pipelines UI (#3842)

Co-authored-by: Mike Harder <mharder@microsoft.com>

* Sync eng/common directory with azure-sdk-tools for PR 3702 (#3843)

* Add language-service to list of valid sample slugs

* Update link to taxonomies

Co-authored-by: Heath Stewart <heaths@microsoft.com>

* Fix incorrect failure notification in vcpkg publishing (#3838)

* Set up for testing of template pipeline

* Override branches, set up for template GA release

* More TODOs to prevent merging an unintended change

* More removal of TestPipeline

* Increment template version number

* Use script to set package version

* Check out the correct branch

* branch parameter in the command

* Use $(PublishToVcpkg) to determine if we should check for changes

* dictionary syntax

* Set GA package version to validate GA publish scenario

* Update changelog

* create-pull-request.yml optionally pushes changes

* Output GH PR URI

* Macro syntax with a variable set earlier

* Move up to 1.2.0-beta.2

* beta.1

* Revert changelog

* Revert testing-related changes

* Revert vcpkg-clone.yml

* Revert eng/common changes, ensure global $(HasChanges) is set properly

* Changes to enable testing

* 1.1.0-beta.1

* vcpkg clone should clone at configured branch

* Clone "main" branch of vcpkg betas

* Undo test-specific changes

* More PR cleanup

* PR cleanup

* Helm charts (#3841)

* helm chart

* first pipe setup

* poi

* magiks

* ewewe

* stress

* cleanup

* pr

* QFE and readme

* clang

* stupid clang , waste of time

* ewqwewewrqrewewrqewrqwrqr

* stupid clang

* cspell

* PR

* try try again

* clang again

* Sync eng/common directory with azure-sdk-tools for PR 3661 (#3846)

* Add full clone fallback to sparse checkout

* Improve clone handling and overrides for sparse checkout

* Use SkipSparseCheckout variable name

Co-authored-by: Ben Broderick Phillips <bebroder@microsoft.com>

* Sync eng/common directory with azure-sdk-tools for PR 3735 (#3845)

* Detect API changes using new snadboxinx approach

* Added strictmode

* Remove unset variable

* Changes as per strict mode 3

* Rervert strict mode to allow language level fixes to merge first

Co-authored-by: praveenkuttappan <prmarott@microsoft.com>

* Increment version for keyvault releases (#3809)

* Increment package version after release of azure-security-keyvault-keys

* Increment package version after release of azure-security-keyvault-secrets

* Increment package version after release of azure-security-keyvault-certificates

* Removed hard dependency on opentelemetry version (#3844)

* Revert "Add full clone fallback to sparse checkout (#3661)" (#3851)

This reverts commit 7605ead00308dd20f20f2afe5acc4ec9900a2c47.

Co-authored-by: Ben Broderick Phillips <ben@benbp.net>

* Sync eng/common directory with azure-sdk-tools for PR 3753 (#3857)

* Bump MacOs version to macos-11

* Update eng/common/scripts/job-matrix/tests/job-matrix-functions.tests.ps1

Co-authored-by: Wes Haggard <weshaggard@users.noreply.github.com>

* Update eng/common/scripts/job-matrix/tests/job-matrix-functions.tests.ps1

Co-authored-by: Wes Haggard <weshaggard@users.noreply.github.com>

Co-authored-by: sima-zhu <sizhu@microsoft.com>
Co-authored-by: Sima Zhu <48036328+sima-zhu@users.noreply.github.com>
Co-authored-by: Wes Haggard <weshaggard@users.noreply.github.com>

* Bump macOs version to macos-11 (#3853)

* Update CHANGELOG.md

* Fix misleading step name in az module install (#3859)

Co-authored-by: Ben Broderick Phillips <bebroder@microsoft.com>

* Retry poll calls on EINTR (#3858)

When signals are delievered to the process, calls here to poll may be
interrupted and return with a spurious failure.  The call instead should be
restarted.

* Fix bad path to sample matrix json (#3860)

Co-authored-by: Ben Broderick Phillips <bebroder@microsoft.com>

* Sync eng/common directory with azure-sdk-tools for PR 3826 (#3863)

* Add link checking for stress CI

* Remove region segment from stress testing links

Co-authored-by: Ben Broderick Phillips <bebroder@microsoft.com>

* Core August releases (#3862)

* Core August releases

* cspell

Co-authored-by: Anton Kolesnyk <antkmsft@users.noreply.github.com>

* Increment version for core releases (#3865)

* Increment package version after release of azure-core

* Increment package version after release of azure-core-tracing-opentelemetry

* Storage Aug GA release (#3864)

* CG only runs on internal (#3866)

* Condition added and indentation changes

* STG 79 80 81 Features (#3850)

* Sync eng/common directory with azure-sdk-tools for PR 3860 (#3871)

* updating pfx and cert
* update the targeted version of the proxy as well

Co-authored-by: scbedd <45376673+scbedd@users.noreply.github.com>

* Storage August Preview Release (#3868)

* Storage August Preview Release

* update versions

* Increment version for storage releases (#3875)

* Increment package version after release of azure-storage-common

* Increment package version after release of azure-storage-blobs

* Fix an issue that reason phrase is missing as expected from HTTP/2 server (#3879)

* Fix an issue that reason phrase is missing as expected from HTTP/2 server

* reverse the condition

* compact comments

* fix clang format

* Update CODEOWNERS (#3881)

* updated targeted proxy version to one that properly allows consumption of TLS certificates (#3888)

Co-authored-by: scbedd <45376673+scbedd@users.noreply.github.com>

* Fix `azure-storage-blobs-cpp` beta install (#3889)

Co-authored-by: Anton Kolesnyk <antkmsft@users.noreply.github.com>

* Fixed #3899 - Handle new OSX version correctly; reformatted platform-matrix JSON files (#3900)

* Simpler get-binarysizes check for OSX (#3901)

* Simpler get-binarysizes check for OSX

* Missed wildcard

* Sync eng/common directory with azure-sdk-tools for PR 3874 (#3907)

* Add sparse checkout to perf template

* Rename base template, add parameters

* Add comment

* Add TODO

* Fix copy/pase bug, add language to artifacts path

* Fix language ref

* Fix python language

* perf.yml extends perf-base.yml

* Remove unnecessary base yml

* Fetch pull request refs

* Fix refs path

* Fetch commitish if matches PR syntax

* Print command before running

* Add PR commitish to remote.origin.fetch

* Add pool and vmimage parameters

* Map ref under "refs/remotes/origin"

* Add ref to refs/remotes/origin

Co-authored-by: Mike Harder <mharder@microsoft.com>

* File Share Features until STG82 (#3908)

* Empty file or existing file won't be created/overwritten if the blob to be downloaded doesn't exist. (#3910)

* Remove unnecessary checkout: none that causes conflicts with sparse checkout declarations (#3915)

Co-authored-by: Ben Broderick Phillips <bebroder@microsoft.com>

* Core September Release (#3913)

Co-authored-by: Anton Kolesnyk <antkmsft@users.noreply.github.com>

* Increment package version after release of azure-core (#3919)

* Migrate SkipDefaultCheckout to SkipCheckoutNone (#3916)

Co-authored-by: Ben Broderick Phillips <bebroder@microsoft.com>

* Storage Sept Release (#3914)

* Increment version for storage releases (#3924)

* Increment package version after release of azure-storage-common

* Increment package version after release of azure-storage-blobs

* Increment package version after release of azure-storage-files-shares

* Add github actions based check enforcer (#3922)

* Add `$schema` to `cgmanifest.json` (#3918)

Co-authored-by: Jamie Magee <jamie.magee@microsoft.com>

* Remove SkipDefaultCheckout parameter (#3930)

Co-authored-by: Ben Broderick Phillips <bebroder@microsoft.com>

* Compatibility improvement for striped blob (#3932)

* add a parameter 'condition' to the test-proxy ci invocations. (#3931)

Co-authored-by: scbedd <45376673+scbedd@users.noreply.github.com>

* storage ad-hoc release (#3934)

* Increment package version after release of azure-storage-blobs (#3935)

* Update `AttestationClient::AttestTpm` API to match existing `AttestOpenEnclave` and `AttestSgxmEnclave`  (#3928)

* Fix broken link and typo in contributing.md

* Use vector<uint8_t> for attest instead of strings

* remove options

* fix comments

* update release version

* remove versionig

* revert changelog

* add the change

* update comment

* Update sdk/attestation/azure-security-attestation/CHANGELOG.md

Co-authored-by: Larry Osterman <LarryOsterman@users.noreply.github.com>

* fix formatting

* address pr comment

* fix formating

* update a comment

* remove the attest tpm comment

Co-authored-by: Peng Li <pengfeli@microsoft.com>
Co-authored-by: Larry Osterman <LarryOsterman@users.noreply.github.com>

* Update check enforcer yaml permissions and name (#3944)

* Set VCPKG_ROOT (#3938)

* Set VCPKG_ROOT

* Update eng/pipelines/templates/steps/vcpkg-clone.yml

Co-authored-by: Ben Broderick Phillips <bebroder@microsoft.com>

Co-authored-by: Ben Broderick Phillips <bebroder@microsoft.com>

* Sync the devops helper scripts between azure-sdk repo and tools repo (#3949)

This should fix https://github.com/Azure/azure-sdk-tools/issues/3538
as it will now upgrade the devops extension to the latest version
which has the auth fix needed.

Co-authored-by: Wes Haggard <Wes.Haggard@microsoft.com>

* Add Win32FileTimeConverter (#3941)

* Sync eng/common directory with azure-sdk-tools for PR 4169 (#3950)

* pin newest version of proxy

Co-authored-by: scbedd <45376673+scbedd@users.noreply.github.com>

* Enable Query() test in blob SDK (#3960)

* Sync eng/common directory with azure-sdk-tools for PR 4212 (#3962)

* version including lock fixes
* target the correct proxy version

Co-authored-by: scbedd <45376673+scbedd@users.noreply.github.com>

* Pipeline core (#3953)

* test1

* glob

* quick cleanup

* ddasda

* ddsa

* envs

* dsds

* Revert "ddsa"

This reverts commit 6d9e385284ba37736fb5bc41e56065943abd7937.

* wq

* comment out issues

* valid test

* maybe

* qwewqewq

* lang steps

* Vcpkg pre-steps in the place Daniel should've recommend they go

* RepoOwner

* Correct repo owner name

* Remove vcpkg.yml (we don't need to write)

* PR trigger

* small change

* Update eng/pipelines/templates/jobs/perf.yml

Co-authored-by: Mike Harder <mharder@microsoft.com>

* Update eng/pipelines/templates/jobs/perf.yml

Co-authored-by: Mike Harder <mharder@microsoft.com>

* Update sdk/core/perf.yml

Co-authored-by: Mike Harder <mharder@microsoft.com>

Co-authored-by: Daniel Jurek <djurek@microsoft.com>
Co-authored-by: Mike Harder <mharder@microsoft.com>

* Win32FileTimeConverter (#3967)

* Sync eng/common directory with azure-sdk-tools for PR 4240 (#3965)

* use version of docker with CLI present

* target repaired executable

Co-authored-by: scbedd <45376673+scbedd@users.noreply.github.com>

* Revert "Add Win32FileTimeConverter (#3941)" (#3966)

This reverts commit 14e4f52b91.

* add test case for batch options on snapshots and versions (#3970)

* add test case for batch options on snapshots and versions

* recording

* Merge feature/datalakestg82 (#3973)

* Build subscription configuration from cloud config values (#3976)

* fix LROs in keyvault (#3952)

* fix LROs in keyvault

* qfe

* some cleanup

* fdd

* clangs

* correct fix

* oops

* Pull all Websockets changes to main except for WebSockets itself. (#3954)

* Pulled WebSocket fixes into main except for WebSockets functionality


Co-authored-by: Rick Winter <rick.winter@microsoft.com>
Co-authored-by: Daniel Jurek <djurek@microsoft.com>
Co-authored-by: George Arama <50641385+gearama@users.noreply.github.com>
Co-authored-by: Ahson Khan <ahson_ahmedk@yahoo.com>
Co-authored-by: Ben Broderick Phillips <bebroder@microsoft.com>
Co-authored-by: Anton Kolesnyk <antkmsft@users.noreply.github.com>

* Upadte Attestation changelog.md (#3992)

* Remove cspell directive from being visible (#3993)

* Update Attestation readme.md (#3991)

* Fixed memory leak in curl (#3995)

* Fixed memory leak in curl

* fixed documentation in unique_handle.hpp

* Fixup comment in unique_handle.hpp to reference curl_easy_cleanup rather than curl_free. (#3997)

* Azure Core October Release (#3996)

* Azure Core October Release

Co-authored-by: Anton Kolesnyk <antkmsft@users.noreply.github.com>
Co-authored-by: Larry Osterman <LarryOsterman@users.noreply.github.com>
Co-authored-by: Ahson Khan <ahkha@microsoft.com>

* Sync eng/common directory with azure-sdk-tools for PR 4315 (#3999)

* update target version to one that includes integration discovered bugfixes

Co-authored-by: scbedd <45376673+scbedd@users.noreply.github.com>

* Increment package version after release of azure-core (#4000)

* Fix 50x errors while loading page links (#4001)

We have hit a few 50x errors while pulling a page to get
links and that has caused the rest of the link checking to
terminate early. To fix that we switching to LogError which will
output an error in devops instead of Write-Error which terminates
immediately. We also add some retry count to the page retrieval
and cache file retrieval to help with these transitent 50x issues.

Co-authored-by: Wes Haggard <Wes.Haggard@microsoft.com>

* enable datalake softdelete tests (#3974)

* Small updates for core tests to work with the main automation. (#4004)

* core tests

* clang

* datalakestg82/change IsServerEncrypted not nullable (#4005)

* Add default .assets directory to .gitignore (#4008)

* Storage October release (#3975)

* Increment version for storage releases (#4013)

* Increment package version after release of azure-storage-blobs

* Increment package version after release of azure-storage-files-datalake

* Increment package version after release of azure-storage-files-shares

* Key Vault October releases (#4010)

* prepScript

* Updates for changelogs for 7.3

* target version with fixes (#4003)

Co-authored-by: scbedd <45376673+scbedd@users.noreply.github.com>

* Increment version for keyvault releases (#4014)

* Increment package version after release of azure-security-keyvault-keys

* Increment package version after release of azure-security-keyvault-certificates

* Increment package version after release of azure-security-keyvault-secrets

* Attestation October (#4017)

* Updated attestation change log to add periods for consistency (#4016)

* Updated attestation change log to add periods for consistency

* Update wording for a breaking change.

* Add back-ticks.

* Increment package version after release of azure-security-attestation (#4018)

* Bump the code owner retriver version. (#4020)

Co-authored-by: sima-zhu <sizhu@microsoft.com>

* Improved discoverability of tests; handle exceptions thrown during test execution (#4021)

* Improved discoverability of tests on WIndows; handle exceptions thrown during test execution better

* Vcpkg macro version for customers (#3909)

* macro version for customers

* remove other macros

* remove variable

* Core test (#4006)

* core tests

* clang

* vcpkg test

* dswsw

* first take on the vcpkg

* vcpkg

* get vcpkg version

* fix cmake

* separators

* vcpkg

* vcpkg

* test1

* disable verify agent od

* put back verify

* put back yml

* Update VCPKG Baseline due to zlib (#4027)

* override zlib version

* shwitch baseline

* macro update

* override zlib

* Fixed CURL build breaks discovered by newer openssl baselines (#4034)

* Vcpkg baseline to latest  (#4036)

* vcpkg baseline

* f4b262b259145adb2ab0116a390b08642489d32b

* 79fa9d85cb4510b05c2657bd7ec8a6a2cb266dc5

* 6ca56aeb457f033d344a7106cb3f9f1abf8f4e98

* override

* 1.4.1`

* Removed version override for opentelemetry (#4037)

* Removed version override for opentelemetry

* Disable deprecation warnings for open telemety tests to guard against future deprecations

* Added explanation for 4996 error; removed InMemoryExporter from documentation

* Sync eng/common directory with azure-sdk-tools for PR 3790 (#4041)

* Added yaml support for job matrix creation

* autogen scenario matrix for stress test

* Temporary Working State

* update to default sparse

* pr comments and some error handling

* custom matrixfilename and ordering of generatedValues.yaml

* common module import

* JobMatrix write host

Co-authored-by: Albert Cheng <albertcheng@microsoft.com>

* Storageblob (#4043)

* first take

* grrrrr

* qwqwq

* ewqw

* eewew

* put back

* pipeline

* Set read-only VCPKG_BINARY_SOURCES_SECRET

* Pass InstallLanguageSteps through the perf template

* blop pipeline

* path

* ';l'l;

* add support for sync param

* --sync flag support

* typo

* sync

* sync to y

* for PR

* clang

Co-authored-by: Daniel Jurek <djurek@microsoft.com>

* Upgrade cspell packages to version `^6.12.0` (#4044)

to address dependabot issue https://github.com/Azure/azure-sdk-for-js/security/dependabot/13

Co-authored-by: Jeremy Meng <yumeng@microsoft.com>

* Sync eng/common directory with azure-sdk-tools for PR 4480 (#4046)

* Add extra parameters for .net readme path

* Use another way for default value

* Remove custom source

Co-authored-by: sima-zhu <sizhu@microsoft.com>

* Converted WinHTTP to Async. (#4015)

* Async WinHTTP

* Added cancellation test; added support for request cancellation.

Co-authored-by: Anton Kolesnyk <41349689+antkmsft@users.noreply.github.com>
Co-authored-by: Ahson Khan <ahkha@microsoft.com>
Co-authored-by: Rick Winter <rick.winter@microsoft.com>

* Updated OpenTelemetry tests to use their own `SpanExporter` rather than depend on the `InMemorySpanExporter`. (#4042)

* Removed version override for opentelemetry

* Disable deprecation warnings for open telemety tests to guard against future deprecations

* Added explanation for 4996 error; removed InMemoryExporter from documentation

* Checkpoint adding manual telemetry exporter

* Switch from using OpenTelemetry's InMemoryExporter (which is an internal-to-opentelemetry test hook) to our own SpanExporter

* removed unused variables because gcc doesn't like them

* Fixed doxygen comments

* Removed a bunch of unnecessary headers

* Update sdk/core/azure-core-tracing-opentelemetry/test/ut/test_exporter.hpp

Co-authored-by: Rick Winter <rick.winter@microsoft.com>

Co-authored-by: Rick Winter <rick.winter@microsoft.com>

* [Perf] Include GA versions of core package (#4053)

* Fix to for a SAL annotation (#4054)

* In-memory Identity token cache (#4024)

* identicalize the comments type (#4063)

* Improve scenario matrix edge case handling (#4065)

Co-authored-by: Ben Broderick Phillips <bebroder@microsoft.com>

* docV1 (#4051)

* docV1

* Update doc/PerformanceTesting.md

Co-authored-by: Larry Osterman <LarryOsterman@users.noreply.github.com>

* Update doc/PerformanceTesting.md

Co-authored-by: Larry Osterman <LarryOsterman@users.noreply.github.com>

* Update doc/PerformanceTesting.md

Co-authored-by: Larry Osterman <LarryOsterman@users.noreply.github.com>

* Update doc/PerformanceTesting.md

Co-authored-by: Larry Osterman <LarryOsterman@users.noreply.github.com>

* comment

* some more updates

* Update doc/PerformanceTesting.md

Co-authored-by: Larry Osterman <LarryOsterman@users.noreply.github.com>

* Update doc/PerformanceTesting.md

Co-authored-by: Larry Osterman <LarryOsterman@users.noreply.github.com>

* Update doc/PerformanceTesting.md

Co-authored-by: Larry Osterman <LarryOsterman@users.noreply.github.com>

* PR

* Update doc/PerformanceTesting.md

Co-authored-by: Larry Osterman <LarryOsterman@users.noreply.github.com>

Co-authored-by: Larry Osterman <LarryOsterman@users.noreply.github.com>

* bump version to newest (#4066)

Co-authored-by: scbedd <45376673+scbedd@users.noreply.github.com>

* Async WInHTTP changes to WebSockets; fixed a couple of websocket bugs reported by cognitive.

* cspell; clang-format

* Sync eng/common directory with azure-sdk-tools for PR 4543 (#4071)

* stress test addons version check

* cleanup

Co-authored-by: Albert Cheng <albertcheng@microsoft.com>

* Disable proxy test on mac

* Fixed crash caused by premature destruction of WinHttpRequest object.

* Disable proxy tests if proxy tests are disabled

* Fixed race condition shutting down connections due to TLS violations

* cspell

* moved cspell out of doxygen comments

* moved cspell out of doxygen comments

* Added the ability to select OpenSSL 1.1.1n if desired. (#4045)

* Added ability to switch to OpenSSL 1.1.1n

* Fixed OpenSSL compilation challenges - the CRL stuff works now

* Added instructions on using OpenSSL 1.1.1 to README

* Added vcpkg args to handle openssl variants

* Improved names of SetEvent and ResetEvent

* cspell

* clang-format

* Traces to figure out test failure

* More traces

* Another try closing the TLS cert failure window

* More atempts at improving CI

* clang-format

Co-authored-by: George Arama <50641385+gearama@users.noreply.github.com>
Co-authored-by: Azure SDK Bot <53356347+azure-sdk@users.noreply.github.com>
Co-authored-by: sima-zhu <sizhu@microsoft.com>
Co-authored-by: Ahson Khan <ahson_ahmedk@yahoo.com>
Co-authored-by: Mike Harder <mharder@microsoft.com>
Co-authored-by: scbedd <45376673+scbedd@users.noreply.github.com>
Co-authored-by: Daniel Jurek <djurek@microsoft.com>
Co-authored-by: Heath Stewart <heaths@microsoft.com>
Co-authored-by: Ben Broderick Phillips <bebroder@microsoft.com>
Co-authored-by: praveenkuttappan <prmarott@microsoft.com>
Co-authored-by: Ben Broderick Phillips <ben@benbp.net>
Co-authored-by: Sima Zhu <48036328+sima-zhu@users.noreply.github.com>
Co-authored-by: Wes Haggard <weshaggard@users.noreply.github.com>
Co-authored-by: Rick Winter <rick.winter@microsoft.com>
Co-authored-by: John Heffner <john@topofcenter.net>
Co-authored-by: Anton Kolesnyk <41349689+antkmsft@users.noreply.github.com>
Co-authored-by: Anton Kolesnyk <antkmsft@users.noreply.github.com>
Co-authored-by: JinmingHu <jinmhu@microsoft.com>
Co-authored-by: Jonathan Cárdenas <JonathanCrd@users.noreply.github.com>
Co-authored-by: keshen-msft <53491277+keshen-msft@users.noreply.github.com>
Co-authored-by: microzchang <110015819+microzchang@users.noreply.github.com>
Co-authored-by: Jamie Magee <jamie.magee@gmail.com>
Co-authored-by: Jamie Magee <jamie.magee@microsoft.com>
Co-authored-by: Peng Li <86324823+penglimsft@users.noreply.github.com>
Co-authored-by: Peng Li <pengfeli@microsoft.com>
Co-authored-by: Wes Haggard <Wes.Haggard@microsoft.com>
Co-authored-by: Ahson Khan <ahkha@microsoft.com>
Co-authored-by: James Suplizio <jasupliz@microsoft.com>
Co-authored-by: Victor Vazquez <victor.vazquez@microsoft.com>
Co-authored-by: Albert Cheng <albertcheng@microsoft.com>
Co-authored-by: Jeremy Meng <yumeng@microsoft.com>
2022-11-01 10:13:28 -07:00

492 lines
15 KiB
PowerShell

<#
.SYNOPSIS
Check broken links.
.DESCRIPTION
The Verify-Links.ps1 script will check whether the files contain any broken links.
.PARAMETER urls
Specify url list to verify links. Can either be a http address or a local file request. Local file paths support md and html files.
.PARAMETER ignoreLinksFile
Specifies the file that contains a set of links to ignore when verifying.
.PARAMETER devOpsLogging
Switch that will enable devops specific logging for warnings
.PARAMETER recursive
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.
.PARAMETER errorStatusCodes
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)/)main(/.*)$
.PARAMETER branchReplacementName
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.
.PARAMETER userAgent
UserAgent to be configured for web requests. Defaults to current Chrome version.
.PARAMETER inputCacheFile
Path to a file that contains a list of links that are known valid so we can skip checking them.
.PARAMETER outputCacheFile
Path to a file that the script will output all the validated links after running all checks.
.PARAMETER requestTimeoutSec
The number of seconds before we timeout when sending an individual web request. Default is 15 seconds.
.EXAMPLE
PS> .\Verify-Links.ps1 C:\README.md
.EXAMPLE
PS> .\Verify-Links.ps1 https://azure.github.io/azure-sdk/index.html
.EXAMPLE
PS> .\Verify-Links C:\README.md -checkLinkGuidance $true
#>
[CmdletBinding()]
param (
[string[]] $urls,
[string] $ignoreLinksFile = "$PSScriptRoot/ignore-links.txt",
[switch] $devOpsLogging = $false,
[switch] $recursive = $true,
[string] $baseUrl = "",
[string] $rootUrl = "",
[array] $errorStatusCodes = @(400, 401, 404, 11001, 11004),
[string] $branchReplaceRegex = "",
[string] $branchReplacementName = "",
[bool] $checkLinkGuidance = $false,
[string] $userAgent,
[string] $inputCacheFile,
[string] $outputCacheFile,
[string] $requestTimeoutSec = 15
)
$ProgressPreference = "SilentlyContinue"; # Disable invoke-webrequest progress dialog
# Regex of the locale keywords.
$locale = "/en-us/"
$emptyLinkMessage = "There is at least one empty link in the page. Please replace with absolute link. Check here for more information: https://aka.ms/azsdk/guideline/links"
if (!$userAgent) {
$userAgent = "Chrome/87.0.4280.88"
}
function NormalizeUrl([string]$url){
if (Test-Path $url) {
$url = "file://" + (Resolve-Path $url).ToString();
}
Write-Verbose "The url to check against: $url."
$uri = [System.Uri]$url;
if ($script:baseUrl -eq "") {
# for base url default to containing directory
$script:baseUrl = (new-object System.Uri($uri, ".")).ToString();
}
if ($script:rootUrl -eq "") {
if ($uri.IsFile) {
# for files default to the containing directory
$script:rootUrl = $script:baseUrl;
}
else {
# for http links default to the root path
$script:rootUrl = new-object System.Uri($uri, "/");
}
}
return $uri
}
function LogWarning
{
if ($devOpsLogging)
{
Write-Host "##vso[task.LogIssue type=warning;]$args"
}
else
{
Write-Warning "$args"
}
}
function LogError
{
if ($devOpsLogging)
{
Write-Host "##vso[task.logissue type=error]$args"
}
else
{
Write-Error "$args"
}
}
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
}
$linkUri = [System.Uri]$link;
# Our link guidelines do not allow relative links so only resolve them when we are not
# validating links against our link guidelines (i.e. !$checkLinkGuideance)
if ($checkLinkGuidance -and !$linkUri.IsAbsoluteUri) {
return $linkUri
}
if (!$linkUri.IsAbsoluteUri) {
# For rooted paths resolve from the baseUrl
if ($link.StartsWith("/")) {
Write-Verbose "rooturl = $rootUrl"
$linkUri = new-object System.Uri([System.Uri]$rootUrl, ".$link");
}
else {
$linkUri = new-object System.Uri($referralUri, $link);
}
}
$linkUri = [System.Uri]$linkUri.GetComponents([System.UriComponents]::HttpRequestUrl, [System.UriFormat]::SafeUnescaped)
Write-Verbose "ResolvedUri $link to $linkUri"
# 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
}
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
}
return $linkUri;
}
function ParseLinks([string]$baseUri, [string]$htmlContent)
{
$hrefRegex = "<a[^>]+href\s*=\s*[""']?(?<href>[^""']*)[""']?"
$regexOptions = [System.Text.RegularExpressions.RegexOptions]"Singleline, IgnoreCase";
$hrefs = [RegEx]::Matches($htmlContent, $hrefRegex, $regexOptions);
#$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 }
#$links | Foreach-Object { Write-Host $_ }
return $links
}
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
}
$originalLinkUri = $linkUri
$linkUri = ReplaceGithubLink $linkUri
$link = $linkUri.ToString()
if ($checkedLinks.ContainsKey($link)) {
if (!$checkedLinks[$link]) {
LogWarning "broken link $link"
}
return $checkedLinks[$link]
}
$linkValid = $true
Write-Verbose "Checking link $linkUri..."
if ($linkUri.IsFile) {
if (!(Test-Path $linkUri.LocalPath)) {
LogWarning "Link to file does not exist $($linkUri.LocalPath)"
$linkValid = $false
}
}
elseif ($linkUri.IsAbsoluteUri) {
try {
$headRequestSucceeded = $true
try {
# Attempt HEAD request first
$response = Invoke-WebRequest -Uri $linkUri -Method HEAD -UserAgent $userAgent -TimeoutSec $requestTimeoutSec
}
catch {
$headRequestSucceeded = $false
}
if (!$headRequestSucceeded) {
# Attempt a GET request if the HEAD request failed.
$response = Invoke-WebRequest -Uri $linkUri -Method GET -UserAgent $userAgent -TimeoutSec $requestTimeoutSec
}
$statusCode = $response.StatusCode
if ($statusCode -ne 200) {
Write-Host "[$statusCode] while requesting $linkUri"
}
}
catch {
$statusCode = $_.Exception.Response.StatusCode.value__
if(!$statusCode) {
# Try to pull the error code from any inner SocketException we might hit
$statusCode = $_.Exception.InnerException.ErrorCode
}
if ($statusCode -in $errorStatusCodes) {
if ($originalLinkUri -ne $linkUri) {
LogError "[$statusCode] broken link $originalLinkUri (resolved to $linkUri)"
}
else {
LogError "[$statusCode] broken link $linkUri"
}
$linkValid = $false
}
else {
if ($null -ne $statusCode) {
# 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
}
# 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"
$linkValid = $false
}
# Check if the url is anchor link has any uppercase.
if ($link -cmatch '#[^?]*[A-Z]') {
LogWarning "Please lower case your anchor tags (i.e. anything after '#' in your link '$linkUri'. Check here for more information: https://aka.ms/azsdk/guideline/links"
$linkValid = $false
}
# Check if link uri includes locale info.
if ($linkUri -match $locale) {
LogWarning "DO NOT include locale $locale information in links: $linkUri. Check here for more information: https://aka.ms/azsdk/guideline/links"
$linkValid = $false
}
}
$checkedLinks[$link] = $linkValid
return $linkValid
}
function ReplaceGithubLink([string]$originLink) {
if (!$branchReplacementName -or !$branchReplaceRegex) {
return $originLink
}
$ReplacementPattern = "`${1}$branchReplacementName`$2"
return $originLink -replace $branchReplaceRegex, $ReplacementPattern
}
function GetLinks([System.Uri]$pageUri)
{
if ($pageUri.Scheme.StartsWith("http")) {
try {
$response = Invoke-WebRequest -Uri $pageUri -UserAgent $userAgent -TimeoutSec $requestTimeoutSec -MaximumRetryCount 3
$content = $response.Content
if ($pageUri.ToString().EndsWith(".md")) {
$content = (ConvertFrom-MarkDown -InputObject $content).html
}
}
catch {
$statusCode = $_.Exception.Response.StatusCode.value__
LogError "Invalid page [$statusCode] $pageUri"
}
}
elseif ($pageUri.IsFile -and (Test-Path $pageUri.LocalPath)) {
$file = $pageUri.LocalPath
if ($file.EndsWith(".md")) {
$content = (ConvertFrom-MarkDown $file).html
}
elseif ($file.EndsWith(".html")) {
$content = Get-Content $file
}
else {
if (Test-Path ($file + "index.html")) {
$content = Get-Content ($file + "index.html")
}
else {
# Fallback to just reading the content directly
$content = Get-Content $file
}
}
}
else {
LogError "Don't know how to process uri $pageUri"
}
$links = ParseLinks $pageUri $content
return $links;
}
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) {
$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)
{
$cacheContent = ""
if ($inputCacheFile.StartsWith("http")) {
try {
$response = Invoke-WebRequest -Uri $inputCacheFile -TimeoutSec $requestTimeoutSec -MaximumRetryCount 3
$cacheContent = $response.Content
}
catch {
$statusCode = $_.Exception.Response.StatusCode.value__
LogError "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
}
}
$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
$pageUrisToCheck.Enqueue($uri);
}
if ($devOpsLogging) {
Write-Host "##[group]Link checking details"
}
while ($pageUrisToCheck.Count -ne 0)
{
$pageUri = $pageUrisToCheck.Dequeue();
if ($checkedPages.ContainsKey($pageUri)) { continue }
$checkedPages[$pageUri] = $true;
$linkUris = GetLinks $pageUri
Write-Host "Checking $($linkUris.Count) links found on page $pageUri";
$badLinksPerPage = @();
foreach ($linkUri in $linkUris) {
$isLinkValid = CheckLink $linkUri
if (!$isLinkValid -and !$badLinksPerPage.Contains($linkUri)) {
if (!$linkUri.ToString().Trim()) {
$linkUri = $emptyLinkMessage
}
$badLinksPerPage += $linkUri
}
if ($recursive -and $isLinkValid) {
if ($linkUri.ToString().StartsWith($baseUrl) -and !$checkedPages.ContainsKey($linkUri)) {
$pageUrisToCheck.Enqueue($linkUri);
}
}
}
if ($badLinksPerPage.Count -gt 0) {
$badLinks[$pageUri] = $badLinksPerPage
}
}
if ($devOpsLogging) {
Write-Host "##[endgroup]"
}
if ($badLinks.Count -gt 0) {
Write-Host "Summary of broken links:"
}
foreach ($pageLink in $badLinks.Keys) {
Write-Host "'$pageLink' has $($badLinks[$pageLink].Count) broken link(s):"
foreach ($brokenLink in $badLinks[$pageLink]) {
Write-Host " $brokenLink"
}
}
$linksChecked = $checkedLinks.Count - $cachedLinksCount
if ($badLinks.Count -gt 0) {
Write-Host "Checked $linksChecked links with $($badLinks.Count) broken link(s) found."
}
else {
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