How do I configure a build on VSTS to FTP deploy - azure-devops

I want to use VSTS to build and deploy my app (to FTP) when Update the master branch of my project. I have the script below. It works in that it triggers and builds but then fails to deploy because it can't find the files and I don't know what values to enter. I get the error below.
When VSTS builds, where does it put the build files?
I've watched youtube but all the examples are old and don't reflect how VSTS works right now so I'm totally stuck. There are no articles here that reflect how VSTS works right now and the Microsoft pages are no help either.
I'm running out of articles to review and am now pretty much guessing, so any help would be very much appreciated.
# ASP.NET Core
# Build and test ASP.NET Core projects targeting .NET Core.
# Add steps that run tests, create a NuGet package, deploy, and more:
# https://learn.microsoft.com/azure/devops/pipelines/languages/dotnet-core
trigger:
- master
pool:
vmImage: 'ubuntu-latest'
variables:
buildConfiguration: 'Release'
steps:
- script: dotnet build --configuration $(buildConfiguration)
displayName: 'dotnet build $(buildConfiguration)'
- task: FtpUpload#2
inputs:
credentialsOption: 'inputs'
serverUrl: 'ftp://xxxxxxx.xxxxxxxx.xxxxx/'
username: 'xxxxxxxxx'
password: 'xxxxxxxxxx'
rootDirectory: '/'
filePatterns: '**'
remoteDirectory: '/'
clean: false
cleanContents: true
preservePaths: false
trustSSL: false
I changed to this
rootDirectory: $(Agent.BuildDirectory)
and tried this
rootDirectory: $(Build.StagingDirectory)
And now the build succeeds but now I get this error/warning. Nothing is deployed.

When you set system.debug=true, then open the log for detailed compile process, you could see:
It is looking for directory '/' which you specified in the task. But, unfortunately, the content obtained with / is not any part of your repos. Then the server tell you sorry, can not find such file or directory in your repos.
This parameter is getting files or folders from your VSTS repos, so here you need use some words to let server know what you want to take from Repos.
(1) Since this task is in your build pipeline, you could use $(Build.SourcesDirectory) to represent for your whole repos.
(2) Also, if you just want to copy part of repos, such as folder or file, just input them with relative path. For example:
Upload the file upload.json which under the folder jobs, just
input rootDirectory: jobs/upload.json.
Upload one folder or file which in the root path of Repos, just input
rootDirectory: {folder name}, or rootDirectory: {folder name}. Like: rootDirectory: jobs, or rootDirectory: web.config

Related

What is the best way to authenticate for a push to azure devops package feed?

I have an azure devops package feed which was working fine for my purposes, until recently a hard drive failure disrupted operations. Suddenly I found myself unable to push any packages without running into a 401 response. I was able to get it to work eventually after modifying a nuget.config file as described in the answer to this question, but given that this entire process was fairly convoluted, it seems like there should be a much more straight-forward way to set this up when needed. So that in the case I ever need to do this again in the future, and so that I don't have to rely on getting lucky with stack overflow answers, what is the best, most straight-forward method for setting up publishing to azure devops package feeds?
nuget.config is the most commonly used authentication method for push packages to feed. There are two ways to push packages to feed, I think you may need another.
Pipeline push should be a easy way to achieve your requirement.
trigger:
- none
pool:
vmImage: 'windows-latest'
steps:
- checkout: self
persistCredentials: true #This step will do the auth.
- task: DotNetCoreCLI#2
inputs:
command: 'build'
projects: '**/*.csproj'
arguments: '--configuration Debug'
- task: DotNetCoreCLI#2
inputs:
command: 'pack'
packagesToPack: '**/*.csproj'
versioningScheme: 'byPrereleaseNumber'
majorVersion: '1'
minorVersion: '0'
patchVersion: '2'
- task: NuGetCommand#2
inputs:
command: 'push'
packagesToPush: '$(Build.ArtifactStagingDirectory)/**/*.nupkg;!$(Build.ArtifactStagingDirectory)/**/*.symbols.nupkg'
nuGetFeedType: 'internal'
publishVstsFeed: 'xxx/xxx'
You just need to 'click' the feed you want push to and then change the step of YAML like the above.
After that, give the permission to pipeline:
Finally, run the pipeline to push artifact to feed:
Each step of this method is very clearly and each time you want to push artifact, you just need to change several settings is ok(Version, Repo that the pipeline based on, artifact name). Create once, use for a long time.
Additional:
How to change the repo that the pipeline based on:
Repository Structure on my side:
Everything of push artifacts:
Publish Nuget packages(NuGet.exe)
Publish Nuget packages(dotnet)
Publish NuGet packages with Azure Pipelines (YAML/Classic)

