Azure Dev Ops CICD copy publish not working as expected - azure

I have the following YAML in my build pipeline.
#Step 3, Copy Files
- task: CopyFiles#2
inputs:
#SourceFolder: '$(Build.SourcesDirectory)'
Contents: '**'
TargetFolder: '$(Build.ArtifactStagingDirectory)'
CleanTargetFolder: true
OverWrite: true
#Step 4, Publish artifacts
- task: PublishBuildArtifacts#1
inputs:
TargetPath: '$(Build.ArtifactStagingDirectory)'
I have a seperate release pipeline, which is attempting to deploy these files to an Azure Function App. However once this completes, the functions are missing. Using KUDU I can see the files have made their way up, however I think something is configured incorrectly.
This is what the artifact structure looks like when I browse for a 'Package or Folder', which to me seems incorrect.
Can anyone advise why my artifacts are not being produced in the format required for a function app?

From you screenshot about artifacts content, it seems that you are directly packaging and publishing your project to Azure Function.
As far as I know, you should be missing the Build step.
You first need to add a build step according to your project type, and then deploy the built product to Azure function.
For more detailed info, you can refer to this doc: Deploy an Azure Function

Related

Azure YAML Pipeline: deploy to Function App without overwriting existing function

I have one Function App, already created in Azure, to which I need to deploy two separate Azure Functions hosted in different repos:
(A) HttpTrigger
(B) QueueTrigger
I would like to do this using a YAML pipeline.
Each Azure Function has its separate YAML pipeline, but every time I run pipeline B, the deployment works ok but function A is overwritten by function B.
Is there a way to keep both?
Below is the deployment to DEV, which appears in both pipelines. I thought there was a flag to say "don't delete anything you find deployed", but there isn't.
What am I missing?
#Deploy to DEV
- stage: DEV
displayName: Deploy to DEV
dependsOn: Build
variables:
- group: my-dev-variables
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/dev'))
jobs:
- job: Deploy
steps:
#Download artifact to make it available to this stage
- task: DownloadPipelineArtifact#2
inputs:
source: 'current'
path: '$(Pipeline.Workspace)'
#Deploy
- task: AzureFunctionApp#1
displayName: Deploy Linux function app
inputs:
azureSubscription: $(azureRmConnection.Id)
appType: 'functionAppLinux'
appName: $(functionAppName)
package: '$(Pipeline.Workspace)/**/*.zip'
deploymentMethod: auto
I’m not sure how projects are structured in Python, but I think what you are trying to do is not possible by having separate repos that you deploy from. However, you should be able to achieve what you want by adding the both functions to the same project and then deploy them from the same repo.
Depending on the app service plan you are running (and your needs), you could also consider having two separate function apps and run them both on the same app service plan.

Azure DevOps: Why does the DotNetCoreCLI#2 task not publish (zip) my Azure Functions project?

I have a .NET Core 3.1 solution that contains 2 Web Application projects. I am using Azure DevOps Pipelines for CI/CD and so I have the build-test-publish steps defined in an azure-pipelines.yml file.
The task that I am using to package the products of my two web application projects is fairly standard and based on the DotNetCoreCLI#2 task:
- task: DotNetCoreCLI#2
inputs:
command: publish
publishWebProjects: True
arguments: '--configuration $(BuildConfiguration) --output $(Build.ArtifactStagingDirectory)'
zipAfterPublish: True
So far so good. This step creates two zip files, one for each web application.
But, having added a new Azure Functions project to my solution, its products are not zipped in the same way. As a result, I am unable to deploy it to Azure.
I guess the task defaults to only publishing Web Application projects. How can I make it also work on my Azure Functions project?
It seems that when one sets publishWebProjects to True, as I have, then the publish command for DotNetCoreCLI#2 will only publish web application projects. Which, I now come to realize, is rather obvious.
The solution I've found for my need is to set publishWebProjects to False and also add projects: '**/*.csproj'.
- task: DotNetCoreCLI#2
inputs:
command: publish
publishWebProjects: False
projects: '**/*.csproj'
arguments: '--configuration $(BuildConfiguration) --output $(Build.ArtifactStagingDirectory)'
zipAfterPublish: True
Now the task creates a zip file for every project in my solution. This includes a few test projects, but I don't mind. If one does mind, one could likely list only the specific projects to be zipped in the projects attribute.

Azure DevOps Repo to Azure Static HTML CI/CD Pipeline

