I would like to have a pull request launch a build and that build must succeed before merging into the target branch is allowed.
I have master and develop branch and create feature branches from develop. work is completed and then a pull request initiated to merge back into develop.
I have created a build pipeline that completes successfully when run manually.
I have specified in the branch policies for the develop branch that the build must be run and complete successfully.
Now when I create a pull request, it says that in order for the pull request to be approved, the build must run but it does not run the build. What am I doing wrong?
This is a c# .net framework app.
Should I be saving the yaml in the develop branch or master? That part confuses me. Is the trigger correct?
This is my yaml for the build pipeline:
trigger:
- develop
pool:
vmImage: 'windows-latest'
name: '1.0.1.$(Rev:r)'
variables:
solution: '**/*.sln'
buildPlatform: 'Any CPU'
buildConfiguration: 'Release'
steps:
- checkout: git://OvaFlow/Utilities#develop
- task: NuGetToolInstaller#0
displayName: 'Use NuGet 4.4.1'
inputs:
versionSpec: 4.4.1
- task: VersionAssemblies#2
inputs:
Path: '$(Build.SourcesDirectory)'
VersionNumber: '$(Build.BuildNumber)'
InjectVersion: true
FilenamePattern: 'AssemblyInfo.*'
OutputVersion: 'OutputedVersion'
- task: NuGetCommand#2
displayName: 'NuGet restore'
inputs:
restoreSolution: '$(Build.SourcesDirectory)/Utilities/packages.config'
feedsToUse: config
nugetConfigPath: '$(Build.SourcesDirectory)/NuGet.config'
restoreDirectory: '$(Build.SourcesDirectory)/packages'
- task: NuGetCommand#2
displayName: 'NuGet restore'
inputs:
restoreSolution: '$(Build.SourcesDirectory)/UtilitiesTests/packages.config'
feedsToUse: config
nugetConfigPath: '$(Build.SourcesDirectory)/NuGet.config'
restoreDirectory: '$(Build.SourcesDirectory)/packages'
- task: VSBuild#1
displayName: 'Build solution **\*.sln'
inputs:
solution: '$(Build.SourcesDirectory)/Utilities.sln'
platform: '$(BuildPlatform)'
configuration: '$(BuildConfiguration)'
- task: VSTest#2
displayName: 'VsTest - testAssemblies'
inputs:
testAssemblyVer2: |
**\$(BuildConfiguration)\*test*.dll
!**\obj\**
codeCoverageEnabled: true
platform: '$(BuildPlatform)'
configuration: '$(BuildConfiguration)'
continueOnError: true
- task: PublishSymbols#2
displayName: 'Publish symbols path'
inputs:
SearchPattern: '**\bin\**\*.pdb'
PublishSymbols: false
continueOnError: true
- task: CopyFiles#2
displayName: 'Copy Files to: $(build.artifactstagingdirectory)'
inputs:
SourceFolder: '$(system.defaultworkingdirectory)'
Contents: '**\bin\$(BuildConfiguration)\**'
TargetFolder: '$(build.artifactstagingdirectory)'
condition: succeededOrFailed()
- task: PublishBuildArtifacts#1
displayName: 'Publish Artifact: drop'
inputs:
PathtoPublish: '$(build.artifactstagingdirectory)'
condition: succeededOrFailed()
Should I be saving the yaml in the develop branch or master? That part confuses me. Is the trigger correct?
The answer is yes! In fact, you have already found the answer.
As we know from the Build validation:
Set a policy requiring changes in a pull request to build successfully
with the protected branch before the pull request can be completed.
Build policies reduce breaks and keep your test results passing. Build
policies help even if you're using continuous integration (CI) on your
development branches to catch problems early.
So, the build validation used for the branches which you want to protected, the .yml should saved in the branch which you set the build policy.
As test, if I set the .yml file under the Test branch, then pull request for the dev branch, the build will not be triggered automatically:
Then, I moved the .yml file to the dev branch with a new build pipeline, it works fine:
Hope this helps.
If build is not configured to run automatically on push, you have to run it manually, here:
Or you can configure build to trigger automatic on branch update:
Related
How can I trigger my build on Azure DevOps using YAML file?
I did a merge on my master branch. Build was tiggered.
Then I did a pull request from master to
release/development
release/staging
release/production
in this order. Only the merge on release/production triggered the build.
Why? To make sure it is not just a question of the correct version of the YAML file on the correct branch I repeated these actions a second time. Same result.
# ASP.NET
# Build and test ASP.NET projects.
# Add steps that publish symbols, save build artifacts, deploy, and more:
# https://learn.microsoft.com/azure/devops/pipelines/apps/aspnet/build-aspnet-4
trigger:
branches:
include:
- master
- release/production
- release/development
- release/staging
pool:
name: Hosted VS2017
demands:
- msbuild
- visualstudio
- vstest
name: $(Date:yy).$(Date:MM).$(Rev:r)
variables:
buildPlatform: 'Any CPU'
buildConfiguration: 'Release'
steps:
- task: NuGetToolInstaller#1
displayName: 'Use NuGet 4.4.1'
inputs:
versionSpec: 4.4.1
- task: NuGetCommand#2
displayName: 'NuGet restore'
inputs:
restoreSolution: $(Solution)
- 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: 'Test Assemblies'
inputs:
testAssemblyVer2: |
**\$(BuildConfiguration)\*test*.dll
!**\obj\**
platform: '$(BuildPlatform)'
configuration: '$(BuildConfiguration)'
diagnosticsEnabled: True
- task: PublishSymbols#2
displayName: 'Publish symbols path'
inputs:
SearchPattern: '**\bin\**\*.pdb'
PublishSymbols: false
continueOnError: true
- task: PublishBuildArtifacts#1
displayName: 'Publish Artifact'
inputs:
PathtoPublish: '$(build.artifactstagingdirectory)'
ArtifactName: '$(Parameters.ArtifactName)'
condition: succeededOrFailed()
Why the master and production build are starting and not the other one?
Check if you have set the trigger on the web UI for the build pipeline. The triggers set on the web UI will override that set in the YAML files.
If the triggers set on the web UI only includes the master and release/production branches, the pipeline will only be triggered for the two branches.
To avoid this, you can disable the triggers set on the web UI and only keep the triggers set in the YAML files.
Did you merge yaml to other branches? The build may not start if it is not in a branch. An example of the development branch:
Within our company we build and release a lot through DevOps for .NET Core applications.
For these application our setup is to have a single pipeline that builds the artifact and then the release pipeline manages pushing this same artifact out through the various stages (test / uat / staging / live)
The advantages we see here is that the package is the same and it is just environment variables on the deployment target that allow for variation in how it runs such as different 3rd party endpoints, different database etc.
We are now looking to move a Vue.js application which is built using Webpack into DevOps for automating the builds and deployments too, but here is where we are in a conundrum.
We need to encapsulate the same variation in our solutions (different api, configs, etc), this is currently managed by doing npm run build:uat, npm run build:live etc.
This works fine, but means we would need to setup different builds for each environment and loose the reassurance the the package we have put out for UAT is consistent with the release we put out for Live.
Are there any best practises around managing builds like this?
Possible options I can see, although open to others:
Build test / uat / live at the same time and then selectively copy the right code for the right environment
Different builds for each release
Can we have a single artifact build and then swap out the configuration variable in some other way?
Any support or advice would be appreciated.
Option 2 should be the simplest solution to understand and operate.
Do not need to keep using a single artifact. A release can be configured to trigger off of multiple artifact sources (builds). Then simply combine multiple builds in one release.
You could create a task which add a label to the current build if there is no other build running/queued.
Additionally add a tag condition for the release trigger.
More details please take a look at boindiil's answer in this link: Combine multiple builds into one release
We ended up going down the following route. We would ideally have had a single build but as the build for each environment is done at the same time from the same npm install install etc I'm happy with this as a compromise.
trigger:
- release/*
variables:
- template: config/app-names.yml
pool:
vmImage: 'ubuntu-latest'
steps:
- task: NodeTool#0
inputs:
versionSpec: '12.x'
displayName: 'Install Node.js'
- script:
npm install
displayName: 'npm install'
- script:
npm run build:test -- --vn "$(Build.SourceBranchName)" --n "$(Build.RequestedFor)"
displayName: 'npm build test'
- task: ArchiveFiles#2
displayName: 'Archive test'
inputs:
rootFolderOrFile: 'dist/$(TestAppName)'
includeRootFolder: true
archiveType: 'zip'
archiveFile: 'dist/test/$(TestAppName).zip'
replaceExistingArchive: true
- script:
npm run build:acc -- --vn "$(Build.SourceBranchName)" --n "$(Build.RequestedFor)"
displayName: 'npm build acc'
- task: ArchiveFiles#2
displayName: 'Archive acc'
inputs:
rootFolderOrFile: 'dist/$(AccAppName)'
includeRootFolder: true
archiveType: 'zip'
archiveFile: 'dist/acc/$(AccAppName).zip'
replaceExistingArchive: true
- script:
npm run build:live -- --vn "$(Build.SourceBranchName)" --n "$(Build.RequestedFor)"
displayName: 'npm build live'
- task: ArchiveFiles#2
displayName: 'Archive live'
inputs:
rootFolderOrFile: 'dist/$(LiveAppName)'
includeRootFolder: true
archiveType: 'zip'
archiveFile: 'dist/live/$(LiveAppName).zip'
replaceExistingArchive: true
- task: PublishBuildArtifacts#1
displayName: 'Publish test build'
inputs:
PathtoPublish: 'dist/test/'
ArtifactName: 'test'
publishLocation: 'Container'
- task: PublishBuildArtifacts#1
displayName: 'Publish acc build'
inputs:
PathtoPublish: 'dist/acc/'
ArtifactName: 'acc'
publishLocation: 'Container'
- task: PublishBuildArtifacts#1
displayName: 'Publish live build'
inputs:
PathtoPublish: 'dist/live/'
ArtifactName: 'live'
publishLocation: 'Container'
This will build successfully after I have completed a PR, but it's not building as part of the validation of the PR. Also, for some reason when I create a new release from the dev branch, it's not triggering a build there either (and thus one of the conditions I have where it builds on a release branch, it's not creating the artifact for my release pipeline).
The current build validation I have for my branch policy on both Dev and my Releases/* branch
My Azure Pipeline for the API:
trigger:
branches:
include:
- Dev
- Releases/*
paths:
include:
- MCR.API/*
jobs:
- job: api
variables:
configuration: release
pool:
vmImage: 'vs2017-win2016'
steps:
- task: DotNetCoreCLI#2
displayName: Restore
inputs:
command: restore
projects: '**/*API.csproj'
- task: DotNetCoreCLI#2
displayName: Build
inputs:
command: build
projects: '**/*API.csproj'
- task: DotNetCoreCLI#2
displayName: Publish API
inputs:
command: publish
publishWebProjects: false
projects: '**/*API.csproj'
arguments: '--output $(build.artifactstagingdirectory) --configuration $(configuration)'
zipAfterPublish: True
- task: PublishBuildArtifacts#1
displayName: 'Publish API Artifact'
condition: and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/heads/Releases/'))
inputs:
PathtoPublish: '$(build.artifactstagingdirectory)'
artifactName: 'API'
I am wanting this to force a PR to dev and Releases/* to have a successful build before it can be completed (it's not doing that). I want it to build after the PR is completed (it IS doing that). I want it to build when a new Release in the Releases/* branch is created (it's not doing that).
So the answer to this problem was rather simple...
In the build validation policy, make sure you have a leading slash in front of your directory - even though you don't need one in your yaml pipelines file.
So far example I changed this:
MCR.API/*
MCR/*
MCR.Admin/*
To:
/MCR.API/*
/MCR/*
/MCR.Admin/*
And everything worked as I wanted.
I need to deploy an Asp.Net Core Application to Azure WebApp using Azure Devops.
I have the following working Azure-Pipelines YAML file:
trigger:
- master
variables:
buildConfiguration: 'Release'
buildPlatform: 'any cpu'
version: '0.2.0'
stages:
- stage: 'Stage1'
jobs:
# Previous Jobs like Build, Test, ...
- job: 'Publish'
pool:
vmImage: 'Ubuntu-16.04'
dependsOn: 'Test'
steps:
- task: DotNetCoreCLI#2
displayName: 'Publish'
inputs:
command: publish
publishWebProjects: false
projects: '**/*.csproj'
arguments: '--configuration $(BuildConfiguration) --output $(build.artifactstagingdirectory)'
zipAfterPublish: true
- task: PublishBuildArtifacts#1
displayName: 'Artifact'
inputs:
PathtoPublish: '$(build.artifactstagingdirectory)'
- task: AzureRmWebAppDeployment#4
displayName: 'Deploy'
inputs:
package: '$(build.artifactstagingdirectory)/App.Api.zip'
azureSubscription: 'MyName.Azure'
appType: 'Web App On Windows'
webAppName: 'myname-api'
This works fine but I would like to use the new Deployment Job.
I removed the 'Deploy' task and added it as a new Deployment Job after the 'Publish' job:
- deployment: DeployJob
dependsOn: 'Publish'
pool:
vmImage: Ubuntu-16.04
environment: production
strategy:
runOnce:
deploy:
steps:
- task: AzureRmWebAppDeployment#4
inputs:
package: '$(build.artifactstagingdirectory)/App.Api.zip'
azureSubscription: 'MyName.Azure'
appType: 'Web App On Windows'
webAppName: 'myname-api'
You can see that the 'AzureRmWebAppDeployment#4' is the same as before.
But now I get the following error when I run the pipeline:
Download artifact to: /home/vsts/work/1/
Could not find any pipeline artifacts in the build.
What am I missing? How to fix this?
I've struggled with this all day myself, until stumbling into a solution. It seems there are a few default "helper" tasks that get bundled into the jobs, and the deployment jobs have a default download task that gets added. I'm still not sure what it was trying to download in my case, but it was causing the same problem you describe.
Try adding a - download: none task to your deployment job's steps, and specifying the tasks explicitly instead. Something like this should work:
- stage: deploy_dev
displayName: Development environment
jobs:
- deployment: Deploy
displayName: Deploy to Development environment
environment: myproject-dev
pool:
vmImage: ubuntu-16.04
strategy:
runOnce:
deploy:
steps:
- download: none
- task: DownloadBuildArtifacts#0
inputs:
artifactName: $(ArtifactName)
buildType: 'current'
downloadType: 'single'
downloadPath: '$(System.ArtifactsDirectory)'
Documentation for the download shortcut can be found here: https://learn.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema#download
Hope that helps!
you need use PublishPipelineArtifact#1 instead of PublishBuildArtifacts#1 if you split the deployment. I was struggling this issue a whole day, hope this can help u.
# - task: PublishBuildArtifacts#1
- task: PublishPipelineArtifact#1
displayName: Publish pipeline Artifacts
inputs:
pathtoPublish: '$(Pipeline.Workspace)'
artifactName: 'coreapidemo'
Try using $(Pipeline.Workspace) instead.
You should also do what #wenbo wrote in his answer but I think it's not required, the important part here is $(Pipeline.Workspace):
By default, files are downloaded to $(Pipeline.Workspace)/{artifact}, where artifact is the name of the artifact. The folder structure of the artifact is always preserved.
source
It looks like you're trying to deploy before you publish an artifact.
dependsOn: 'Publish'
You need to publish the artifact first. This is the step you have called Artifact.
I'd also expect that the package path you have, $(build.artifactstagingdirectory)/App.Api.zip, won't work. It's probably going to be somewhere under $(System.DefaultWorkingDirectory).
It seems that the format is not correct in your yaml.
dependsOn: 'Publish'
You may try to use following instead.
dependsOn: Publish
Here the dependency should be a job object, not a string. In the expression, if the value is string, it must be single-quoted. Please refer to this document.
I want to create packages to load to the store.
Here is the YAML so far
trigger:
- master
pool:
vmImage: 'VS2017-Win2016'
variables:
solution: '**/*.sln'
buildPlatform: 'x64'
buildConfiguration: 'Release'
appxPackageDir: '$(build.artifactStagingDirectory)\AppxPackages\\'
steps:
- task: NuGetToolInstaller#0
- task: NuGetCommand#2
inputs:
restoreSolution: '**\*.sln'
feedsToUse: config
nugetConfigPath: 'MyApp.Win10/mynuget.config'
- task: VSBuild#1
inputs:
platform: 'x64'
solution: '**\*.sln'
configuration: '$(buildConfiguration)'
msbuildArgs: '/p:AppxBundlePlatforms="$(buildPlatform)" /p:AppxPackageDir="$(appxPackageDir)" /p:AppxBundle=Always /p:UapAppxPackageBuildMode=StoreUpload'
The docs mention the Artifacts explorer on the Artifacts tab of the builds results page. But I cant find it.
I have also looked at the Artifacts in the project but they only contain some nuget packages I put there.
You don't see the artifacts becuase you don't have the "Publish Build Artifacts" task.
For example, add this task:
- task: PublishBuildArtifacts#1
inputs:
pathtoPublish: '$(appxPackageDir)'
artifactName: 'drop'