Terraform: Error while loading schemas for plugin components

I have an Azure DevOps Build pipeline that publishes the entire repository as an artifact to be used with the Release pipeline.
# Publish artifacts to be used in release
- task: PublishBuildArtifacts#1
displayName: 'publish artifacts'
inputs:
PathtoPublish: '$(System.DefaultWorkingDirectory)'
ArtifactName: 'TerraformModule'
publishLocation: 'Container'
The build pipeline triggers the creation of a release pipeline where I try to deploy the terraform configuration.
I can successfully run terraform init in this pipeline but when I try to run plan or apply, I get the following error:
Looking at the screenshot, it looks like it tries to execute the command from /usr/local/bin instead of what I specified in the step? Confused by this. Below is the yaml for my plan step:
steps:
- task: ms-devlabs.custom-terraform-tasks.custom-terraform-release-task.TerraformTaskV3#3
displayName: 'terraform plan'
inputs:
provider: aws
command: plan
workingDirectory: '/home/vsts/work/r1/a/_terraform/TerraformModule/Projects/Potentium/Prod'
environmentServiceNameAWS: 'AWS-Terraform-Build'
I manually changed workingDirectory to where the Artifacts from the build pipeline were downloaded to. See log below for example:
2022-08-14T23:41:31.3359557Z Downloaded TerraformModule/Projects/Potentium/Prod/main.tf to /home/vsts/work/r1/a/_terraform/TerraformModule/Projects/Potentium/Prod/main.tf
The plan step in my build pipeline executes without any issues so I have a feeling it is something to do with the artefacts/extraction that is occurring in the download step. Looking for any advice.
I've had similar issues with the extraction phase, when using ExtractFiles#1 doing a similar thing with terraform. I think there's a bug in it, I could not get it to extract files back to the root of System.DefaultWorkingDirectory unless the root folder was included in the archiv, I am using ArchiveFiles#2. So I was ending up with /opt/az_devops/_work/*/s/s
My solution, was to shell out a command to do the extraction. No problems extracting to the root of System.DefaultWorkingDirectory
Just remember if you're running a subsequent terraform plan, by default the working directory System.DefaultWorkingDirectory will change between runs. So ensure you use these variables rather than an explicit reference.

Single WCF project will not create build artifact under YAML Azure DevOps Build Pipeline

