Azure DevOps Pipeline create empty zip - azure

I would like to ask you how to solve a problem which I encountered during a creation of Azure pipeline.
Problem description:
Probably, "brick" responsible for building a project not create a bin folder so I finally get empty zip.
Despite of the fact all test were successfully completed(passed).
My yaml file:
trigger:
- main
pool:
vmImage: 'windows-latest'
variables:
solution: '**/*.sln'
buildPlatform: 'Any CPU'
buildConfiguration: 'Release'
steps:
- task: NuGetToolInstaller#1
- task: UseDotNet#2
inputs:
packageType: 'sdk'
version: '3.1.x'
- task: NuGetCommand#2
inputs:
restoreSolution: '$(solution)'
- task: DotNetCoreCLI#2
inputs:
command: 'build'
projects: '**/XXX.EvaluateFunction.csproj'
- task: ArchiveFiles#2
inputs:
rootFolderOrFile: '$(Build.BinariesDirectory)'
includeRootFolder: true
archiveType: 'zip'
archiveFile: '$(Build.ArtifactStagingDirectory)/Evaluate.zip'
replaceExistingArchive: true
- task: PublishBuildArtifacts#1
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactName: 'PortalArtifact'
publishLocation: 'Container'

According to the document about predefined variables: Build.BinariesDirectory is the local path on the agent you can use as an output folder for compiled binaries. Your yaml file does not use it as an output folder so that this folder is empty. You can use Build.BinariesDirectory as an output folder in .NET Core task: arguments: '--output $(Build.BinariesDirectory)'
Here is my complete sample:
trigger:
- main
pool:
vmImage: 'windows-latest'
variables:
solution: '**/*.csproj'
buildPlatform: 'Any CPU'
buildConfiguration: 'Release'
stages:
- stage: Build
jobs:
- job: Build
steps:
- task: DotNetCoreCLI#2
inputs:
command: 'restore'
projects: '**/*.csproj'
feedsToUse: 'select'
- task: DotNetCoreCLI#2
inputs:
command: 'build'
projects: '**/*.csproj'
arguments: '--configuration $(BuildConfiguration)'
- task: DotNetCoreCLI#2
inputs:
command: 'publish'
publishWebProjects: true
arguments: '--configuration $(BuildConfiguration) --output $(Build.BinariesDirectory)'
- task: ArchiveFiles#2
inputs:
rootFolderOrFile: '$(Build.BinariesDirectory)'
includeRootFolder: true
archiveType: 'zip'
archiveFile: '$(Build.ArtifactStagingDirectory)/Evaluate.zip'
replaceExistingArchive: true
- task: PublishBuildArtifacts#1
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactName: 'drop'
publishLocation: 'Container'
You can also refer to the sample about create your first .NET Core pipeline.

Related

how to use Devops Pipelines and Releases: Deploying One solution with 6 webjob console app as one zip file/package

