@@ -43,13 +43,17 @@ parameters:
4343 type : boolean
4444 default : false
4545 - name : notarizeAfterSign
46- displayName : Notarize Build Output
46+ displayName : Notarize Build Output (MacOS only)
4747 type : boolean
4848 default : true
4949 - name : simulate
5050 displayName : Simulate operations (faster)
5151 type : boolean
5252 default : false
53+ - name : forceNugetPublish
54+ displayName : Force Publishing the Nuget output
55+ type : boolean
56+ default : false
5357
5458# test ----------> | build -> | |
5559# | | sign |
@@ -118,9 +122,10 @@ stages:
118122 - ${{ if ne(parameters.simulate, 'true') }} :
119123 - template : templates/nuget-packages.yaml
120124 parameters :
125+ extraRestoreArgs : -p:PublishReadyToRun=true
121126 vstsFeedName : ${{variables.internalFeed}}
122127
123- - pwsh : dotnet publish ./src/msgraph-beta-cli.csproj --no-restore --runtime $(rid) --self-contained true --configuration $(buildConfiguration) --output $(outputDir)
128+ - pwsh : dotnet publish ./src/msgraph-beta-cli.csproj -p:PublishSingleFile=true -p:PublishReadyToRun=true - -no-restore --runtime $(rid) --self-contained true --configuration $(buildConfiguration) --output $(outputDir)
124129 workingDirectory : $(Build.SourcesDirectory)
125130 condition : and(succeeded(), ne('${{ parameters.simulate }}', 'true'))
126131 displayName : DotNet publish
@@ -207,7 +212,7 @@ stages:
207212 vmImage : windows-latest
208213 dependsOn : [build]
209214 # Only sign binaries if we're building a tag.
210- condition : and(succeeded(), or(eq('${{ parameters.forceSignOutput }}', 'true'), startsWith(variables['Build.SourceBranch'], 'refs/tags/v')))
215+ condition : and(succeeded(), or(eq('${{ parameters.forceSignOutput }}', 'true'), eq('${{ parameters.forceNugetPublish }}', 'true'), startsWith(variables['Build.SourceBranch'], 'refs/tags/v')))
211216 jobs :
212217 - job : esrpSign
213218 dependsOn : []
@@ -271,6 +276,71 @@ stages:
271276 }
272277 ]
273278 inlineNotarizeOperation : " "
279+ nuget :
280+ rid : nuget
281+ vmImage : windows-latest
282+ packageType : " zip"
283+ compressionProgram : " none"
284+ sign : true
285+ forceNugetPublish : ${{ parameters.forceNugetPublish }}
286+ pattern : |
287+ mgc-beta.dll
288+ inlineSignOperation : |
289+ [
290+ {
291+ "keyCode": "CP-230012",
292+ "operationSetCode": "SigntoolSign",
293+ "parameters": [
294+ {
295+ "parameterName": "OpusName",
296+ "parameterValue": "Microsoft"
297+ },
298+ {
299+ "parameterName": "OpusInfo",
300+ "parameterValue": "http://www.microsoft.com"
301+ },
302+ {
303+ "parameterName": "FileDigest",
304+ "parameterValue": "/fd \"SHA256\""
305+ },
306+ {
307+ "parameterName": "PageHash",
308+ "parameterValue": "/NPH"
309+ },
310+ {
311+ "parameterName": "TimeStamp",
312+ "parameterValue": "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256"
313+ }
314+ ],
315+ "toolName": "sign",
316+ "toolVersion": "1.0"
317+ },
318+ {
319+ "keyCode": "CP-230012",
320+ "operationSetCode": "SigntoolVerify",
321+ "parameters": [ ],
322+ "toolName": "sign",
323+ "toolVersion": "1.0"
324+ }
325+ ]
326+ inlineNugetSignOperation : |
327+ [
328+ {
329+ "keyCode": "CP-401405",
330+ "operationSetCode": "NuGetSign",
331+ "parameters": [ ],
332+ "toolName": "sign",
333+ "toolVersion": "1.0"
334+ },
335+ {
336+ "keyCode": "CP-401405",
337+ "operationSetCode": "NuGetVerify",
338+ "parameters": [ ],
339+ "toolName": "sign",
340+ "toolVersion": "1.0"
341+ }
342+ ]
343+
274344 ' MacOS-x64 ' :
275345 rid : osx-x64
276346 vmImage : macOS-11
@@ -304,18 +374,30 @@ stages:
304374 Write-Verbose 'fileNameTemplate = ''$(fileNameTemplate)'''
305375 Write-Verbose 'artifactsDownloadLocation = ''$(artifactsDownloadLocation)'''
306376 Write-Verbose 'sign = ''$(sign)'''
377+ Write-Verbose 'forceNugetPublish = ''$(forceNugetPublish)'''
307378 Write-Verbose 'notarize = ''$(notarize)'''
308379 Write-Verbose 'inlineSignOperation = ''$(inlineSignOperation)'''
309380 Write-Verbose 'inlineNotarizeOperation = ''$(inlineNotarizeOperation)'''
381+ Write-Verbose 'inlineNugetSignOperation = ''$(inlineNugetSignOperation)'''
310382 $rid = '$(rid)'
311383 $shouldSign = '$(sign)'
384+ if ($shouldSign.ToLower() -eq 'true' -and '$(rid)' -eq 'nuget') {
385+ $shouldSign = '$(forceNugetPublish)'
386+ }
312387 $shouldNotarize = '$(notarize)'
313388 $notarizeOp = '$(inlineNotarizeOperation)'
389+ $isNuget = $rid -eq 'nuget'
390+ $isDarwin = $rid.StartsWith('osx')
391+ $workDir = Join-Path -Path '$(artifactsDownloadLocation)' -ChildPath '$(rid)'
392+ $downloadDir = Join-Path -Path $workDir -ChildPath 'build-output-$(rid)'
314393 Write-Host "##vso[task.setvariable variable=RUNTIME_ID]$rid"
394+ Write-Host "##vso[task.setvariable variable=IS_NUGET]$isNuget"
395+ Write-Host "##vso[task.setvariable variable=IS_MACOS]$isDarwin"
315396 Write-Host "##vso[task.setvariable variable=SHOULD_SIGN]$shouldSign"
316397 Write-Host "##vso[task.setvariable variable=SHOULD_NOTARIZE]$shouldNotarize"
317398 Write-Host "##vso[task.setvariable variable=NOTARIZE_OPERATION]$notarizeOp"
318- Write-Host "##vso[task.setvariable variable=WORKING_DIR]$(artifactsDownloadLocation)/$(rid)"
399+ Write-Host "##vso[task.setvariable variable=WORKING_DIR]$workDir"
400+ Write-Host "##vso[task.setvariable variable=ARTIFACTS_PATH]$downloadDir"
319401 verbosePreference : ' $(OUTPUT_PREFERENCE)'
320402 debugPreference : ' $(OUTPUT_PREFERENCE)'
321403 informationPreference : ' $(OUTPUT_PREFERENCE)'
@@ -326,11 +408,62 @@ stages:
326408
327409 - checkout : self
328410
411+ # Nuget tool doesn't work with multi-stage builds
412+ - task : UseDotNet@2
413+ displayName : ' Use .NET 7'
414+ condition : and(succeeded(), ne('${{ parameters.simulate }}', 'true'), eq(variables['IS_NUGET'], 'true'))
415+ inputs :
416+ version : 7.x
417+
418+ - ${{ if ne(parameters.simulate, 'true') }} :
419+ - template : templates/nuget-packages.yaml
420+ parameters :
421+ vstsFeedName : ${{variables.internalFeed}}
422+ enabled : $(IS_NUGET)
423+
424+ - task : DotNetCoreCLI@2
425+ displayName : " build nuget tool"
426+ inputs :
427+ projects : ' ./src/msgraph-beta-cli.csproj'
428+ arguments : " --no-restore --configuration $(buildConfiguration) --no-incremental"
429+ condition : and(succeeded(), ne('${{ parameters.simulate }}', 'true'), eq(variables['IS_NUGET'], 'true'))
430+
431+ - pwsh : |
432+ New-Item '$(ARTIFACTS_PATH)' -ItemType Directory -Force
433+ echo "Test file" > '$(ARTIFACTS_PATH)/mgc-beta.dll'
434+ echo "Test file2" > '$(ARTIFACTS_PATH)/mgc-beta.txt'
435+ condition: and(succeeded(), eq('${{ parameters.simulate }}', 'true'), eq(variables['IS_NUGET'], 'true'))
436+ displayName: Simulate nuget build
437+
329438 - task : DownloadPipelineArtifact@2
330439 inputs :
331440 patterns : build-output-$(rid)/**/*
332441 path : $(WORKING_DIR)
333- condition : and(succeeded(), eq(variables['SHOULD_SIGN'], 'True'))
442+ condition : and(succeeded(), eq(variables['SHOULD_SIGN'], 'True'), ne(variables['IS_NUGET'], 'true'))
443+
444+ - task : PowerShell@2
445+ inputs :
446+ pwsh : true
447+ targetType : inline
448+ script : |
449+ $path = '$(ARTIFACTS_PATH)'
450+ if ('$(IS_NUGET)'.ToLower() -eq 'true' -and ('${{ parameters.simulate }}'.ToLower() -ne 'true')) {
451+ $path = './src/obj/$(buildConfiguration)/net7.0'
452+ }
453+ Write-Verbose "Checking if $path has files"
454+ $hasArtifacts = Test-Path $path/* -PathType Leaf
455+ Write-Verbose "Result $hasArtifacts"
456+
457+ $shouldSign = '$(SHOULD_SIGN)'.ToLower() -eq 'true'
458+ if ($shouldSign) {
459+ $shouldSign = $shouldSign -and $hasArtifacts
460+ }
461+ Write-Host "##vso[task.setvariable variable=SIGN_PATH]$path"
462+ Write-Host "##vso[task.setvariable variable=SHOULD_SIGN]$shouldSign"
463+ verbosePreference : ' $(OUTPUT_PREFERENCE)'
464+ debugPreference : ' $(OUTPUT_PREFERENCE)'
465+ informationPreference : ' $(OUTPUT_PREFERENCE)'
466+ displayName : Check for artifacts
334467
335468 - task : PowerShell@2
336469 inputs :
@@ -344,6 +477,7 @@ stages:
344477 debugPreference : ' $(OUTPUT_PREFERENCE)'
345478 informationPreference : ' $(OUTPUT_PREFERENCE)'
346479 displayName : Compute zip name
480+ condition : and(succeeded(), eq(variables['SHOULD_SIGN'], 'True'), ne(variables['IS_NUGET'], 'true'))
347481
348482 - task : PowerShell@2
349483 inputs :
@@ -352,7 +486,7 @@ stages:
352486 script : |
353487 . $(powershellScriptsDir)/BuildTools.ps1
354488
355- $downloadDir = Join-Path -Path '$(WORKING_DIR)' -ChildPath 'build-output-$(rid )'
489+ $downloadDir = '$(ARTIFACTS_PATH )'
356490 $extractPath = Join-Path -Path '$(WORKING_DIR)' -ChildPath artifacts
357491 Expand-EsrpArtifacts -SourceDir $downloadDir -OutputDir $extractPath -FileNameTemplate '$(fileNameTemplate)' -BranchOrTagName '$(branchOrTagName)' -RuntimeIdentifier '$(rid)' -PackageType $(packageType) -TarCompression $(compressionProgram) -Cleanup
358492
@@ -362,31 +496,39 @@ stages:
362496 debugPreference : ' $(OUTPUT_PREFERENCE)'
363497 informationPreference : ' $(OUTPUT_PREFERENCE)'
364498 displayName : Extract archive
365- condition : and(succeeded(), eq(variables['SHOULD_SIGN'], 'True'))
499+ condition : and(succeeded(), eq(variables['SHOULD_SIGN'], 'True'), ne(variables['IS_NUGET'], 'True') )
366500
367501 - template : templates/prepare-unsigned-executable-darwin.yaml
368502 parameters :
369503 executablePath : $(ARTIFACTS_PATH)
370504 executableName : mgc-beta
371505 zipName : $(ZIP_NAME)
372506 targetRuntime : $(rid)
507+ enabled : $(IS_MACOS)
373508
374509 - pwsh : |
375510 Write-Host "##vso[task.setvariable variable=ESRP_FILE_PATTERN]$(ZIP_NAME)"
376511 displayName: Compute ESRP filter pattern osx
377- condition: and(succeeded(), startsWith (variables['RUNTIME_ID '], 'osx '))
512+ condition: and(succeeded(), eq (variables['SHOULD_SIGN '], 'True'), eq(variables['IS_MACOS'], 'true '))
378513
379514 - pwsh : |
380515 Write-Host "##vso[task.setvariable variable=ESRP_FILE_PATTERN]$(pattern)"
381- displayName: Compute ESRP filter pattern Windows
382- condition: and(succeeded(), startsWith(variables['RUNTIME_ID'], 'win'))
516+ displayName: Compute ESRP filter pattern Windows/Nuget
517+ condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'True'), or(startsWith(variables['RUNTIME_ID'], 'win'), eq(variables['IS_NUGET'], 'true')))
518+
519+ # ESRP needs .NET 6
520+ - task : UseDotNet@2
521+ displayName : ' Change to .NET 6'
522+ condition : and(succeeded(), ne('${{ parameters.simulate }}', 'true'), eq(variables['IS_NUGET'], 'true'))
523+ inputs :
524+ version : 6.x
383525
384526 - task : EsrpCodeSigning@2
385- displayName : ' ESRP CodeSigning (Sign)'
527+ displayName : ' ESRP CodeSigning (Sign Build output )'
386528 inputs :
387529 # Pipeline validation can't expand service name from matrix variables
388530 ConnectedServiceName : " microsoftgraph ESRP CodeSign DLL and NuGet (AKV)"
389- FolderPath : $(ARTIFACTS_PATH )
531+ FolderPath : $(SIGN_PATH )
390532 signConfigType : inlineSignParams
391533 UseMinimatch : true
392534 Pattern : $(ESRP_FILE_PATTERN)
@@ -399,14 +541,38 @@ stages:
399541 inputs :
400542 # Pipeline validation can't expand service name from matrix variables
401543 ConnectedServiceName : " microsoftgraph ESRP CodeSign DLL and NuGet (AKV)"
402- FolderPath : $(ARTIFACTS_PATH )
544+ FolderPath : $(SIGN_PATH )
403545 signConfigType : inlineSignParams
404546 UseMinimatch : true
405547 Pattern : $(ESRP_FILE_PATTERN)
406548 inlineOperation : $(inlineNotarizeOperation)
407549 SessionTimeout : 20
408550 condition : and(succeeded(), ne('${{ parameters.simulate }}', 'true'), gt(length(variables['NOTARIZE_OPERATION']), 0), ne(variables['NOTARIZE_OPERATION'], '$(inlineNotarizeOperation)'), and(eq(variables['SHOULD_SIGN'], 'True'), eq(variables['SHOULD_NOTARIZE'], 'True')))
409551
552+ - pwsh : |
553+ dotnet pack ./src/msgraph-beta-cli.csproj --configuration $(buildConfiguration) --output $(ARTIFACTS_PATH) --no-build --include-symbols --include-source /p:SymbolPackageFormat=snupkg -v d
554+ workingDirectory: $(Build.SourcesDirectory)
555+ displayName: DotNet pack (nuget)
556+ condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'True'), ne('${{ parameters.simulate }}', 'true'), eq(variables['Is_NUGET'], 'true'))
557+
558+ - task : EsrpCodeSigning@2
559+ displayName : ' ESRP CodeSigning (Sign Nuget)'
560+ inputs :
561+ # Pipeline validation can't expand service name from matrix variables
562+ ConnectedServiceName : " microsoftgraph ESRP CodeSign DLL and NuGet (AKV)"
563+ FolderPath : $(ARTIFACTS_PATH)
564+ signConfigType : inlineSignParams
565+ UseMinimatch : true
566+ Pattern : " *.nupkg"
567+ inlineOperation : $(inlineNugetSignOperation)
568+ SessionTimeout : 20
569+ condition : and(succeeded(), ne('${{ parameters.simulate }}', 'true'), eq(variables['SHOULD_SIGN'], 'True'), eq(variables['IS_NUGET'], 'true'))
570+
571+ - pwsh : |
572+ $artifactsPath = '$(ARTIFACTS_PATH)'
573+ Write-Host "##vso[task.setvariable variable=WORKING_DIR]$artifactsPath"
574+ condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'True'), eq(variables['IS_NUGET'], 'true'))
575+
410576 - task : PowerShell@2
411577 displayName : Simulate ESRP
412578 inputs :
@@ -435,7 +601,7 @@ stages:
435601 verbosePreference : ' $(OUTPUT_PREFERENCE)'
436602 debugPreference : ' $(OUTPUT_PREFERENCE)'
437603 informationPreference : ' $(OUTPUT_PREFERENCE)'
438- condition : and(succeeded(), eq('${{ parameters.simulate }}', 'true'))
604+ condition : and(succeeded(), eq(variables['SHOULD_SIGN'], 'True'), eq( '${{ parameters.simulate }}', 'true'))
439605
440606 - task : PowerShell@2
441607 inputs :
@@ -478,7 +644,7 @@ stages:
478644 pool :
479645 vmImage : windows-latest
480646 # Only scan binaries if we're building a tag, building main, or building a PR targeting main
481- condition : and(succeeded(), or(startsWith(variables['Build.SourceBranch'], 'refs/tags/v'), eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['System.PullRequest.TargetBranch'], 'main')))
647+ condition : and(succeeded(), or(startsWith(variables['Build.SourceBranch'], 'refs/tags/v'), eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['System.PullRequest.TargetBranch'], 'main'), eq('${{ parameters.forceNugetPublish }}', 'true') ))
482648 jobs :
483649 - job : scan
484650 displayName : Scanning binaries
@@ -491,11 +657,12 @@ stages:
491657
492658 - stage : upload
493659 dependsOn : [binaryScan, sign]
494- # Only upload release if we're building a tag.
495- condition : and(succeeded(), ne('${{ parameters.simulate }}', 'true'), startsWith(variables['Build.SourceBranch'], 'refs/tags/v'))
660+ condition : and(succeeded(), ne('${{ parameters.simulate }}', 'true'))
496661 jobs :
497- - job : upload
498- displayName : Upload binaries
662+ - job : uploadGitHub
663+ displayName : Upload binaries (GitHub)
664+ # Only upload release if we're building a tag.
665+ condition : and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/tags/v'))
499666 steps :
500667 - checkout : none
501668 - task : DownloadPipelineArtifact@2
@@ -519,3 +686,29 @@ stages:
519686 $(artifactsDownloadLocation)/sign-output-*/*.tar*
520687 $(artifactsDownloadLocation)/sign-output-*/*.zip
521688 isPreRelease : $(IS_PREVIEW)
689+
690+ - deployment : deployNuget
691+ displayName : Deploy Nuget
692+ dependsOn : []
693+ environment : microsoftgraph-nuget-org
694+ condition : and(succeeded(), or(startsWith(variables['Build.SourceBranch'], 'refs/tags/v'), eq('${{ parameters.forceNugetPublish }}', 'true')))
695+ strategy :
696+ runOnce :
697+ deploy :
698+ pool :
699+ vmImage : ubuntu-latest
700+ steps :
701+ - task : DownloadPipelineArtifact@2
702+ displayName : Download nupkg from artifacts
703+ inputs :
704+ artifact : sign-output-nuget
705+ source : current
706+ path : $(artifactsDownloadLocation)/nuget
707+ - task : NuGetCommand@2
708+ displayName : " NuGet push"
709+ inputs :
710+ command : push
711+ packagesToPush : " $(artifactsDownloadLocation)/nuget/Microsoft.Graph.Beta.Cli.*.nupkg;$(artifactsDownloadLocation)/nuget/Microsoft.Graph.Beta.Cli.*.snupkg;"
712+ nuGetFeedType : external
713+ publishFeedCredentials : " microsoftgraph NuGet connection"
714+
0 commit comments