diff --git a/.azure-pipelines/ci-build.yml b/.azure-pipelines/ci-build.yml index 74f652c9a..37297d5cc 100644 --- a/.azure-pipelines/ci-build.yml +++ b/.azure-pipelines/ci-build.yml @@ -39,6 +39,9 @@ extends: name: Azure-Pipelines-1ESPT-ExDShared image: windows-2022 os: windows + settings: + # Direct NuGet.org publishing is blocked by CFSClean. Keep later CFS policies enabled. + networkIsolationPolicy: Permissive, CFSClean2, CFSClean3 customBuildTags: - ES365AIMigrationTooling stages: @@ -71,13 +74,6 @@ extends: inputs: useGlobalJson: true - # Install the nuget tool. - - task: NuGetToolInstaller@1 - displayName: 'Use NuGet >=6.11.0' - inputs: - versionSpec: '>=6.11.0' - checkLatest: true - # Build the Product project - task: NuGetAuthenticate@1 displayName: 'Authenticate to Azure Artifacts' @@ -93,11 +89,20 @@ extends: "@ | Set-Content -Path "$(Build.SourcesDirectory)/nuget.config" -Encoding UTF8 displayName: 'Create nuget.config (central feed)' + + - task: DotNetCoreCLI@2 + displayName: 'restore' + inputs: + command: restore + projects: '$(Build.SourcesDirectory)\Microsoft.OpenApi.slnx' + feedsToUse: config + nugetConfigPath: '$(Build.SourcesDirectory)\nuget.config' + - task: DotNetCoreCLI@2 displayName: 'build' inputs: projects: '$(Build.SourcesDirectory)\Microsoft.OpenApi.slnx' - arguments: '--configuration $(BuildConfiguration) --no-incremental' + arguments: '--configuration $(BuildConfiguration) --no-incremental --no-restore' # Run the Unit test - task: DotNetCoreCLI@2 @@ -107,7 +112,7 @@ extends: projects: '$(Build.SourcesDirectory)\Microsoft.OpenApi.slnx' arguments: '--configuration $(BuildConfiguration) --no-build' - - task: EsrpCodeSigning@5 + - task: EsrpCodeSigning@6 displayName: 'ESRP CodeSigning binaries' inputs: ConnectedServiceName: 'Federated DevX ESRP Managed Identity Connection' @@ -162,18 +167,18 @@ extends: PendingAnalysisWaitTimeoutMinutes: '5' # Pack core lib - - pwsh: dotnet pack $(Build.SourcesDirectory)/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj -o $(Build.ArtifactStagingDirectory) --configuration $(BuildConfiguration) --no-build --include-symbols --include-source /p:SymbolPackageFormat=snupkg + - pwsh: dotnet pack $(Build.SourcesDirectory)/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj -o $(Build.ArtifactStagingDirectory) --configuration $(BuildConfiguration) --no-build --no-restore --include-symbols --include-source /p:SymbolPackageFormat=snupkg displayName: 'pack OpenAPI' # Pack YamlReader - - pwsh: dotnet pack $(Build.SourcesDirectory)/src/Microsoft.OpenApi.YamlReader/Microsoft.OpenApi.YamlReader.csproj -o $(Build.ArtifactStagingDirectory) --configuration $(BuildConfiguration) --no-build --include-symbols --include-source /p:SymbolPackageFormat=snupkg + - pwsh: dotnet pack $(Build.SourcesDirectory)/src/Microsoft.OpenApi.YamlReader/Microsoft.OpenApi.YamlReader.csproj -o $(Build.ArtifactStagingDirectory) --configuration $(BuildConfiguration) --no-build --no-restore --include-symbols --include-source /p:SymbolPackageFormat=snupkg displayName: 'pack YamlReader' # Pack hidi - - pwsh: dotnet pack $(Build.SourcesDirectory)/src/Microsoft.OpenApi.Hidi/Microsoft.OpenApi.Hidi.csproj -o $(Build.ArtifactStagingDirectory) --configuration $(BuildConfiguration) --no-build --include-symbols --include-source /p:SymbolPackageFormat=snupkg + - pwsh: dotnet pack $(Build.SourcesDirectory)/src/Microsoft.OpenApi.Hidi/Microsoft.OpenApi.Hidi.csproj -o $(Build.ArtifactStagingDirectory) --configuration $(BuildConfiguration) --no-build --no-restore --include-symbols --include-source /p:SymbolPackageFormat=snupkg displayName: 'pack Hidi' - - task: EsrpCodeSigning@5 + - task: EsrpCodeSigning@6 displayName: 'ESRP CodeSigning Nuget Packages' inputs: ConnectedServiceName: 'Federated DevX ESRP Managed Identity Connection' @@ -212,7 +217,7 @@ extends: displayName: publish Hidi as executable inputs: command: 'publish' - arguments: -c Release --runtime win-x64 /p:PublishSingleFile=true /p:PackAsTool=false --self-contained --output $(Build.ArtifactStagingDirectory)/Microsoft.OpenApi.Hidi + arguments: -c Release --runtime win-x64 -p:RestoreConfigFile=$(Build.SourcesDirectory)\nuget.config /p:PublishSingleFile=true /p:PackAsTool=false --self-contained --output $(Build.ArtifactStagingDirectory)/Microsoft.OpenApi.Hidi projects: 'src/Microsoft.OpenApi.Hidi/Microsoft.OpenApi.Hidi.csproj' publishWebProjects: False zipAfterPublish: false @@ -252,7 +257,7 @@ extends: inputs: - input: pipelineArtifact artifactName: Nugets - targetPath: '$(Pipeline.Workspace)' + targetPath: '$(Pipeline.Workspace)/Nugets' dependsOn: [] environment: nuget-org strategy: @@ -264,10 +269,12 @@ extends: - task: 1ES.PublishNuget@1 displayName: 'NuGet push' inputs: - packagesToPush: '$(Pipeline.Workspace)/Microsoft.OpenApi.Hidi.*.nupkg' - packageParentPath: '$(Pipeline.Workspace)' + packagesToPush: '$(Pipeline.Workspace)/Nugets/Microsoft.OpenApi.Hidi.*.nupkg' + packageParentPath: '$(Pipeline.Workspace)/Nugets' nuGetFeedType: external publishFeedCredentials: 'OpenAPI Nuget Connection' + publishPackageMetadata: true + retryCountOnTaskFailure: 2 - deployment: deploy_lib condition: and(contains(variables['build.SourceBranch'], 'refs/tags/v'), succeeded()) @@ -277,7 +284,7 @@ extends: inputs: - input: pipelineArtifact artifactName: Nugets - targetPath: '$(Pipeline.Workspace)' + targetPath: '$(Pipeline.Workspace)/Nugets' dependsOn: [] environment: nuget-org strategy: @@ -287,7 +294,7 @@ extends: vmImage: ubuntu-latest steps: - pwsh: | - $fileNames = "$(Pipeline.Workspace)/Microsoft.OpenApi.Hidi.*.nupkg", "$(Pipeline.Workspace)/Microsoft.OpenApi.YamlReader.*.nupkg", "$(Pipeline.Workspace)/Microsoft.OpenApi.Workbench.*.nupkg" + $fileNames = "$(Pipeline.Workspace)/Nugets/Microsoft.OpenApi.Hidi.*.nupkg", "$(Pipeline.Workspace)/Nugets/Microsoft.OpenApi.YamlReader.*.nupkg", "$(Pipeline.Workspace)/Nugets/Microsoft.OpenApi.Workbench.*.nupkg" foreach($fileName in $fileNames) { if(Test-Path $fileName) { Remove-Item $fileName -Verbose @@ -297,10 +304,12 @@ extends: - task: 1ES.PublishNuget@1 displayName: 'NuGet push' inputs: - packagesToPush: '$(Pipeline.Workspace)/Microsoft.OpenApi.*.nupkg' - packageParentPath: '$(Pipeline.Workspace)' + packagesToPush: '$(Pipeline.Workspace)/Nugets/Microsoft.OpenApi.*.nupkg' + packageParentPath: '$(Pipeline.Workspace)/Nugets' nuGetFeedType: external publishFeedCredentials: 'OpenAPI Nuget Connection' + publishPackageMetadata: true + retryCountOnTaskFailure: 2 - deployment: deploy_yaml_reader condition: and(contains(variables['build.SourceBranch'], 'refs/tags/v'), succeeded()) @@ -310,7 +319,7 @@ extends: inputs: - input: pipelineArtifact artifactName: Nugets - targetPath: '$(Pipeline.Workspace)' + targetPath: '$(Pipeline.Workspace)/Nugets' dependsOn: deploy_lib environment: nuget-org strategy: @@ -322,10 +331,12 @@ extends: - task: 1ES.PublishNuget@1 displayName: 'NuGet push' inputs: - packagesToPush: '$(Pipeline.Workspace)/Microsoft.OpenApi.YamlReader.*.nupkg' - packageParentPath: '$(Pipeline.Workspace)' + packagesToPush: '$(Pipeline.Workspace)/Nugets/Microsoft.OpenApi.YamlReader.*.nupkg' + packageParentPath: '$(Pipeline.Workspace)/Nugets' nuGetFeedType: external publishFeedCredentials: 'OpenAPI Nuget Connection' + publishPackageMetadata: true + retryCountOnTaskFailure: 2 - deployment: create_github_release condition: and(contains(variables['build.SourceBranch'], 'refs/tags/v'), succeeded()) @@ -386,6 +397,9 @@ extends: scriptLocation: inlineScript inlineScript: | az acr login --name $(REGISTRY) + + - task: NuGetAuthenticate@1 + displayName: 'Authenticate Docker build to Azure Artifacts' - pwsh: | $content = [XML](Get-Content $(Pipeline.Workspace)/Directory.Build.props) @@ -471,27 +485,51 @@ extends: - bash: | echo "Building Docker image..." echo "Using build date: ${BUILDDATE}" + if [ -z "${VSS_NUGET_ACCESSTOKEN:-}" ]; then + echo "##vso[task.logissue type=error]VSS_NUGET_ACCESSTOKEN is not available. Ensure NuGetAuthenticate@1 ran successfully before docker build." + exit 1 + fi # Using quotes around tags to prevent flag interpretation docker buildx build \ --platform linux/amd64,linux/arm64/v8 \ --push \ + --build-arg VSS_NUGET_EXTERNAL_FEED_ENDPOINTS \ + --build-arg VSS_NUGET_URI_PREFIXES \ + --secret id=vss_nuget_accesstoken,env=VSS_NUGET_ACCESSTOKEN \ + --secret id=nuget_config,src="$(Pipeline.Workspace)/nuget.config" \ -t "$(REGISTRY)/$(IMAGE_NAME):nightly" \ -t "$(REGISTRY)/$(IMAGE_NAME):${VERSION}.${BUILDDATE}${RUNNUMBER}" \ "$(Pipeline.Workspace)" displayName: 'Build and Push Nightly Image' condition: eq(variables['Build.SourceBranch'], variables['PREVIEW_BRANCH']) + env: + VSS_NUGET_ACCESSTOKEN: $(VSS_NUGET_ACCESSTOKEN) + VSS_NUGET_EXTERNAL_FEED_ENDPOINTS: $(VSS_NUGET_EXTERNAL_FEED_ENDPOINTS) + VSS_NUGET_URI_PREFIXES: $(VSS_NUGET_URI_PREFIXES) - bash: | echo "Building Docker image for release..." - docker buildx build\ + if [ -z "${VSS_NUGET_ACCESSTOKEN:-}" ]; then + echo "##vso[task.logissue type=error]VSS_NUGET_ACCESSTOKEN is not available. Ensure NuGetAuthenticate@1 ran successfully before docker build." + exit 1 + fi + docker buildx build \ --platform linux/amd64,linux/arm64/v8 \ --push \ + --build-arg VSS_NUGET_EXTERNAL_FEED_ENDPOINTS \ + --build-arg VSS_NUGET_URI_PREFIXES \ + --secret id=vss_nuget_accesstoken,env=VSS_NUGET_ACCESSTOKEN \ + --secret id=nuget_config,src="$(Pipeline.Workspace)/nuget.config" \ -t "$(REGISTRY)/$(IMAGE_NAME):latest" \ -t "$(REGISTRY)/$(IMAGE_NAME):${VERSION}" \ "$(Pipeline.Workspace)" displayName: 'Build and Push Release Image' condition: contains(variables['Build.SourceBranch'], 'refs/tags/v') + env: + VSS_NUGET_ACCESSTOKEN: $(VSS_NUGET_ACCESSTOKEN) + VSS_NUGET_EXTERNAL_FEED_ENDPOINTS: $(VSS_NUGET_EXTERNAL_FEED_ENDPOINTS) + VSS_NUGET_URI_PREFIXES: $(VSS_NUGET_URI_PREFIXES) # once the nuget has been released, fill this form to get the public documentation updated. # https://dev.azure.com/msft-skilling/Content/_workitems/create/User%20Story?templateId=39fb91e3-64a2-4c8a-83db-b2bdf3603dd3&ownerId=c4a28f90-17ae-4384-b514-7273392b082b diff --git a/Dockerfile b/Dockerfile index 25f1ec589..f6aaacc2c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,22 @@ -FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build-env +# syntax=docker/dockerfile:1.2 +FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build-env WORKDIR /app +ARG VSS_NUGET_URI_PREFIXES +ARG VSS_NUGET_EXTERNAL_FEED_ENDPOINTS COPY ./src ./hidi/src COPY ./Directory.Build.props ./hidi/Directory.Build.props COPY ./README.md ./hidi/README.md WORKDIR /app/hidi -RUN dotnet publish ./src/Microsoft.OpenApi.Hidi/Microsoft.OpenApi.Hidi.csproj -c Release +RUN --mount=type=secret,id=vss_nuget_accesstoken,target=/run/secrets/vss_nuget_accesstoken,required=false \ + --mount=type=secret,id=nuget_config,target=/run/secrets/nuget_config,required=false \ + if [ -f /run/secrets/nuget_config ]; then \ + wget -qO- https://aka.ms/install-artifacts-credprovider.sh | bash && \ + VSS_NUGET_ACCESSTOKEN="$(cat /run/secrets/vss_nuget_accesstoken)" \ + dotnet publish ./src/Microsoft.OpenApi.Hidi/Microsoft.OpenApi.Hidi.csproj -c Release -p:RestoreConfigFile=/run/secrets/nuget_config; \ + else \ + dotnet publish ./src/Microsoft.OpenApi.Hidi/Microsoft.OpenApi.Hidi.csproj -c Release; \ + fi FROM mcr.microsoft.com/dotnet/runtime:8.0-jammy-chiseled AS runtime WORKDIR /app