My situation : I have 1 solution with 6 console apps.
My target : publish 6 console apps as 6 web jobs under 1 App service.
Summary :
6 consoleapps -->convert --> 6 dlls in 1 ZIP file --> Publish --> 6 webjobs in 1 App Service
How can I do that in Yaml?
azure-pipeline.yaml :
trigger:
- main
variables:
buildPlatform: 'Any CPU'
buildConfiguration: 'Release'
stages:
- stage: Build
displayName: 'Build stage'
pool:
vmImage: 'windows-latest'
jobs:
- job: BuildOrderShipmentJob
displayName: 'Build Order Shipment Job'
steps:
- checkout: self
displayName: 'checkout'
- task: NuGetToolInstaller#0
displayName: "NuGet use 6.3.0"
inputs:
versionSpec: 6.3.0
- task: NuGetCommand#2
displayName: 'nuget restore'
inputs:
command: 'restore'
restoreSolution: '**/*.sln'
feedsToUse: 'select'
- task: MSBuild#1
displayName: 'msbuild'
inputs:
solution: 'src/xxxxx/xxxxx.csproj'
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'
msbuildArguments: '/p:OutputPath=$(build.ArtifactStagingDirectory)/xxxxx-$(Build.BuildNumber)/App_Data/jobs/continuous/xxxxx'
- task: ArchiveFiles#2
displayName: 'package'
inputs:
rootFolderOrFile: '$(build.ArtifactStagingDirectory)/xxxxx-$(Build.BuildNumber)'
includeRootFolder: false
archiveType: 'zip'
archiveFile: '$(Build.ArtifactStagingDirectory)/xxxxx-$(Build.BuildNumber).zip'
replaceExistingArchive: true
- task: PublishBuildArtifacts#1
displayName: 'publish'
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)/xxxxx-$(Build.BuildNumber).zip'
ArtifactName: 'drop'
- stage: Test
displayName: 'Test stage'
pool:
vmImage: 'windows-latest'
jobs:
- job: TestOrderShipmentJob
displayName: 'Test Order Shipment Job'
steps:
- checkout: self
displayName: 'checkout'
- task: NuGetToolInstaller#0
displayName: "NuGet use 6.3.0"
inputs:
versionSpec: 6.3.0
- task: NuGetCommand#2
displayName: 'nuget restore'
inputs:
command: 'restore'
restoreSolution: '**/*.sln'
- task: VSBuild#1
displayName: 'vsbuild'
inputs:
solution: '**/*.sln'
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'
clean: true
- task: DotNetCoreCLI#2
displayName: 'dotnet test'
inputs:
command: test
arguments: '--collect:"XPlat Code Coverage" /p:CoverletOutputFormat=cobertura'
publishTestResults: true
workingDirectory: '$(System.DefaultWorkingDirectory)/src'
- task: PublishCodeCoverageResults#1
displayName: 'publish code coverage results'
inputs:
codeCoverageTool: 'Cobertura'
summaryFileLocation: '$(Agent.TempDirectory)/**/coverage.cobertura.xml'
- stage: Deploy_Test
displayName: 'Deploy test'
dependsOn: Test
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
pool:
name: 'bmersgtsteuw-app-eurotracs-pool'
jobs:
- deployment: BaukingOrderShipmentJob
displayName: 'Deploy Order Shipment Job'
environment: 'BME-CF-Test'
strategy:
runOnce:
deploy:
steps:
- download: current
artifact: drop
- task: AzureRMWebAppDeployment#4
inputs:
ConnectionType: AzureRM
azureSubscription: 'ARM-Con-BME-SUB-TST-EUW-APP'
appType: 'webApp'
WebAppName: 'xxxapptsteuw-app-tst'
package: '$(Pipeline.Workspace)/drop/xxxxx-$(Build.BuildNumber).zip'
removeAdditionalFilesFlag: true
- stage: Deploy_Prod
displayName: 'Deploy production'
dependsOn: Deploy_Test
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
pool:
name: 'xxxrsgprdeuw-app-tst-pool'
jobs:
- deployment: YYYYYOrderShipmentJob
displayName: 'Deploy Order Shipment Job'
environment: XXXX-CF-Prod
strategy:
runOnce:
deploy:
steps:
- download: current
artifact: drop
- task: AzureRMWebAppDeployment#4
inputs:
ConnectionType: AzureRM
azureSubscription: 'ARM-Con-XXXX-SUB-PRD-EUW-APP'
appType: 'webApp'
WebAppName: 'xxxappprdeuw-app-tst'
package: '$(Pipeline.Workspace)/drop/xxxxx-$(Build.BuildNumber).zip'
removeAdditionalFilesFlag: true
Based on your situation, you have 1 solution with 6 console apps.
6 consoleapps -->convert --> 6 dlls in 1 ZIP file --> Publish --> 6 webjobs in 1 App Service
To achieve your requirement, you can directly define the solution file and modify the msbuildArguments in Msbuild task.
For example:
- task: MSBuild#1
displayName: 'Build solution **/*.sln'
inputs:
solution: '**/*.sln'
platform: '$(BuildPlatform)'
configuration: '$(BuildConfiguration)'
msbuildArguments: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:DesktopBuildPackageLocation="$(build.artifactstagingdirectory)\WebApp.zip" /p:DeployIisAppPath="Default Web Site"'
Then the 6 console apps in 1 solution file will be built and the output will be saved at one zip file. So you can remove the ArchiveFiles task in YAML sample

No artifact Created during the CI in Azure DevOps

