diff --git a/eng/Directory.Build.Data.targets b/eng/Directory.Build.Data.targets index 60c77a97f474..29ac55cb55d4 100644 --- a/eng/Directory.Build.Data.targets +++ b/eng/Directory.Build.Data.targets @@ -221,5 +221,8 @@ + + + - \ No newline at end of file + diff --git a/eng/scripts/Automation-Sdk-Generate.ps1 b/eng/scripts/Automation-Sdk-Generate.ps1 new file mode 100644 index 000000000000..13e46786dfa2 --- /dev/null +++ b/eng/scripts/Automation-Sdk-Generate.ps1 @@ -0,0 +1,144 @@ +[CmdletBinding()] +param( + [Parameter()] + [ValidateNotNullOrEmpty()] + [string] $InputJsonPath, + + [Parameter()] + [string] $OutputJsonPath, + + [Parameter()] + [string] $RepoRoot = "${PSScriptRoot}/../.." +) + +$inputFileContent = Get-Content $InputJsonPath | ConvertFrom-Json +[string[]] $inputFilePaths = $inputFileContent.changedFiles; +$inputFilePaths += $inputFileContent.relatedReadmeMdFiles; +$inputFilePaths = $inputFilePaths | Select-Object -Unique + +$changedFilePaths = $inputFilePaths -join "`n"; +Write-Host "List of changed swagger files and related readmes:`n$changedFilePaths`n" + +$autorestFilesPath = Get-ChildItem -Path "$RepoRoot/sdk" -Filter autorest.md -Recurse | Resolve-Path -Relative + +Write-Host "Updating autorest.md files for all the changed swaggers." +$sdksInfo = @{} +$headSha = $inputFileContent.headSha +$repoHttpsUrl = $inputFileContent.repoHttpsUrl +foreach ($path in $autorestFilesPath) { + $fileContent = Get-Content $path + foreach ($inputFilePath in $inputFilePaths) { + $isUpdatedLines = $false + $escapedInputFilePath = [System.Text.RegularExpressions.Regex]::Escape($inputFilePath) + $regexForMatchingShaAndPath = "https:\/\/[^`"]*[\/][0-9a-f]{4,40}[\/]$escapedInputFilePath" + $updatedLines = foreach ($line in $fileContent) { + if ($line -match $regexForMatchingShaAndPath) { + $line -replace $regexForMatchingShaAndPath, "$repoHttpsUrl/blob/$headSha/$inputFilePath" + + $isUpdatedLines = $true + $sdkpath = (get-item $path).Directory.Parent.FullName | Resolve-Path -Relative + if (!$sdksInfo.ContainsKey($sdkpath)) { + $specReadmePath = $inputFileContent.relatedReadmeMdFiles -match $inputFilePath + $sdksInfo.Add($sdkpath, $specReadmePath) + } + } + else { + $line + } + } + if ($isUpdatedLines) { + $updatedLines | Out-File -FilePath $path + } + } +} + +Write-Host "Updated autorest.md files for all the changed swaggers. `n" + +$packages = @() +$dotnet = Join-Path $RepoRoot ".dotnet" +$env:PATH = "$dotnet`:" + $env:PATH +foreach ($sdkPath in $sdksInfo.Keys) { + $packageName = Split-Path $sdkPath -Leaf + Write-Host "Generating code for " $packageName + $artifacts = @() + $hasBreakingChange = $null + $content = $null + $srcPath = Join-Path $sdkPath 'src' + dotnet msbuild /restore /t:GenerateCode $srcPath + if (!$LASTEXITCODE) { + $result = "succeeded" + Write-Host "Successfully generated code for" $packageName "`n" + + dotnet pack $srcPath /p:RunApiCompat=$false + if (!$LASTEXITCODE) { + $result = "succeeded" + $artifactsPath = "$RepoRoot/artifacts/packages/Debug/$packageName" + $artifacts += Get-ChildItem $artifactsPath -Filter *.nupkg -Recurse | Select-Object -ExpandProperty FullName | Resolve-Path -Relative + + $logFilePath = Join-Path "$srcPath" 'log.txt' + if (!(Test-Path $logFilePath)) { + New-Item $logFilePath + } + dotnet build $srcPath /t:RunApiCompat /p:TargetFramework=netstandard2.0 /flp:v=m`;LogFile=$logFilePath + if (!$LASTEXITCODE) { + $hasBreakingChange = $false + } + else { + $logFile = Get-Content -Path $logFilePath | select-object -skip 2 + $breakingChanges = $logFile -join ",`n" + $content = "Breaking Changes: $breakingChanges" + $hasBreakingChange = $true + } + + if (Test-Path $logFilePath) { + Remove-Item $logFilePath + } + } + else { + $result = "failed" + Write-Error "Error occurred while generating artifacts for $packageName `n" + } + } + else { + $result = "failed" + Write-Error "Error occurred while generating code for $packageName `n" + } + + $path = , $sdkPath + + $readmeMd = $sdksInfo[$sdkPath] + + $changelog = [PSCustomObject]@{ + content = $content + hasBreakingChange = $hasBreakingChange + } + + $downloadUrlPrefix = $inputFileContent.installInstructionInput.downloadUrlPrefix + $full = $null + if ($artifacts.count -gt 0) { + $fileName = Split-Path $artifacts[0] -Leaf + $full = "Download the $packageName package from [here]($downloadUrlPrefix/$fileName)" + } + $installInstructions = [PSCustomObject]@{ + full = $full + lite = $full + } + + $packageInfo = [PSCustomObject]@{ + packageName = $packageName + path = $path + readmeMd = $readmeMd + changelog = $changelog + artifacts = $artifacts + installInstructions = $installInstructions + result = $result + } + $packages += $packageInfo +} + +if ($OutputJsonPath) { + Write-Host "`nGenerating output JSON..." + ConvertTo-Json @{ + packages = $packages + } -depth 5 | Out-File -FilePath $OutputJsonPath +} diff --git a/eng/scripts/Automation-Sdk-Init.ps1 b/eng/scripts/Automation-Sdk-Init.ps1 new file mode 100644 index 000000000000..043d84f194bf --- /dev/null +++ b/eng/scripts/Automation-Sdk-Init.ps1 @@ -0,0 +1,46 @@ +[string] $RepoRoot = "${PSScriptRoot}/../.." +[string] $dotnetInstallScriptVersion = "v1" + +function GetDotNetInstallScript() { + $installScript = Join-Path $RepoRoot 'dotnet-install.sh' + if (!(Test-Path $installScript)) { + New-Item -Path $RepoRoot -Force -ItemType 'Directory' | Out-Null + $maxRetries = 5 + $retries = 1 + + $uri = "https://dot.net/$dotnetInstallScriptVersion/dotnet-install.sh" + while ($true) { + try { + Write-Host "GET $uri" + Invoke-WebRequest $uri -OutFile $installScript + break + } + catch { + Write-Host "Failed to download '$uri'" + Write-Error $_.Exception.Message -ErrorAction Continue + } + if (++$retries -le $maxRetries) { + $delayInSeconds = [math]::Pow(2, $retries) - 1 # Exponential backoff + Write-Host "Retrying. Waiting for $delayInSeconds seconds before next attempt ($retries of $maxRetries)." + Start-Sleep -Seconds $delayInSeconds + } + else { + throw "Unable to download file in $maxRetries attempts." + } + } + } + + return $installScript +} + +$GlobalJson = Get-Content -Raw -Path (Join-Path $RepoRoot 'global.json') | ConvertFrom-Json +$dotnetSdkVersion = $GlobalJson.sdk.version + +$installScript = GetDotNetInstallScript + +$dotnet = Join-Path $RepoRoot ".dotnet" +& bash $installScript --install-dir $dotnet --version $dotnetSdkVersion + +if (Test-Path $installScript) { + Remove-Item $installScript +} diff --git a/eng/swagger_to_sdk_config.json b/eng/swagger_to_sdk_config.json new file mode 100644 index 000000000000..62638ace2d7b --- /dev/null +++ b/eng/swagger_to_sdk_config.json @@ -0,0 +1,13 @@ +{ + "$schema": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/documentation/sdkautomation/SwaggerToSdkConfigSchema.json", + "generateOptions": { + "generateScript": { + "path": "pwsh ./eng/scripts/Automation-Sdk-Generate.ps1" + } + }, + "initOptions": { + "initScript": { + "path": "pwsh ./eng/scripts/Automation-Sdk-Init.ps1" + } + } +}