diff --git a/eng/common/pipelines/templates/steps/verify-agent-os.yml b/eng/common/pipelines/templates/steps/verify-agent-os.yml index 1786612ba..b221583bc 100644 --- a/eng/common/pipelines/templates/steps/verify-agent-os.yml +++ b/eng/common/pipelines/templates/steps/verify-agent-os.yml @@ -1,4 +1,3 @@ -# Template for all Python Scripts in this repository parameters: OSVmImage: $(OSVmImage) diff --git a/eng/common/pipelines/templates/steps/verify-changelog.yml b/eng/common/pipelines/templates/steps/verify-changelog.yml new file mode 100644 index 000000000..f90238471 --- /dev/null +++ b/eng/common/pipelines/templates/steps/verify-changelog.yml @@ -0,0 +1,25 @@ +parameters: +- name: PackageName + type: string + default: 'not-specified' +- name: ServiceName + type: string + default: 'not-specified' +- name: ForRelease + type: boolean + default: false + +steps: + - task: Powershell@2 + inputs: + filePath: /eng/common/scripts/Verify-ChangeLog.ps1 + arguments: > + -PackageName ${{ parameters.PackageName }} + -ServiceName ${{ parameters.ServiceName }} + -RepoRoot $(Build.SourcesDirectory) + -RepoName $(Build.Repository.Name) + -ForRelease ${{ parameters.ForRelease }} + pwsh: true + workingDirectory: $(Pipeline.Workspace) + displayName: Verify ChangeLog / Release Notes + continueOnError: false \ No newline at end of file diff --git a/eng/common/pipelines/templates/steps/verify-links.yml b/eng/common/pipelines/templates/steps/verify-links.yml new file mode 100644 index 000000000..1a99350f0 --- /dev/null +++ b/eng/common/pipelines/templates/steps/verify-links.yml @@ -0,0 +1,12 @@ +parameters: + Directory: 'not-specified' + +steps: + - task: PowerShell@2 + displayName: Link verification check + inputs: + pwsh: true + workingDirectory: $(Build.SourcesDirectory)/${{ parameters.Directory }} + filePath: eng/common/scripts/Verify-Links.ps1 + arguments: > + -urls $(dir -r -i *.md) -rootUrl "file://$(Build.SourcesDirectory)/${{ parameters.Directory }}" diff --git a/eng/common/scripts/Verify-ChangeLog.ps1 b/eng/common/scripts/Verify-ChangeLog.ps1 new file mode 100644 index 000000000..1f9991bfd --- /dev/null +++ b/eng/common/scripts/Verify-ChangeLog.ps1 @@ -0,0 +1,22 @@ +# Wrapper Script for ChangeLog Verification +param ( + [Parameter(Mandatory=$true)] + [string]$PackageName, + [Parameter(Mandatory=$true)] + [string]$ServiceName, + [string]$RepoRoot, + [ValidateSet("net","java","js","python")] + [string]$Language, + [string]$RepoName, + [boolean]$ForRelease=$False +) + +Import-Module "${PSScriptRoot}/modules/common-manifest.psd1" + +if ([System.String]::IsNullOrEmpty($Language)) +{ + $Language = $RepoName.Substring($RepoName.LastIndexOf('-') + 1) +} + +$PackageProp = Get-PkgProperties -PackageName $PackageName -ServiceName $ServiceName -Language $Language -RepoRoot $RepoRoot +Confirm-ChangeLog -ChangeLogLocation $PackageProp.pkgChangeLogPath -VersionString $PackageProp.pkgReadMePath -ForRelease $ForRelease \ No newline at end of file diff --git a/eng/common/scripts/Verify-Links.ps1 b/eng/common/scripts/Verify-Links.ps1 new file mode 100644 index 000000000..c78ce9020 --- /dev/null +++ b/eng/common/scripts/Verify-Links.ps1 @@ -0,0 +1,244 @@ +param ( + # url list to verify links. Can either be a http address or a local file request. Local file paths support md and html files. + [string[]] $urls, + # file that contains a set of links to ignore when verifying + [string] $ignoreLinksFile = "$PSScriptRoot/ignore-links.txt", + # switch that will enable devops specific logging for warnings + [switch] $devOpsLogging = $false, + # check the links recurisvely based on recursivePattern + [switch] $recursive = $true, + # recusiving check links for all links verified that begin with this baseUrl, defaults to the folder the url is contained in + [string] $baseUrl = "", + # path to the root of the site for resolving rooted relative links, defaults to host root for http and file directory for local files + [string] $rootUrl = "", + # list of http status codes count as broken links. Defaults to 404. + [array] $errorStatusCodes = @(404), + # flag to allow resolving relative paths or not + [bool] $resolveRelativeLinks = $true +) + +$ProgressPreference = "SilentlyContinue"; # Disable invoke-webrequest progress dialog + +function NormalizeUrl([string]$url){ + if (Test-Path $url) { + $url = "file://" + (Resolve-Path $url).ToString(); + } + + $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 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 + } + + $linkUri = [System.Uri]$link; + if($resolveRelativeLinks){ + if (!$linkUri.IsAbsoluteUri) { + # For rooted paths resolve from the baseUrl + if ($link.StartsWith("/")) { + echo "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 $null + } + + if ($null -ne $ignoreLinks -and $ignoreLinks.Contains($link)) { + Write-Verbose "Ignoring invalid link $linkUri because it is in the ignore file." + return $null + } + + return $linkUri; +} + +function ParseLinks([string]$baseUri, [string]$htmlContent) +{ + $hrefRegex = "]+href\s*=\s*[""']?(?[^""']*)[""']?" + $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 } | Sort-Object -Unique + + #$links | Foreach-Object { Write-Host $_ } + + return $links +} + +function CheckLink ([System.Uri]$linkUri) +{ + if ($checkedLinks.ContainsKey($linkUri)) { return } + + Write-Verbose "Checking link $linkUri..." + if ($linkUri.IsFile) { + if (!(Test-Path $linkUri.LocalPath)) { + LogWarning "Link to file does not exist $($linkUri.LocalPath)" + $script:badLinks += $linkUri + } + } + else { + try { + $response = Invoke-WebRequest -Uri $linkUri + $statusCode = $response.StatusCode + if ($statusCode -ne 200) { + Write-Host "[$statusCode] while requesting $linkUri" + } + } + catch { + $statusCode = $_.Exception.Response.StatusCode.value__ + + if ($statusCode -in $errorStatusCodes) { + LogWarning "[$statusCode] broken link $linkUri" + $script:badLinks += $linkUri + } + else { + if ($null -ne $statusCode) { + Write-Host "[$statusCode] while requesting $linkUri" + } + else { + Write-Host "Exception while requesting $linkUri" + Write-Host $_.Exception.ToString() + } + } + } + } + $checkedLinks[$linkUri] = $true; +} + +function GetLinks([System.Uri]$pageUri) +{ + if ($pageUri.Scheme.StartsWith("http")) { + try { + $response = Invoke-WebRequest -Uri $pageUri + $content = $response.Content + } + catch { + $statusCode = $_.Exception.Response.StatusCode.value__ + Write-Error "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 { + Write-Error "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) "; + 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)." +} + +$badLinks = @(); +$ignoreLinks = @(); +if (Test-Path $ignoreLinksFile) +{ + $ignoreLinks = [Array](Get-Content $ignoreLinksFile | ForEach-Object { ($_ -replace "#.*", "").Trim() } | Where-Object { $_ -ne "" }) +} + +$checkedPages = @{}; +$checkedLinks = @{}; +$pageUrisToCheck = new-object System.Collections.Queue + +foreach ($url in $urls) { + $uri = NormalizeUrl $url + $pageUrisToCheck.Enqueue($uri); +} + +while ($pageUrisToCheck.Count -ne 0) +{ + $pageUri = $pageUrisToCheck.Dequeue(); + if ($checkedPages.ContainsKey($pageUri)) { continue } + $checkedPages[$pageUri] = $true; + + $linkUris = GetLinks $pageUri + Write-Host "Found $($linkUris.Count) links on page $pageUri"; + + foreach ($linkUri in $linkUris) { + CheckLink $linkUri + if ($recursive) { + if ($linkUri.ToString().StartsWith($baseUrl) -and !$checkedPages.ContainsKey($linkUri)) { + $pageUrisToCheck.Enqueue($linkUri); + } + } + } +} + +Write-Host "Found $($checkedLinks.Count) links with $($badLinks.Count) broken" +$badLinks | ForEach-Object { Write-Host " $_" } + +exit $badLinks.Count diff --git a/eng/common/scripts/artifact-metadata-parsing.ps1 b/eng/common/scripts/artifact-metadata-parsing.ps1 index 2d2362f0d..e48a526fe 100644 --- a/eng/common/scripts/artifact-metadata-parsing.ps1 +++ b/eng/common/scripts/artifact-metadata-parsing.ps1 @@ -1,3 +1,4 @@ +Import-Module "${PSScriptRoot}/modules/ChangeLog-Operations.psm1" . (Join-Path $PSScriptRoot SemVer.ps1) $SDIST_PACKAGE_REGEX = "^(?.*)\-(?$([AzureEngSemanticVersion]::SEMVER_REGEX))" @@ -8,8 +9,8 @@ function CreateReleases($pkgList, $releaseApiUrl, $releaseSha) { Write-Host "Creating release $($pkgInfo.Tag)" $releaseNotes = "" - if ($pkgInfo.ReleaseNotes[$pkgInfo.PackageVersion].ReleaseContent -ne $null) { - $releaseNotes = $pkgInfo.ReleaseNotes[$pkgInfo.PackageVersion].ReleaseContent + if ($pkgInfo.ReleaseNotes -ne $null) { + $releaseNotes = $pkgInfo.ReleaseNotes } $isPrerelease = $False @@ -96,7 +97,7 @@ function ParseMavenPackage($pkg, $workingDirectory) { $changeLogLoc = @(Get-ChildItem -Path $pkg.DirectoryName -Recurse -Include "$($pkg.Basename)-changelog.md")[0] if ($changeLogLoc) { - $releaseNotes = &"${PSScriptRoot}/../Extract-ReleaseNotes.ps1" -ChangeLogLocation $changeLogLoc + $releaseNotes = Get-ChangeLogEntryAsString -ChangeLogLocation $changeLogLoc -VersionString $pkgVersion } $readmeContentLoc = @(Get-ChildItem -Path $pkg.DirectoryName -Recurse -Include "$($pkg.Basename)-readme.md")[0] @@ -169,13 +170,15 @@ function ParseNPMPackage($pkg, $workingDirectory) { tar -xzf $pkg $packageJSON = ResolvePkgJson -workFolder $workFolder | Get-Content | ConvertFrom-Json + $pkgId = $packageJSON.name + $pkgVersion = $packageJSON.version $changeLogLoc = @(Get-ChildItem -Path $workFolder -Recurse -Include "CHANGELOG.md")[0] if ($changeLogLoc) { - $releaseNotes = &"${PSScriptRoot}/../Extract-ReleaseNotes.ps1" -ChangeLogLocation $changeLogLoc + $releaseNotes = Get-ChangeLogEntryAsString -ChangeLogLocation $changeLogLoc -VersionString $pkgVersion } - $readmeContentLoc = @(Get-ChildItem -Path $workFolder -Recurse -Include "README.md")[0] + $readmeContentLoc = @(Get-ChildItem -Path $workFolder -Recurse -Include "README.md") | Select-Object -Last 1 if ($readmeContentLoc) { $readmeContent = Get-Content -Raw $readmeContentLoc } @@ -183,9 +186,6 @@ function ParseNPMPackage($pkg, $workingDirectory) { cd $origFolder Remove-Item $workFolder -Force -Recurse -ErrorAction SilentlyContinue - $pkgId = $packageJSON.name - $pkgVersion = $packageJSON.version - $resultObj = New-Object PSObject -Property @{ PackageId = $pkgId PackageVersion = $pkgVersion @@ -229,10 +229,12 @@ function ParseNugetPackage($pkg, $workingDirectory) { Copy-Item -Path $pkg -Destination $zipFileLocation Expand-Archive -Path $zipFileLocation -DestinationPath $workFolder [xml] $packageXML = Get-ChildItem -Path "$workFolder/*.nuspec" | Get-Content + $pkgId = $packageXML.package.metadata.id + $pkgVersion = $packageXML.package.metadata.version $changeLogLoc = @(Get-ChildItem -Path $workFolder -Recurse -Include "CHANGELOG.md")[0] if ($changeLogLoc) { - $releaseNotes = &"${PSScriptRoot}/../Extract-ReleaseNotes.ps1" -ChangeLogLocation $changeLogLoc + $releaseNotes = Get-ChangeLogEntryAsString -ChangeLogLocation $changeLogLoc -VersionString $pkgVersion } $readmeContentLoc = @(Get-ChildItem -Path $workFolder -Recurse -Include "README.md")[0] @@ -241,8 +243,6 @@ function ParseNugetPackage($pkg, $workingDirectory) { } Remove-Item $workFolder -Force -Recurse -ErrorAction SilentlyContinue - $pkgId = $packageXML.package.metadata.id - $pkgVersion = $packageXML.package.metadata.version return New-Object PSObject -Property @{ PackageId = $pkgId @@ -297,13 +297,15 @@ function ParsePyPIPackage($pkg, $workingDirectory) { $changeLogLoc = @(Get-ChildItem -Path $workFolder -Recurse -Include "CHANGELOG.md")[0] if ($changeLogLoc) { - $releaseNotes = &"${PSScriptRoot}/../Extract-ReleaseNotes.ps1" -ChangeLogLocation $changeLogLoc + $releaseNotes = Get-ChangeLogEntryAsString -ChangeLogLocation $changeLogLoc -VersionString $pkgVersion } - $readmeContentLoc = @(Get-ChildItem -Path $workFolder -Recurse -Include "README.md")[0] + $readmeContentLoc = @(Get-ChildItem -Path $workFolder -Recurse -Include "README.md") | Select-Object -Last 1 + if ($readmeContentLoc) { $readmeContent = Get-Content -Raw $readmeContentLoc } + Remove-Item $workFolder -Force -Recurse -ErrorAction SilentlyContinue return New-Object PSObject -Property @{ @@ -321,10 +323,12 @@ function ParseCArtifact($pkg, $workingDirectory) { $releaseNotes = "" $readmeContent = "" + $pkgVersion = $packageInfo.version + $changeLogLoc = @(Get-ChildItem -Path $packageArtifactLocation -Recurse -Include "CHANGELOG.md")[0] if ($changeLogLoc) { - $releaseNotes = &"${PSScriptRoot}/../Extract-ReleaseNotes.ps1" -ChangeLogLocation $changeLogLoc + $releaseNotes = Get-ChangeLogEntryAsString -ChangeLogLocation $changeLogLoc -VersionString $pkgVersion } $readmeContentLoc = @(Get-ChildItem -Path $packageArtifactLocation -Recurse -Include "README.md")[0] @@ -333,8 +337,8 @@ function ParseCArtifact($pkg, $workingDirectory) { } return New-Object PSObject -Property @{ - PackageId = '' - PackageVersion = $packageInfo.version + PackageId = 'azure-sdk-for-c' + PackageVersion = $pkgVersion # Artifact info is always considered deployable for C becasue it is not # deployed anywhere. Dealing with duplicate tags happens downstream in # CheckArtifactShaAgainstTagsList diff --git a/eng/common/scripts/create-tags-and-git-release.ps1 b/eng/common/scripts/create-tags-and-git-release.ps1 index 1667cddd7..cec45536b 100644 --- a/eng/common/scripts/create-tags-and-git-release.ps1 +++ b/eng/common/scripts/create-tags-and-git-release.ps1 @@ -6,6 +6,7 @@ param ( # used by VerifyPackages $artifactLocation, # the root of the artifact folder. DevOps $(System.ArtifactsDirectory) $workingDirectory, # directory that package artifacts will be extracted into for examination (if necessary) + [ValidateSet("Nuget","NPM","PyPI","Maven")] $packageRepository, # used to indicate destination against which we will check the existing version. # valid options: PyPI, Nuget, NPM, Maven, C # used by CreateTags diff --git a/eng/common/scripts/modules/ChangeLog-Operations.psm1 b/eng/common/scripts/modules/ChangeLog-Operations.psm1 new file mode 100644 index 000000000..527966841 --- /dev/null +++ b/eng/common/scripts/modules/ChangeLog-Operations.psm1 @@ -0,0 +1,116 @@ +# Common Changelog Operations + +$RELEASE_TITLE_REGEX = "(?^\#+.*(?\b\d+\.\d+\.\d+([^0-9\s][^\s:]+)?)(\s(?\(Unreleased\)|\(\d{4}-\d{2}-\d{2}\)))?)" + +# Returns a Collection of changeLogEntry object containing changelog info for all version present in the gived CHANGELOG +function Get-ChangeLogEntries { + param ( + [Parameter(Mandatory = $true)] + [String]$ChangeLogLocation + ) + + $changeLogEntries = @{} + if (!(Test-Path $ChangeLogLocation)) { + Write-Host "ChangeLog '{0}' was not found" -f $ChangeLogLocation + exit 1 + } + + try { + $contents = Get-Content $ChangeLogLocation + # walk the document, finding where the version specifiers are and creating lists + $changeLogEntry = $null + foreach ($line in $contents) { + if ($line -match $RELEASE_TITLE_REGEX) { + $changeLogEntry = [pscustomobject]@{ + ReleaseVersion = $matches["version"] + ReleaseStatus = $matches["releaseStatus"] + ReleaseTitle = $line + ReleaseContent = @() # Release content without the version title + } + $changeLogEntries[$changeLogEntry.ReleaseVersion] = $changeLogEntry + } + else { + if ($changeLogEntry) { + $changeLogEntry.ReleaseContent += $line + } + } + } + } + catch { + Write-Host "Error parsing $ChangeLogLocation." + Write-Host $_.Exception.Message + } + return $changeLogEntries +} + +# Returns single changeLogEntry object containing the ChangeLog for a particular version +function Get-ChangeLogEntry { + param ( + [Parameter(Mandatory = $true)] + [String]$ChangeLogLocation, + [Parameter(Mandatory = $true)] + [String]$VersionString + ) + + $changeLogEntries = Get-ChangeLogEntries -ChangeLogLocation $ChangeLogLocation + + if ($changeLogEntries.ContainsKey($VersionString)) { + return $changeLogEntries[$VersionString] + } + Write-Error "Release Notes for the Specified version ${VersionString} was not found" + exit 1 +} + +#Returns the changelog for a particular version as string +function Get-ChangeLogEntryAsString { + param ( + [Parameter(Mandatory = $true)] + [String]$ChangeLogLocation, + [Parameter(Mandatory = $true)] + [String]$VersionString + ) + + $changeLogEntries = Get-ChangeLogEntry -ChangeLogLocation $ChangeLogLocation -VersionString $VersionString + [string]$releaseTitle = $changeLogEntries.ReleaseTitle + [string]$releaseContent = $changeLogEntries.ReleaseContent -Join [Environment]::NewLine + return $releaseTitle, $releaseContent -Join [Environment]::NewLine +} + +function Confirm-ChangeLogEntry { + param ( + [Parameter(Mandatory = $true)] + [String]$ChangeLogLocation, + [Parameter(Mandatory = $true)] + [String]$VersionString, + [boolean]$ForRelease = $false + ) + + $changeLogEntries = Get-ChangeLogEntry -ChangeLogLocation $ChangeLogLocation -VersionString $VersionString + + if ([System.String]::IsNullOrEmpty($changeLogEntries.ReleaseStatus)) { + Write-Host ("##[error]Changelog '{0}' has wrong release note title" -f $ChangeLogLocation) + Write-Host "##[info]Ensure the release date is included i.e. (yyyy-MM-dd) or (Unreleased) if not yet released" + exit 1 + } + + if ($ForRelease -eq $True) { + $CurrentDate = Get-Date -Format "yyyy-MM-dd" + if ($changeLogEntries.ReleaseStatus -ne "($CurrentDate)") { + Write-Host ("##[warning]Incorrect Date: Please use the current date in the Changelog '{0}' before releasing the package" -f $ChangeLogLocation) + exit 1 + } + + if ([System.String]::IsNullOrWhiteSpace($changeLogEntries.ReleaseContent)) { + Write-Host ("##[error]Empty Release Notes for '{0}' in '{1}'" -f $VersionString, $ChangeLogLocation) + Write-Host "##[info]Please ensure there is a release notes entry before releasing the package." + exit 1 + } + } + + Write-Host ($changeLogEntries | Format-Table | Out-String) +} + +Export-ModuleMember -Function 'Get-ChangeLogEntries' +Export-ModuleMember -Function 'Get-ChangeLogEntry' +Export-ModuleMember -Function 'Get-ChangeLogEntryAsString' +Export-ModuleMember -Function 'Confirm-ChangeLogEntry' \ No newline at end of file diff --git a/eng/common/scripts/modules/common-manifest.psd1 b/eng/common/scripts/modules/common-manifest.psd1 index 419f046e6..43dee1c26 100644 --- a/eng/common/scripts/modules/common-manifest.psd1 +++ b/eng/common/scripts/modules/common-manifest.psd1 @@ -66,7 +66,7 @@ ScriptsToProcess = @("${PSScriptRoot}\..\SemVer.ps1") # FormatsToProcess = @() # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess -NestedModules = @("${PSScriptRoot}\Package-Properties.psm1") +NestedModules = @("${PSScriptRoot}\Package-Properties.psm1", "${PSScriptRoot}\ChangeLog-Operations.psm1") # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. # FunctionsToExport = @() diff --git a/eng/common/scripts/update-docs-metadata.ps1 b/eng/common/scripts/update-docs-metadata.ps1 index 9eba32ae3..a858078f5 100644 --- a/eng/common/scripts/update-docs-metadata.ps1 +++ b/eng/common/scripts/update-docs-metadata.ps1 @@ -22,19 +22,19 @@ param ( function GetMetaData($lang){ switch ($lang) { "java" { - $metadataUri = "https://raw.githubusercontent.com/Azure/azure-sdk/master/_data/allpackages/java-packages.csv" + $metadataUri = "https://raw.githubusercontent.com/Azure/azure-sdk/master/_data/releases/latest/java-packages.csv" break } ".net" { - $metadataUri = "https://raw.githubusercontent.com/Azure/azure-sdk/master/_data/allpackages/dotnet-packages.csv" + $metadataUri = "https://raw.githubusercontent.com/Azure/azure-sdk/master/_data/releases/latest/dotnet-packages.csv" break } "python" { - $metadataUri = "https://raw.githubusercontent.com/Azure/azure-sdk/master/_data/allpackages/python-packages.csv" + $metadataUri = "https://raw.githubusercontent.com/Azure/azure-sdk/master/_data/releases/latest/python-packages.csv" break } "javascript" { - $metadataUri = "https://raw.githubusercontent.com/Azure/azure-sdk/master/_data/allpackages/js-packages.csv" + $metadataUri = "https://raw.githubusercontent.com/Azure/azure-sdk/master/_data/releases/latest/js-packages.csv" break } default { @@ -61,7 +61,7 @@ function GetAdjustedReadmeContent($pkgInfo, $lang){ $service = $metadata | ? { $_.Package -eq $pkgId } if ($service) { - $service = "$($service.Service)" + $service = "$($service.ServiceName)".ToLower().Replace(" ", "") } } catch { @@ -70,15 +70,17 @@ function GetAdjustedReadmeContent($pkgInfo, $lang){ } $fileContent = $pkgInfo.ReadmeContent + $foundTitle = "" # only replace the version if the formatted header can be found $headerContentMatches = (Select-String -InputObject $pkgInfo.ReadmeContent -Pattern 'Azure .+? (client|plugin|shared) library for (JavaScript|Java|Python|\.NET|C)') if ($headerContentMatches) { - $headerContentMatch = $headerContentMatches.Matches[0] - $header = "---`ntitle: $headerContentMatch`nkeywords: Azure, $lang, SDK, API, $($pkgInfo.PackageId), $service`nauthor: maggiepint`nms.author: magpint`nms.date: $date`nms.topic: article`nms.prod: azure`nms.technology: azure`nms.devlang: $lang`nms.service: $service`n---`n" - $fileContent = $pkgInfo.ReadmeContent -replace $headerContentMatch, "$headerContentMatch - Version $($pkgInfo.PackageVersion) `n" + $foundTitle = $headerContentMatches.Matches[0] + $fileContent = $pkgInfo.ReadmeContent -replace $foundTitle, "$foundTitle - Version $($pkgInfo.PackageVersion) `n" } + $header = "---`ntitle: $foundTitle`nkeywords: Azure, $lang, SDK, API, $($pkgInfo.PackageId), $service`nauthor: maggiepint`nms.author: magpint`nms.date: $date`nms.topic: article`nms.prod: azure`nms.technology: azure`nms.devlang: $lang`nms.service: $service`n---`n" + if ($fileContent) { return "$header`n$fileContent" }