I am trying to create an Azure pipeline for a .NET core project. The build appears to complete with no errors but there is no artifact generated:
Here you can the warnings as well
The YAML definition is below, can anyone see what I'm doing wrong here
trigger:
branches:
include:
- release/*
paths:
include:
- Reeft/Organization/OrganizationService/*
- Reeft/Organization/OrganizationServicePipelines/organization-service-test.yml
pool:
vmImage: 'windows-2022'
variables:
solution: '**/*.sln'
buildPlatform: 'Any CPU'
buildConfiguration: 'Release'
projectName: '**/F11.Web.csproj'
runtime: 'win-x64'
steps:
- task: UseDotNet#2
displayName: 'Use .NET 5 SDK (preview)'
inputs:
packageType: 'sdk'
version: '5.0.100-rc.1.20452.10'
vsVersion: '16.8.0'
includePreviewVersions: true
- task: DotNetCoreCLI#2
inputs:
command: 'restore'
projects: '$(projectName)'
feedsToUse: 'select'
- task: DotNetCoreCLI#2
displayName: Build
inputs:
projects: '$(projectName)'
arguments: '--no-restore'
- task: DotNetCoreCLI#2
displayName: Test
inputs:
command: test
projects: '$(projectName)'
arguments: '-l "console;verbosity=detailed"'
- task: DotNetCoreCLI#2
displayName: 'Publish WebApi'
inputs:
command: publish
publishWebProjects: false
projects: '$(projectName)'
arguments: '--configuration $(BuildConfiguration) --output $(Build.ArtifactStagingDirectory) --runtime -r $(runtime)'
- task: CopyFiles#2
inputs:
Contents: '**'
TargetFolder: '$(Build.ArtifactStagingDirectory)'
To generate artifacts you need to add appropriate task Publish Build Artifacts task:
# Publish build artifacts
# Publish build artifacts to Azure Pipelines or a Windows file share
- task: PublishBuildArtifacts#1
inputs:
#pathToPublish: '$(Build.ArtifactStagingDirectory)'
#artifactName: 'drop'
#publishLocation: 'Container' # Options: container, filePath
#targetPath: # Required when publishLocation == FilePath
#parallel: false # Optional
#parallelCount: # Optional
#fileCopyOptions: #Optional
#storeAsTar: false # Optional

CI-CD Azure devops for function app deployment