I have a static HTML website hosted in Azure Storage using the static HTML feature. I'm using Azure DevOps Git Repo as my source control.
Currently I'm manually pushing changed files Azure Storage, but would like to automate the task. The trigger would be when the master branch is updated then it should update the Azure Storage account ($web folder).
I was looking at Pipelines and started using the wizard and selected my repo. I saw the first option for "Configure your pipeline" was called HTML - Archive your static HTML project and save it with the build record.
It produces this YAML:
# HTML
# Archive your static HTML project and save it with the build record.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml
trigger:
- master
pool:
vmImage: 'ubuntu-latest'
steps:
- task: ArchiveFiles#2
inputs:
rootFolderOrFile: '$(build.sourcesDirectory)'
includeRootFolder: false
- task: PublishBuildArtifacts#1
Questions:
Is this the right template to start with to accomplish what I'm trying to do? If yes, what do I need to add/modify to accomplish my goal?
Is there another approach to accomplish my goal?
You're on the right path. You will need to update your inputs to be similar to:
inputs:
rootFolderOrFile: ‘$(Build.SourcesDirectory)/dist’
archiveType: ‘zip’
archiveFile: ‘$(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip’
replaceExistingArchive: true
There's also a blog out there that you can reference for this:
https://medium.com/#matthewleak/deploying-a-static-website-to-azure-storage-using-azure-devops-fa0bed457d07

Azure Devops - Clean Destination Directory Before Deployment

I have a Azure Devops build step like so:
- task: PublishBuildArtifacts#1
displayName: 'Publish Artifact: drop'
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)\ArtifactsToBePublished'
The publish step just deploys the app on top of what is currently in the directory, but in the meantime the entire app structure may have changed. Is there any way to clear the destination directory before the publish step takes place?
PublishBuildArtifact doesn't do what you think it does. All it does it takes the files in the path you specify, uploads them to Azure DevOps, and attaches them to the build so that they can be downloaded and consumed in other pipelines.
So basically the premise of your question is faulty, as there is nothing to clear.

Defining which project should be deployed to an Azure Functions app from source control

We have a collection of Azure Function Apps in c# net core. Each App contains a small number of Azure Functions. All Function Apps reside in a single git repository.
We would like some of our environments to deploy automatically from source (e.g. bitBucket or gitHub).
How do we configure the project so that Azure knows which project in source relates to which created Function App?
I have searched around this problem for a number of days and have not seen any results that sit outside of "it just works" so can only assume that we are missing something fundamental.
I'd recommend using Azure DevOps (formerly VSTS) to deploy to Azure, you use YAML to define a build pipeline which can publish an artifact from each of your function apps. The artifacts then get picked up by a release pipeline and can be deployed to Azure.
The basic building blocks of this are, firstly some YAML like this in your build pipeline for each project:
...
steps:
# a script task that let's you use any CLI available on the DevOps build agent, also uses a variable for the build config
- script: dotnet build MyFirstProjectWithinSolution\MyFirstProject.csproj --configuration $(buildConfiguration)
displayName: 'dotnet build MyFirstProject'
# other steps removed, e.g. run and publish tests
- script: dotnet publish MyFirstProjectWithinSolution\MyFirstProject.csproj --configuration $(buildConfiguration) --output MyFirstArtifact
displayName: 'dotnet publish MyFirstProject'
# a DevOps named task called CopyFiles (which is version 2 = #2), DevOps supplies lots of standard tasks you can make use of
- task: CopyFiles#2
inputs:
contents: 'MyFirstProjectWithinSolution\MyFirstArtifact\**'
targetFolder: '$(Build.ArtifactStagingDirectory)'
# now publish the artifact which makes it available to the release pipeline, doing so into a sub folder allows multiple artifacts to be dealt with
- task: PublishBuildArtifacts#1
displayName: 'publish MyFirstArtifact artifact'
inputs:
pathtoPublish: '$(Build.ArtifactStagingDirectory)\MyFirstProjectWithinSolution\MyFirstArtifact'
artifactName: MyFirstArtifact
# now repeat the above for every project you need to deploy, each in their own artifact sub-folder
Next you create a release, which in its simplest form picks up the artifacts and does one or more deployment, here's a simple one which deploys two function app projects:
Within a deployment stage (right hand side above), you can define your release process, again in its simplest form you can just deploy straight to production or to a slot, although until function slots are out of preview you could also spin up another function app and deploy and test there.
This screenshot shows a simple deployment which uses a standard Azure Function App deployment from Azure DevOps:
Within your deployment stage you can define which artifact is deployed and after running your build pipeline for the first time you'll get to see all the available artifacts that it created.
All or parts of the above can be automated from pushing a branch (or other triggers such as on a schedule). Notifications and "gates" can be added as well if you want manual intervention before release or between release stages.
There are also other ways to cut this up, eg with multiple build pipelines, it’s basically completely flexible but the above are the elements you can use to deploy one or more function apps at a time.

Resources