From 6289083361f030367cf767ebdb16517ffca95b27 Mon Sep 17 00:00:00 2001 From: sharanya-rao <31542731+sharanya-rao@users.noreply.github.com> Date: Wed, 29 Apr 2020 09:44:29 +0800 Subject: [PATCH] Enabled ESRPCodeSign for docfx v2 - dev (#5832) * Enable code sign for docfxv2 - dev * Updated matched paths with include filters instead of exclude paths. * minor fix * fixed build error * Included pack step * Resolved review comments. * Fixed batchsign policy file. * Fixed build/pack/codesign * Fixed indentation; Moved pack after e2etest --- azure-pipelines-stable.yml | 18 ++++ build.ps1 | 156 ++++------------------------------- codesign_policy.json | 125 ++++++++++++++++++++++++++++ common.ps1 | 38 +++++++++ pack.ps1 | 145 ++++++++++++++++++++++++++++++++ tools/Deployment/gulpfile.js | 10 ++- 6 files changed, 350 insertions(+), 142 deletions(-) create mode 100644 codesign_policy.json create mode 100644 common.ps1 create mode 100644 pack.ps1 diff --git a/azure-pipelines-stable.yml b/azure-pipelines-stable.yml index e0b044a4389..73532d3070e 100644 --- a/azure-pipelines-stable.yml +++ b/azure-pipelines-stable.yml @@ -28,6 +28,24 @@ steps: - task: CmdLine@1 displayName: 'gulp build' + inputs: + filename: node + arguments: '.\node_modules\gulp\bin\gulp.js dev:build' + workingFolder: tools/Deployment + +- task: EsrpCodeSigning@1 + displayName: Sign executables and dlls + inputs: + ConnectedServiceName: 'CodeSigning-APEX' + FolderPath: '$(Build.SourcesDirectory)/target/Release' + signType: 'batchSigning' + batchSignPolicyFile: '$(Build.SourcesDirectory)/codesign_policy.json' + SessionTimeout: '60' + MaxConcurrency: '50' + MaxRetryAttempts: '5' + +- task: CmdLine@1 + displayName: 'gulp pack' inputs: filename: node arguments: '.\node_modules\gulp\bin\gulp.js dev:release' diff --git a/build.ps1 b/build.ps1 index f9426a46c09..9da16c9a494 100644 --- a/build.ps1 +++ b/build.ps1 @@ -14,6 +14,10 @@ param( # [-skipTests]: If it's set, running unit tests will be skipped ################################################################################################ +# Include +$scriptRoot = $($MyInvocation.MyCommand.Definition) | Split-Path +. "$scriptRoot/common.ps1" + $ErrorActionPreference = 'Stop' $releaseBranch = "master" $gitCommand = "git" @@ -21,21 +25,9 @@ $framework = "net472" $packageVersion = "1.0.0" $assemblyVersion = "1.0.0.0" -if ([environment]::OSVersion.Platform -eq "Win32NT") { - $os = "Windows" -} -else { - $os = "Linux" -} +$os = GetOperatingSystemName Write-Host "Running on OS $os" - -if ($os -eq "Windows") { - $nugetCommand = "$env:LOCALAPPDATA/Nuget/Nuget.exe" -} -else { - $nugetCommand = "nuget" -} - +$nugetCommand = GetNuGetCommand ($os) $scriptPath = $MyInvocation.MyCommand.Path $scriptHome = Split-Path $scriptPath $versionCsFolderPath = $scriptHome + "/TEMP/" @@ -46,47 +38,11 @@ $global:LASTEXITCODE = $null Push-Location $scriptHome -function NugetPack { - param($basepath, $nuspec, $version) - if (Test-Path $nuspec) { - & $nugetCommand pack $nuspec -Version $version -OutputDirectory artifacts/$configuration -BasePath $basepath - ProcessLastExitCode $lastexitcode "$nugetCommand pack $nuspec -Version $version -OutputDirectory artifacts/$configuration -BasePath $basepath" - } -} - -function ProcessLastExitCode { - param($exitCode, $msg) - if ($exitCode -eq 0) { - Write-Host "Success: $msg - " -ForegroundColor Green - } - else { - Write-Host "Error $($exitCode): $msg - " -ForegroundColor Red - Pop-Location - Exit 1 - } -} - -function ValidateCommand { - param($command) - return (Get-Command $command -ErrorAction SilentlyContinue) -ne $null -} - # Check if dotnet cli exists globally if (-not(ValidateCommand("dotnet"))) { ProcessLastExitCode 1 "Dotnet CLI is not successfully configured. Please follow https://www.microsoft.com/net/core to install .NET Core." } -# Check if nuget.exe exists -if (-not(ValidateCommand($nugetCommand))) { - Write-Host "Downloading NuGet.exe..." - mkdir -Path "$env:LOCALAPPDATA/Nuget" -Force - $ProgressPreference = 'SilentlyContinue' - [Net.WebRequest]::DefaultWebProxy.Credentials = [Net.CredentialCache]::DefaultCredentials - Invoke-WebRequest 'https://dist.nuget.org/win-x86-commandline/latest/nuget.exe' -OutFile $nugetCommand -} - # Update template if ($raw -eq $false) { ./UpdateTemplate.ps1 @@ -164,6 +120,10 @@ do () Write-Host "Using package version $packageVersion, and assembly version $assemblyVersion, assembly file version $assemblyFileVersion" +$packageVersionFilePath = ".\package_version_temp.txt" +$packageVersion | Out-File -FilePath $packageVersionFilePath -Force +Write-Host "Package version saved to $packageVersionFilePath" + foreach ($sln in (Get-ChildItem *.sln)) { Write-Host "Start building $($sln.FullName)" @@ -202,98 +162,14 @@ if (-not $skipTests) { } } -# dotnet pack first -foreach ($proj in (Get-ChildItem -Path ("src", "plugins") -Include *.[cf]sproj -Exclude 'docfx.msbuild.csproj' -Recurse)) { - if ($os -eq "Windows") { - & dotnet pack $proj.FullName -c $configuration -o $scriptHome/artifacts/$configuration /p:Version=$packageVersion - ProcessLastExitCode $lastexitcode "dotnet pack $($proj.FullName) -c $configuration -o $scriptHome/artifacts/$configuration /p:Version=$packageVersion" - } - else { - & nuget pack $($proj.FullName) -Properties Configuration=$configuration -OutputDirectory $scriptHome/artifacts/$configuration -Version $packageVersion - ProcessLastExitCode $lastexitcode "nuget pack $($proj.FullName) -Properties Configuration=$configuration -OutputDirectory $scriptHome/artifacts/$configuration -Version $packageVersion" - } -} - -# Pack docfx.console -$docfxTarget = "target/$configuration/docfx"; -if (-not(Test-Path -path $docfxTarget)) { - New-Item $docfxTarget -Type Directory -} - -Copy-Item -Path "src/nuspec/docfx.console/build" -Destination $docfxTarget -Force -Recurse -Copy-Item -Path "src/nuspec/docfx.console/content" -Destination $docfxTarget -Force -Recurse - -$packages = @{ - "docfx" = @{ - "proj" = $null; - "nuspecs" = @("src/nuspec/docfx.console/docfx.console.nuspec"); - }; - "MergeDeveloperComments" = @{ - "proj" = $null; - "nuspecs" = @("src/nuspec/MergeDeveloperComments/MergeDeveloperComments.nuspec"); - }; - "MergeSourceInfo" = @{ - "proj" = $null; - "nuspecs" = @("src/nuspec/MergeSourceInfo/MergeSourceInfo.nuspec"); - }; - "TocConverter" = @{ - "proj" = $null; - "nuspecs" = @("src/nuspec/TocConverter/TocConverter.nuspec"); - }; - "MarkdownMigrateTool" = @{ - "proj" = $null; - "nuspecs" = @("src/nuspec/MarkdownMigrateTool/MarkdownMigrateTool.nuspec"); - }; - "YamlSplitter" = @{ - "proj" = $null; - "nuspecs" = @("src/nuspec/YamlSplitter/YamlSplitter.nuspec"); - }; - "SandcastleRefMapper" = @{ - "proj" = $null; - "nuspecs" = @("src/nuspec/SandcastleRefMapper/SandcastleRefMapper.nuspec") - }; -} - -# Pack plugins and tools -foreach ($proj in (Get-ChildItem -Path ("src", "plugins", "tools") -Include *.csproj -Recurse)) { +foreach ($proj in (Get-ChildItem -Path ("src", "plugins", "tools") -Include *.csproj -Recurse)) +{ $name = $proj.BaseName - if ($packages.ContainsKey($name)) { - $packages[$name].proj = $proj - } - $nuspecs = Join-Path $proj.DirectoryName "*.nuspec" -Resolve - if ($nuspecs -ne $null) { - if ($packages.ContainsKey($name)) { - $packages[$name].nuspecs = $packages[$name].nuspecs + $nuspecs - } - else { - $packages[$name] = @{ - nuspecs = $nuspecs; - proj = $proj; - } - } - } -} - -foreach ($name in $packages.Keys) { - $val = $packages[$name] - $proj = $val.proj - - if ($proj -eq $null) { - Write-Host $package - ProcessLastExitCode 1 "$name does not have project found" - } - $outputFolder = "$scriptHome/target/$configuration/$name" - # publish to target folder before pack - & dotnet publish $proj.FullName -c $configuration -f $framework -o $outputFolder - ProcessLastExitCode $lastexitcode "dotnet publish $($proj.FullName) -c $configuration -f $framework -o $outputFolder" - - $nuspecs = $val.nuspecs - foreach ($nuspec in $nuspecs) { - NugetPack $outputFolder $nuspec $packageVersion - } + # publish to target folder + & dotnet publish $proj.FullName -c $configuration --no-build -f $framework -o $outputFolder + ProcessLastExitCode $lastexitcode "dotnet publish $($proj.FullName) -c $configuration --no-build -f $framework -o $outputFolder" } Write-Host "Build succeeds." -ForegroundColor Green -Pop-Location - +Pop-Location \ No newline at end of file diff --git a/codesign_policy.json b/codesign_policy.json new file mode 100644 index 00000000000..511f9f45c42 --- /dev/null +++ b/codesign_policy.json @@ -0,0 +1,125 @@ +{ + "Version": "1.0.0", + "UseMinimatch": true, + "SignBatches": [ + { + "MatchedPath": [ + "Microsoft.DocAsCode*.dll", + "*.exe" + ], + "SigningInfo": { + "Operations": [ + { + "KeyCode": "CP-230012", + "OperationSetCode": "SigntoolSign", + "parameters": [ + { + "parameterName": "OpusName", + "parameterValue": "Microsoft" + }, + { + "parameterName": "OpusInfo", + "parameterValue": "http://www.microsoft.com" + }, + { + "parameterName": "PageHash", + "parameterValue": "/NPH" + }, + { + "parameterName": "TimeStamp", + "parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256" + }, + { + "parameterName": "FileDigest", + "parameterValue": "/fd \"SHA256\"" + } + ], + "ToolName": "sign", + "ToolVersion": "1.0" + }, + { + "KeyCode": "CP-230012", + "OperationSetCode": "SigntoolVerify", + "Parameters": [ + { + "parameterName": "VerifyAll", + "parameterValue": "/all" + } + ], + "ToolName": "sign", + "ToolVersion": "1.0" + } + ] + } + }, + { + "MatchedPath": [ + "DotLiquid.resources.dll", + "AutoMapper.dll", + "CommandLine.dll", + "DotLiquid.dll", + "Dotnet.ProjInfo.dll", + "Dotnet.ProjInfo.Helpers.dll", + "FSharp.Compiler.*.dll", + "HtmlAgilityPack.dll", + "itextsharp.dll", + "Jint.dll", + "Markdig.dll", + "Newtonsoft.Json.dll", + "Newtonsoft.Json.Schema.dll", + "Nustache.Core.dll", + "Owin.dll", + "SQLitePCLRaw.core.dll", + "YamlDotNet.dll" + ], + "SigningInfo": { + "Operations": [ + { + "KeyCode": "CP-231522", + "OperationSetCode": "SigntoolSign", + "parameters": [ + { + "parameterName": "OpusName", + "parameterValue": "Microsoft" + }, + { + "parameterName": "OpusInfo", + "parameterValue": "http://www.microsoft.com" + }, + { + "parameterName": "Append", + "parameterValue": "/as" + }, + { + "parameterName": "PageHash", + "parameterValue": "/NPH" + }, + { + "parameterName": "TimeStamp", + "parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256" + }, + { + "parameterName": "FileDigest", + "parameterValue": "/fd \"SHA256\"" + } + ], + "ToolName": "sign", + "ToolVersion": "1.0" + }, + { + "KeyCode": "CP-231522", + "OperationSetCode": "SigntoolVerify", + "Parameters": [ + { + "parameterName": "VerifyAll", + "parameterValue": "/all" + } + ], + "ToolName": "sign", + "ToolVersion": "1.0" + } + ] + } + } + ] +} \ No newline at end of file diff --git a/common.ps1 b/common.ps1 new file mode 100644 index 00000000000..e352e23697d --- /dev/null +++ b/common.ps1 @@ -0,0 +1,38 @@ +function GetOperatingSystemName() +{ + if ([environment]::OSVersion.Platform -eq "Win32NT") { + return "Windows" + } + else { + return "Linux" + } +} + +function GetNuGetCommand([string]$os) +{ + if ($os -eq "Windows") { + return "$env:LOCALAPPDATA/Nuget/Nuget.exe" + } + else { + return "nuget" + } +} + +function ProcessLastExitCode { + param($exitCode, $msg) + if ($exitCode -eq 0) { + Write-Host "Success: $msg + " -ForegroundColor Green + } + else { + Write-Host "Error $($exitCode): $msg + " -ForegroundColor Red + Pop-Location + Exit 1 + } +} + +function ValidateCommand { + param($command) + return (Get-Command $command -ErrorAction SilentlyContinue) -ne $null +} \ No newline at end of file diff --git a/pack.ps1 b/pack.ps1 new file mode 100644 index 00000000000..519fa477d01 --- /dev/null +++ b/pack.ps1 @@ -0,0 +1,145 @@ +param([string] $configuration = "Release") + +# Include +$scriptRoot = $($MyInvocation.MyCommand.Definition) | Split-Path +. "$scriptRoot/common.ps1" + +$ErrorActionPreference = 'Stop' +$packageVersionFilePath = ".\package_version_temp.txt" # build.ps1 saves the package version to this temp file + +if (Test-Path $packageVersionFilePath){ + $packageVersion = Get-Content -Path $packageVersionFilePath + Write-Host "Package version: $packageVersion" +} +else{ + ProcessLastExitCode 1 "$packageVersionFilePath is not found. Please run build.ps1 to generate the file." +} + +$os = GetOperatingSystemName +Write-Host "Running on OS $os" +$nugetCommand = GetNuGetCommand ($os) +$scriptPath = $MyInvocation.MyCommand.Path +$scriptHome = Split-Path $scriptPath + +$global:LASTEXITCODE = $null + +Push-Location $scriptHome + +function NugetPack { + param($basepath, $nuspec, $version) + if (Test-Path $nuspec) { + & $nugetCommand pack $nuspec -Version $version -OutputDirectory artifacts/$configuration -BasePath $basepath + ProcessLastExitCode $lastexitcode "$nugetCommand pack $nuspec -Version $version -OutputDirectory artifacts/$configuration -BasePath $basepath" + } +} + +# Check if dotnet cli exists globally +if (-not(ValidateCommand("dotnet"))) { + ProcessLastExitCode 1 "Dotnet CLI is not successfully configured. Please follow https://www.microsoft.com/net/core to install .NET Core." +} + +# Check if nuget.exe exists +if (-not(ValidateCommand($nugetCommand))) { + Write-Host "Downloading NuGet.exe..." + mkdir -Path "$env:LOCALAPPDATA/Nuget" -Force + $ProgressPreference = 'SilentlyContinue' + [Net.WebRequest]::DefaultWebProxy.Credentials = [Net.CredentialCache]::DefaultCredentials + Invoke-WebRequest 'https://dist.nuget.org/win-x86-commandline/latest/nuget.exe' -OutFile $nugetCommand +} + +# dotnet pack first +foreach ($proj in (Get-ChildItem -Path ("src", "plugins") -Include *.[cf]sproj -Exclude 'docfx.msbuild.csproj' -Recurse)) { + if ($os -eq "Windows") { + if ($proj.FullName -like "*.csproj"){ + & dotnet pack $proj.FullName -c $configuration --no-build -o $scriptHome/artifacts/$configuration /p:Version=$packageVersion /p:OutputPath=$scriptHome/target/$configuration/$($proj.BaseName) + ProcessLastExitCode $lastexitcode "dotnet pack $($proj.FullName) -c $configuration --no-build -o $scriptHome/artifacts/$configuration /p:Version=$packageVersion /p:OutputPath=$scriptHome/target/$configuration/$($proj.BaseName)" + } + else { + & dotnet pack $proj.FullName -c $configuration -o $scriptHome/artifacts/$configuration /p:Version=$packageVersion + ProcessLastExitCode $lastexitcode "dotnet pack $($proj.FullName) -c $configuration -o $scriptHome/artifacts/$configuration /p:Version=$packageVersion" + } + } + else { + & nuget pack $($proj.FullName) -Properties Configuration=$configuration -OutputDirectory $scriptHome/artifacts/$configuration -Version $packageVersion -BasePath $scriptHome/target/$configuration/$($proj.BaseName) + ProcessLastExitCode $lastexitcode "nuget pack $($proj.FullName) -Properties Configuration=$configuration -OutputDirectory $scriptHome/artifacts/$configuration -Version $packageVersion -BasePath $scriptHome/target/$configuration/$($proj.BaseName)" + } +} + +# Pack docfx.console +$docfxTarget = "target/$configuration/docfx"; +if (-not(Test-Path -path $docfxTarget)) { + New-Item $docfxTarget -Type Directory +} + +Copy-Item -Path "src/nuspec/docfx.console/build" -Destination $docfxTarget -Force -Recurse +Copy-Item -Path "src/nuspec/docfx.console/content" -Destination $docfxTarget -Force -Recurse + +$packages = @{ + "docfx" = @{ + "proj" = $null; + "nuspecs" = @("src/nuspec/docfx.console/docfx.console.nuspec"); + }; + "MergeDeveloperComments" = @{ + "proj" = $null; + "nuspecs" = @("src/nuspec/MergeDeveloperComments/MergeDeveloperComments.nuspec"); + }; + "MergeSourceInfo" = @{ + "proj" = $null; + "nuspecs" = @("src/nuspec/MergeSourceInfo/MergeSourceInfo.nuspec"); + }; + "TocConverter" = @{ + "proj" = $null; + "nuspecs" = @("src/nuspec/TocConverter/TocConverter.nuspec"); + }; + "MarkdownMigrateTool" = @{ + "proj" = $null; + "nuspecs" = @("src/nuspec/MarkdownMigrateTool/MarkdownMigrateTool.nuspec"); + }; + "YamlSplitter" = @{ + "proj" = $null; + "nuspecs" = @("src/nuspec/YamlSplitter/YamlSplitter.nuspec"); + }; + "SandcastleRefMapper" = @{ + "proj" = $null; + "nuspecs" = @("src/nuspec/SandcastleRefMapper/SandcastleRefMapper.nuspec") + }; +} + +# Pack plugins and tools +foreach ($proj in (Get-ChildItem -Path ("src", "plugins", "tools") -Include *.csproj -Recurse)) { + $name = $proj.BaseName + if ($packages.ContainsKey($name)) { + $packages[$name].proj = $proj + } + $nuspecs = Join-Path $proj.DirectoryName "*.nuspec" -Resolve + if ($nuspecs -ne $null) { + if ($packages.ContainsKey($name)) { + $packages[$name].nuspecs = $packages[$name].nuspecs + $nuspecs + } + else { + $packages[$name] = @{ + nuspecs = $nuspecs; + proj = $proj; + } + } + } +} + +foreach ($name in $packages.Keys) { + $val = $packages[$name] + $proj = $val.proj + + if ($proj -eq $null) { + Write-Host $package + ProcessLastExitCode 1 "$name does not have project found" + } + + $outputFolder = "$scriptHome/target/$configuration/$name" + $nuspecs = $val.nuspecs + foreach ($nuspec in $nuspecs) { + NugetPack $outputFolder $nuspec $packageVersion + } +} + +Write-Host "Pack succeeds." -ForegroundColor Green +Pop-Location \ No newline at end of file diff --git a/tools/Deployment/gulpfile.js b/tools/Deployment/gulpfile.js index c400a583c64..80c7e921db3 100644 --- a/tools/Deployment/gulpfile.js +++ b/tools/Deployment/gulpfile.js @@ -46,6 +46,11 @@ gulp.task("build", () => { return Common.execAsync("powershell", ["./build.ps1", "-prod"], config.docfx.home); }); +gulp.task("pack", () => { + Guard.argumentNotNullOrEmpty(config.docfx.home, "config.docfx.home", "Can't find docfx home directory in configuration."); + return Common.execAsync("powershell", ["./pack.ps1"], config.docfx.home); +}); + gulp.task("build:release", () => { Guard.argumentNotNullOrEmpty(config.docfx.home, "config.docfx.home", "Can't find docfx home directory in configuration."); return Common.execAsync("powershell", ["./build.ps1", "-prod", "-release"], config.docfx.home); @@ -243,9 +248,10 @@ gulp.task("syncBranchCore", () => { let docfxHome = path.resolve(config.docfx.home); return SyncBranch.runAsync(repoUrl, docfxHome, config.sync.fromBranch, config.sync.targetBranch); }); -gulp.task("test", gulp.series("clean", "build", "e2eTest", "publish:myget-test")); +gulp.task("test", gulp.series("clean", "build", "e2eTest", "pack", "publish:myget-test")); gulp.task("dev", gulp.series("clean", "build", "e2eTest")); -gulp.task("dev:release", gulp.series("clean", "build", "e2eTest", "publish:myget-dev", "publish:azdevops-perf-login", "publish:azdevops-perf", "publish:azdevops-internal-login", "publish:azdevops-internal", "publish:azdevops-ppe-login", "publish:azdevops-ppe")); +gulp.task("dev:build", gulp.series("clean", "build", "e2eTest")); +gulp.task("dev:release", gulp.series("pack", "publish:myget-dev", "publish:azdevops-perf-login", "publish:azdevops-perf", "publish:azdevops-internal-login", "publish:azdevops-internal", "publish:azdevops-ppe-login", "publish:azdevops-ppe")); gulp.task("master:build", gulp.series("clean", "build:release", "e2eTest", "updateGhPage")); gulp.task("master:release", gulp.series("packAssetZip", "publish:myget-master", "publish:azdevops-prod-login", "publish:azdevops-prod", "publish:gh-release", "publish:gh-asset", "publish:chocolatey"));