My Function app Name:
my_func_dev_app
Functions I have in my project
func_dev
func_prd
Push func_dev to my_func_dev_app
Push func_prd to my_func_prd_app
But It is pushing both func_dev and func_prd to my_func_de_app
My app folder structure
(folder)myapp_function
(folder)func_dev --__init__.py
-- function.json
(folder)func_prd --__init__.py
-- function.json
task.py
Multi stage Pipeline:
#pipelines1
trigger:
- '*'
stages:
- stage: 'Build'
displayName: 'Build the web application'
jobs:
- job: 'Build'
displayName: 'Build job'
pool:
name: 'onprem_agent'
steps:
- task: CopyFiles#2
displayName: 'Copy Files to: $(Build.ArtifactStagingDirectory)'
inputs:
SourceFolder: '$(Build.SourcesDirectory)'
Contents: |
**/*
!.git/**
OverWrite: true
CleanTargetFolder: true
TargetFolder: '$(Build.ArtifactStagingDirectory)'
- task: ArchiveFiles#2
displayName: "Archive files"
inputs:
rootFolderOrFile: '$(Build.ArtifactStagingDirectory)/myapp_function'
includeRootFolder: false
archiveFile: '$(Build.ArtifactStagingDirectory)/build$(Build.BuildId).zip'
- task: PublishBuildArtifacts#1
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactName: 'myapp_function'
- stage: 'DEV_AZURE'
displayName: 'Az DEV Deploy'
dependsOn: Build
condition: |
and
(
succeeded(),
eq(variables['Build.SourceBranchName'], variables['releaseBranchName'])
)
jobs:
- deployment: Deploy
environment: dev
variables:
- group: Release
strategy:
runOnce:
deploy:
steps:
- download: current
artifact: myapp_function
displayName: Downloading artifacts
- task: AzureFunctionApp#1
inputs:
azureSubscription: CI-CD
appType: functionAppLinux
appName: my_func_dev_app
package: '$(Pipeline.Workspace)/myapp_function/*.zip'
deployToSlotOrASE: true
resourceGroupName: my-rg
slotName: PRODUCTION
displayName: 'Deploying dev'
How to fix? Push func_dev to my_func_dev_app and ignore func_prd
How to fix? Push func_dev to my_func_dev_app and ignore func_prd
To solve this issue, you can package your two projects separately into zip.
In your ArchiveFiles task, you need to specify a specific project.
For example:
For func_dev project: $(Build.ArtifactStagingDirectory)/myapp_function/func_dev
- task: ArchiveFiles#2
displayName: "Archive files"
inputs:
rootFolderOrFile: '$(Build.ArtifactStagingDirectory)/myapp_function/func_dev'
includeRootFolder: false
archiveFile: '$(Build.ArtifactStagingDirectory)/build$(Build.BuildId)-func_dev.zip'
Then you can only package the project corresponding to the function app name.
If you want to deploy two projects to the corresponding function app in one pipeline at the same time, you could use the same method to separately package the two projects as zip.

Produced artifact has too many layers of folders

I have the following pipeline that builds a ASP.NET Core 5 Web project, but the artifact produced has the following structure
ProjectName.zip
Content
D_C
a
1
s
ProjectName
obj
release
package
PackageTmp
(Finally The actual content) as it should be
archive.xml
parameters.xml
systeminfo.xml
I simply want my zip to be the content of packagetmp without any parent folders
trigger:
- master
pool:
vmImage: 'windows-latest'
variables:
solution: '**/*.sln'
buildPlatform: 'Any CPU'
buildConfiguration: 'Release'
steps:
- task: NuGetToolInstaller#1
- task: NuGetCommand#2
inputs:
command: 'restore'
restoreSolution: '**/*.sln'
feedsToUse: 'select'
vstsFeed: ''myfeed'
- task: VSBuild#1
inputs:
solution: '$(solution)'
msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactStagingDirectory)"'
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'
- task: VSTest#2
inputs:
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'
- task: PublishBuildArtifacts#1
displayName: "Upload Artifacts"
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
You can change the msbuildArgs as below to generate the artifacts as files instead of a zip file. And then you can use Archive files task to zip the artifacts. See below:
- task: VSBuild#1
inputs:
solution: '$(solution)'
msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=FileSystem /p:publishUrl="$(build.artifactstagingdirectory)" /p:PackageAsSingleFile=false /p:SkipInvalidConfigurations=true'
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'
The msbuildArgs in above example will output the artifacts to folder $(build.artifactstagingdirectory) unzipped.
Then after VSBuild Task. You can add Archive files task to zip the artifacts:
- task: ArchiveFiles#2
displayName: 'Archive task'
inputs:
rootFolderOrFile: '$(Build.ArtifactStagingDirectory)/'
includeRootFolder: false
archiveFile: '$(Build.ArtifactStagingDirectory)/Temp/ProjectName.zip'
Above example will zip the artifacts in $(Build.ArtifactStagingDirectory), and save the zip file in $(Build.ArtifactStagingDirectory)/Temp/ProjectName.zip
Then in the PublishBuildArtifacts task. Set the PathtoPublish to folder $(Build.ArtifactStagingDirectory)/Temp
- task: PublishBuildArtifacts#1
displayName: "Upload Artifacts"
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)/Temp'
You should get a zip file with the content of packagetmp only.

Extra Artifact published when using templates