Our build pipeline includes a YML template that is used to build all of our WCF services and Web applications. For all of the WCF services but one, it works like a charm. For this one WCF service, however, the following output is generated in the build logs during the Publish Artifact stage:
##[warning]Directory 'D:\azagent\A2_work\1381\a' is empty. Nothing will be added to build artifact 'drop'.
Our Build stage invokes a separate YML file which includes the following to build and publish the project:
- task: VSBuild#1
displayName: "Build ${{ parameters.solution}}"
inputs:
solution: ${{ parameters.solution }}
msbuildArgs: >
/p:DeployOnBuild=true
/p:WebPublishMethod=Package
/p:PackageAsSingleFile=true
/p:SkipInvalidConfigurations=true
/p:IgnoreDeployManagedRuntimeVersion=true
/p:PackageLocation="$(build.ArtifactStagingDirectory)"
platform: ${{ parameters.buildPlatform }}
configuration: ${{ parameters.buildConfiguration }}
- task: PublishBuildArtifacts#1
displayName: "Publish Build Artifact"
inputs:
PathtoPublish: "$(Build.ArtifactStagingDirectory)"
ArtifactName: "drop"
publishLocation: "Container"
As stated earlier, this works perfectly for all other WCF projects, and generates a build artifact. However, for the problematic WCF Service, no build artifact is generated. What we've observed is that no ZIP file is created in the D:\azagent\A2_work\1381\a folder (theoretically, Build.ArtifactStagingDirectory).
I have tried numerous recommended solutions to resolve this issue, all to no effect.
Adding a CopyFiles#2 task between the VSBuild#1 task and the PublishBuildArtifacts#1 task did place the files in the Build.ArtifactStagingDirectory, but they were not in a ZIP file. Further, the deployment task (later in the pipeline) failed because no ZIP file was present in the drop folder.
Adding /p:OutDir=$(Build.ArtfactStagingDirectory) did seem to produce some sort of artifact, but the deployment task still failed, claiming it could not find the ZIP file in the drop folder.
I created a test repo that contained only the WCF project (as it's normally contained in a solution containing it and a Web application) and ran the pipeline against that repo. No build artifact was created.
Ultimately, nothing I do seems to be able to get this project to generate a build artifact.
What am I missing here? What further information can I provide that will help you to help me resolve this issue?
According to Microsoft's Developer Community, this has been a known issue since August of 2019. WCF services built using a YAML pipeline do not produce build artifacts. Consequently, they cannot be deployed via YAML pipelines.
As of this date, there is neither a fix nor a workaround available from Microsoft.

Set working directory of a project in mono repo in Azure Devops

My project is using microservices and in one repos we have multiple applications in Azure DevOps.
For Example, we have Repos named Microservice, where we have .NetProject, AngularUI Project, and Java Project code.The structure looks like this:
While setting up the CI pipeline, I have included the path like the below:
variables:
- name: working-dir
value: 'MicroserviceProject/AngularUI/ClientApp/'
trigger:
branches:
include:
- master
paths:
include:
- 'MicroserviceProject/AngularUI/ClientApp/*'
I don't see the code of AngularUI project being checkout properly and encountering the error, that they cannot locate the package.json file.
How can I set the working directory for different projects in a repo?
Update:
I am able to locate the file but the build isnot giving me any output files.
How I fixed this issue:
Initially I was not sure if the working directory was set properly.Even if it was , I was not sure whether the package.json file was read properly. To check that, I added the below script to the Azure CI pipeline, for example:
inputs:
targetType: 'inline'
script: dir
$(Build.ArtifactStagingDirectory)
displayName: 'Check'
This showed me that after building , the artifacts are not stored anywhere. hence I had to explicitly mention the outputpath. For that I ran the below command for build:
run-script build -- --output-path=$(Build.ArtifactStagingDirectory
This fixed the issue I was facing.

Azure DevOps release pipeline: Angular and .NET Core application

We're trying to release an Angular 7 / .NET Core application into Azure using the DevOps release pipelines. I have my build setup to create the .NET and Angular builds as separate artifacts which you can see in the screen shots below (under the Package or Folder box).
From what I've read it seems that you need to create two separate release tasks to deploy the builds to the web app. However the second build seems to be overriding the first which is causing the API not to start.
Does anyone know of a way to ensure the deployments in a given stage simply appends the changes rather than replacing them? Or is there something else I am missing here?
My recommendation would be to implement the following pattern for your pipeline:
'ng build --prod' the angular app in it's own job, and add the artifacts to your pipeline
'dotnet publish' the dotnet core api in it's own job, running in parallel with the angular job, and add the artifacts to your pipeline
Append the Angular and Dotnet Core artifacts together into a new artifact. This serves as your final package to deploy
Deploy the final package
You're missing step 3, so you'd want something like the following logic defined in YAML, where you create a new zip that represents your actual deployed bits in your pipeline. Then release that artifact, since it is the representation of what you have running on your instances.
- job: CreateReleaseArtifact
displayName: 'Package for shared-hosting of angular app and web api'
pool:
vmImage: windows-2019
dependsOn:
- BuildNetcore
- BuildAngularApp
condition: succeeded()
steps:
- checkout: none
- download: current
- task: CopyFiles#2
displayName: 'Copy WebApi Files'
inputs:
SourceFolder: $(Pipeline.Workspace)/api
Contents: '**/*'
TargetFolder: $(Pipeline.Workspace)/package
includeRootFolder: false
- task: CopyFiles#2
displayName: 'Copy Angular Files'
inputs:
SourceFolder: $(Pipeline.Workspace)/webapp
Contents: 'wwwroot/**'
TargetFolder: $(Pipeline.Workspace)/package
includeRootFolder: true
OverWrite: true
- publish: $(Pipeline.Workspace)/package
artifact: package
Does anyone know of a way to ensure the deployments in a given stage simply appends the changes rather than replacing them?
Based on my experience, in your case, after deploy the API or Angular 7, then I you could use the Kudu zip API to upload another one to the Azure WebApp.
You could use the Powershell task to do that. For more inforamtion about powershell demo code, you could refer to this link.
If creating another WebApp is acceptable, you could add a new WebApp and use the same service plan (no extral cost). Then you could deploy them separately.