Currently started using global templates in the majority of my pipelines and there is an issue occurring where an empty artifact is getting published in addition to the original artifact.
This is causing minor issues with some of my deployment groups (workaround is to just ignore it when downloading). While it is not causing major issues, I'm just curious about why the extra file is being published as well as preventing it.
EDIT:
Included my yaml template being used as:
parameters:
ArtifactPath: ''
ArtifactName: ''
ArtifactPublish: false
Artifacts: []
Solution: '**/*.sln'
jobs:
- job: Build
displayName: 'Build, Pack, and Publish'
pool:
vmImage: 'windows-latest'
variables:
solution: ${{ parameters.Solution }}
buildPlatform: 'Any CPU'
buildConfiguration: 'Release'
prereleaseVersion: '$(majorVersion).$(minorVersion).$(Build.BuildNumber)-$(Build.SourceBranchName)'
releaseVersion: '$(majorVersion).$(minorVersion).$(Build.BuildNumber)'
steps:
- task: NuGetToolInstaller#1
displayName: "Install Nuget Tool"
- task: NuGetCommand#2
displayName: 'Restore Nuget Packages'
inputs:
command: 'restore'
restoreSolution: '$(solution)'
feedsToUse: 'select'
vstsFeed: 'FEED'
- task: VSBuild#1
displayName: 'Build Solution'
inputs:
solution: '$(solution)'
msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(Build.ArtifactStagingDirectory)"'
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'
- task: VSTest#2
displayName: 'Run Unit Tests'
inputs:
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'
- task: NuGetCommand#2
displayName: 'Pack Prerelease Nuget Packages'
condition: and(succeeded(), ne(variables['Build.SourceBranch'], 'refs/heads/master'), ne(variables['Build.SourceBranch'], 'refs/heads/release'))
inputs:
command: 'pack'
configuration: '$(buildConfiguration)'
packagesToPack: '**/nuspec/*.nuspec'
versioningScheme: 'byEnvVar'
versionEnvVar: prereleaseVersion
verbosityPack: 'detailed'
- task: NuGetCommand#2
displayName: 'Push Prerelease Nuget Packages'
condition: and(succeeded(), ne(variables['Build.SourceBranch'], 'refs/heads/master'), ne(variables['Build.SourceBranch'], 'refs/heads/release'))
inputs:
command: 'push'
packagesToPush: '$(Build.ArtifactStagingDirectory)/**/*.nupkg'
nuGetFeedType: 'internal'
publishVstsFeed: 'FEED'
verbosityPush: 'normal'
- task: NuGetCommand#2
displayName: 'Pack Release Nuget Packages'
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/release'))
inputs:
command: 'pack'
configuration: '$(buildConfiguration)'
packagesToPack: '**/nuspec/*.nuspec'
versioningScheme: 'byEnvVar'
versionEnvVar: releaseVersion
verbosityPack: 'detailed'
- task: NuGetCommand#2
displayName: 'Push Release Nuget Packages'
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/release'))
continueOnError: true
inputs:
command: 'push'
packagesToPush: '$(Build.ArtifactStagingDirectory)/**/*.nupkg'
nuGetFeedType: 'internal'
publishVstsFeed: 'FEED'
verbosityPush: 'detailed'
- task: PublishSymbols#2
displayName: 'Publish Symbols to Symbol Server'
inputs:
SearchPattern: '**/bin/**/*.pdb'
SymbolServerType: 'TeamServices'
- ${{ if eq(parameters.ArtifactPublish, true) }}:
- ${{ each artifact in parameters.Artifacts }}:
- task: CopyFiles#2
displayName: 'Copy .artifactignore: ${{ artifact.ArtifactPath }}'
inputs:
SourceFolder: '$(Build.SourcesDirectory)'
Contents: '.artifactignore'
TargetFolder: '$(Build.SourcesDirectory)/${{ artifact.ArtifactPath }}'
- ${{ each artifact in parameters.Artifacts }}:
- task: PublishPipelineArtifact#1
displayName: 'Publish Artifact: ${{ artifact.ArtifactName }}'
inputs:
targetPath: '$(Build.SourcesDirectory)/${{ artifact.ArtifactPath }}'
artifactName: '${{ artifact.ArtifactName }}'
Yaml file that consumes it:
trigger:
- release
- development
- master
- feature/*
- task/*
resources:
repositories:
- repository: templates
name: Project/Repo-Name
type: git
ref: refs/heads/release
variables:
# This is the version displayed in package manager (Major.Minor.BuildNumber)
majorVersion: 1
minorVersion: 1
jobs:
- template: Templates/build.yml#templates
parameters:
Solution: 'SolutionName'
ArtifactPublish: true
Artifacts:
- ArtifactPath: 'bin/directory/$(buildConfiguration)'
ArtifactName: 'ArtifactName'
You have one Publish Symbols task in your template, this task will publish symbols to the symbol server in Azure Artifacts with a random name. That's why we can see the extra artifact in Published tab, it's expected behavior when using PublishSymbols#2 task.
I'm just curious about why the extra file is being published as well
as preventing it.
It's not recommended to disable or remove the Publish Symbols step though it helps to remove the artifact. This task is quite important for some scenarios where you want to have the ability to debug the published nuget packages, check my another similar issue. So my suggestion is just ignoring it~

Resources