Why does Azure Devops change the date on dlls downloaded from Nuget? - azure-devops

I notice that files such as EntityFramework.Dll are deployed with the current time.
I have been experiencing this error and I resolved it by copying dlls from my development machine to the overwrite deployed dlls.
What causes the date to change on the dlls?
azure-pipelines.yml is
trigger:
- master
pool:
vmImage: 'VS2017-Win2016'
variables:
solution: '**/*.sln'
buildPlatform: 'Any CPU'
buildConfiguration: 'Debug'
steps:
- task: NuGetToolInstaller#0
- task: NuGetCommand#2
inputs:
restoreSolution: '**\*.sln'
feedsToUse: config
nugetConfigPath: 'MyService.ServiceHost/nuget.config'
- task: VSBuild#1
inputs:
solution: '$(solution)'
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'
- task: VSTest#2
inputs:
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'
- task: CopyFiles#2
displayName: 'Copy Files to: $(Build.ArtifactStagingDirectory)'
inputs:
SourceFolder: '$(Build.SourcesDirectory)'
Contents: |
$(Build.SourcesDirectory)\MyService.ServiceHost\bin\debug\**\*.*
TargetFolder: '$(build.artifactstagingdirectory)'
- task: PublishBuildArtifacts#1
inputs:
artifactName: 'drop'
my nuget.config references
and a private feed in https://pkgs.dev.azure.com
[Update]
I tried adding preserveTimestamp: True to the CopyFiles#2 task but it made no difference
- task: CopyFiles#2
displayName: 'Copy Files to: $(Build.ArtifactStagingDirectory)'
inputs:
SourceFolder: '$(Build.SourcesDirectory)'
Contents: |
$(Build.SourcesDirectory)\MyService.ServiceHost\bin\debug\**\*.*
TargetFolder: '$(build.artifactstagingdirectory)'
preserveTimestamp: True
[Update]
Leo advises a work around.
However I am wondering how to unzip the file to release
Currently my release pipeline contains
copy C:\azagent\A2\_work\r1\a\_PreMyFolder\drop\MyService.ServiceHost\bin\Debug\*.* "C:\Program Files (x86)\MyCompany\MyService Service"

Why does Azure Devops change the date on dlls downloaded from Nuget?
That because the default value of the preserveTimestamp option is False in the Copy Files task.
- task: CopyFiles#2
inputs:
#sourceFolder: # Optional
#contents: '**'
targetFolder:
#preserveTimestamp: false # Optional
To resolve this issue, you just need change the value to True.
- task: CopyFiles#2
inputs:
sourceFolder:
contents: '**'
targetFolder:
preserveTimestamp: True
Update:
I tried adding preserveTimestamp: True to the CopyFiles#2 task but it
made no difference
When I first tested this issue, I found that the copy task would modify the Timestamp of the file. This is indeed the case. And found a solution using option preserveTimestamp. I thought this was the whole issue until Kirsten Greed replied to me that this solution did not work.
I had to test the issue again and found that the PublishBuildArtifacts task would also modify the Timestamp of the file, but there is no such preserveTimestamp option like copy task. We could found some similar thread here and here, but none of them gives a solution/workaround.
The workaround I currently think of is that you could try to Bundle the artifacts in a compressed zip file, then unzip it when you use it.
So, I use the Archive files instead of the copy task:
- task: ArchiveFiles#2
displayName: 'Archive $(Build.SourcesDirectory)\TestSample\TestSample\bin\Debug'
inputs:
rootFolderOrFile: '$(Build.SourcesDirectory)\TestSample\TestSample\bin\Debug'
archiveFile: '$(Build.ArtifactStagingDirectory)/Test.zip'
Then publish this zip file as artifact:
- task: PublishBuildArtifacts#1
displayName: 'Publish Artifact: drop'
Now, I could keep the Timestamp for the files:
Hope this helps.

I have this same problem. If I zip the files or simply do a Machine File Copy task to the server the date modified is always updated by Azure Dev Ops.
I don't believe is it currently possible to deploy from Dev Ops whilst preserving the date modified of the files.

Related

Azure devops ASP.Net CI -get artifact in zip

I have Asp.net CI, which publishes .zip artifacts.
When I download the .zip artifact, I have to go through many folders to be able to see the files.
I used the default arguments when building solution and many other ones, but no result.
Is there a way to publish the .zip so, that when I download it I see the files already?
In .net core that issue doesn't occur, but in asp.net does.
I used templated not yaml files.
Soulution build:
steps:
- task: VSBuild#1
displayName: 'Build solution'
inputs:
solution: '$(Parameters.solution)'
msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactstagingdirectory)\\"'
platform: '$(BuildPlatform)'
configuration: '$(BuildConfiguration)'
Publish Symbols
steps:
- task: PublishSymbols#2
displayName: 'Publish symbols path'
inputs:
SearchPattern: '**\bin\**\*.pdb'
PublishSymbols: false
continueOnError: true
Publish artifact
steps:
- task: PublishBuildArtifacts#1
displayName: 'Publish Artifact WEB: to drop'
inputs:
PathtoPublish: '$(build.artifactstagingdirectory)\HRSoft.WebClient.zip'
ArtifactName: '$(Parameters.ArtifactName)'
condition: succeededOrFailed()
In your msbuildArgs you should say that you want the artifacts as zip:
/p:DesktopBuildPackageLocation="$(build.artifactstagingdirectory)\WebApp.zip" or /p:p:PackageLocation="$(build.artifactstagingdirectory)\WebApp.zip"

dotnet build failing because project not found

I have a YAML file with tasks to copy & publish files to artifact and download the artifact:
Log for task DownloadPipelineArtifact#2:
Downloading: D:\a\1\s\Service\ProjectName\Repositories.Logging/Repositories.Logging.csproj
Then, I have a task to build. The build fails on this task.
Log for task DotNetCoreCLI#2:
Skipping project "D:\a\1\s\Service\ProjectName\Repositories.Logging\Repositories.Logging.csproj" because it was not found.
Why does it say skipping project because it was not found even though log for DownloadPipelineArtifact#2 shows the same path? What am I missing and how do I fix that?
UPDATE:
I know that there is a difference in the slashes. However, I don't have conrol over updating the slashes:
Tasks to copy, publish, download:
- task: CopyFiles#2
displayName: 'copy service'
inputs:
SourceFolder: 'Service\ProjectName'
contents: '**'
TargetFolder: '$(build.artifactstagingdirectory)'
- task: PublishBuildArtifacts#1
displayName: 'publish artifact'
inputs:
PathtoPublish: '$(build.artifactstagingdirectory)'
ArtifactName: '$(Build.BuildNumber)'
- task: DownloadPipelineArtifact#2
inputs:
artifactName: '$(Build.BuildNumber)'
downloadPath: Service\ProjectName
On updating download task to:
- task: DownloadBuildArtifacts#0
inputs:
artifactName: '$(Build.BuildNumber)'
downloadPath: $(System.DefaultWorkingDirectory)\Service\ProjectName
I see the following log from DownloadBuildArtifacts#0:
Downloaded to D:\a\1\s\Service\ProjectName\20201118.10\Repositories.Logging\Repositories.Logging.csproj
and following log from DotNetCoreCLI#2:
D:\a\1\s\Service\ProjectName\Repositories.Logging\Repositories.Logging.csproj because it was not found
In this case I see the slashes correctly. Is it possible to remove:
20201118.10
from downloadPath so that it becomes:
D:\a\1\s\Service\ProjectName\Repositories.Logging\Repositories.Logging.csproj
Is it possible to remove 20201118.10 from downloadPath.
We could not remove the artifact Name 20201118.10 when we use the task Download build artifacts.
When we check the task Download build artifacts in the classic mode, we could to know the option Artifact name is required:
To resolve this issue, we could add a copy task to copy files to $(System.DefaultWorkingDirectory)\Service\ProjectName folder
- task: CopyFiles#2
displayName: 'Move artifact Name'
inputs:
SourceFolder: '$(System.DefaultWorkingDirectory)\Service\ProjectName\$(Build.BuildNumber)'
TargetFolder: '$(System.DefaultWorkingDirectory)\Service\ProjectName'
Or you could specify the path including the artifact Name 20201118.10 when you build the project:
- task: DotNetCoreCLI#2
displayName: 'dotnet build'
inputs:
projects: '$(System.DefaultWorkingDirectory)\Service\ProjectName\$(Build.BuildNumber)\Repositories.Logging\Repositories.Logging.csproj'

Publishing Pipeline Artifacts for use in another pipeline

I'm trying to publish a couple of pipeline artifacts during a build so that I can use them in a build of another solution.
My first build builds and tests the soltuion using the following yaml
- stage: build_test_release
displayName: Build
pool:
vmImage: 'windows-latest'
variables:
solution: '**/*.sln'
buildPlatform: 'Any CPU'
buildConfiguration: 'Release'
jobs:
- job: build
steps:
- task: NuGetToolInstaller#1
- task: NuGetCommand#2
inputs:
restoreSolution: '$(solution)'
- 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)'
This all works great and I've been able to do deployments using this yaml in the same file
- task: AzureRmWebAppDeployment#4
inputs:
ConnectionType: 'AzureRM'
azureSubscription: 'azuresubscription'
appType: 'webApp'
WebAppName: 'webappname'
deployToSlotOrASE: true
ResourceGroupName: 'resourcegroupname'
SlotName: 'staging'
packageForLinux: '$(build.artifactStagingDirectory)/**/projectToPublish.zip'
I'm now trying to publish some of the projects which were build as Pipeline Artifacts so that I can use them in the build of another solution which references them. The following publish task gives me the error:
"##[error]Path does not exist: D:\a\1\a**\projectToPublish.zip"
- task: PublishPipelineArtifact#1
inputs:
targetPath: '$(build.artifactStagingDirectory)/**/projectToPublish.zip'
artifact: 'artifactname'
publishLocation: 'pipeline'
What am I missing here? I've been thinking of moving the projects which are referenced by both soltuions into their own solutions and adding them as nuget packages or something similar. The projects I am trying to publish as artifacts to be used in the second solution are both WCF Client projects.
Thanks!
The issue is that the task you're using, Publish Pipeline Artifacts, does not support wildcards for the 'File or directory path' argument. For this task $(build.artifactStagingDirectory) is replaced with D:\a\1\a\, in the second directory named a Azure DevOps is looking for a sub directory named ** which does not exist and causes the shown error. The other task AzureRmWebAppDeployment#4 you're using does support wildcards.
See the image below, where Azure DevOps shows in the the UI that the PublishPipelineArtifact#1 task does not support wildcards in targetPath:
Second I'm wondering why you're using a wildcard, because the task VSBuild#1 will just drop the package in the build.artifactStagingDirectory which should make the path $(build.artifactStagingDirectory)/projectToPublish.zip to locate the package.
In AzureRmWebAppDeployment#4 you have
'$(build.artifactStagingDirectory)/**/WebProjectToPublish.zip'
And in PublishPipelineArtifact#1 you have a different name
'$(build.artifactStagingDirectory)/**/projectToPublish.zip'

How to launch a build pipeline on pull request

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:

Can I get a download link for my WPF application from Azure Devops

I'm developing a Windows WPF application that I have set up a build pipeline for in Azure Devops. My problem is that I can't seem to figure out any way to download the artifacts after successfully completing the build.
Is it possible to get a link to a zip containing all the built files somehow. How can I get my files? I don't want to publish to NPM or NuGet or anything like that, just download to my desktop for now.
Thanks!
Edit: This is my build configuration
trigger:
- master
pr:
- master
pool:
vmImage: 'VS2017-Win2016'
variables:
solution: '**/*.sln'
buildPlatform: 'x64'
buildConfiguration: 'Release'
steps:
- task: NuGetToolInstaller#0
displayName: 'NuGet Tool Installer'
- task: NuGetCommand#2
displayName: 'Restore NuGet dependencies'
inputs:
restoreSolution: '$(solution)'
- task: VSBuild#1
displayName: 'Build $(buildConfiguration) $(buildPlatform)'
inputs:
solution: '$(solution)'
platform: '$(buildPlatform)'
configuration: '$(buildConfiguration)'
- task: CopyFiles#2
displayName: 'Copy files'
inputs:
Contents: '_buildOutput\\**\\*.dll'
TargetFolder: $(Build.ArtifactStagingDirectory)
- task: PublishBuildArtifacts#1
displayName: 'Publishing artifact drop'
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
artifactName: 'drop'
publishLocation: 'filePath'
targetPath: '$(Build.ArtifactStagingDirectory)\\outdir\\$(Build.DefinitionName)\\$(Build.BuildNumber)'
- task: DownloadBuildArtifacts#0
inputs:
buildType: 'current'
downloadType: 'single'
artifactName: 'drop'
downloadPath: '$(System.ArtifactsDirectory)'
You may use 2 ways:
Copy the download link from the build results:
Use link from this example (Artifacts - Get Artifact).
You need to know the Id for your build.
Then you may use download link with this format (for drop by default):
https://dev.azure.com/{organization}/{project}/_apis/build/builds/{buildId}/artifacts?artifactName=drop&api-version=5.0&%24format=zip
Updates (if you use yaml):
You have to use the "Publish Artifact" task if you want to work with build result and have the "Artifact" button.
You can publish it to Azure DevOps (by default):
- task: PublishBuildArtifacts#1
displayName: 'Publish Artifact: drop'
inputs:
PathtoPublish: 'Your folder with build results'
Also you can publish you results to the some file share:
- task: PublishBuildArtifacts#1
displayName: 'Publish Artifact: drop'
inputs:
PathtoPublish: 'Your folder with build results'
publishLocation: FilePath
TargetPath: '\\my\share\$(Build.DefinitionName)\$(Build.BuildNumber)'
Updates 2:
If try to download your with format:
https://dev.azure.com/{organization}/{project}/_apis/build/builds/{buildId}/artifacts?artifactName=drop&api-version=5.0
You will get json with urls:
You may add "&%24format=zip" to the end of url and get a zip file:
Update 3
This is the part of my yaml build definition that was converted from standard build:
- task: CopyFiles#2
displayName: 'Copy Files to: $(build.artifactstagingdirectory)'
inputs:
SourceFolder: '$(build.sourcesdirectory)'
Contents: '**\bin\$(buildConfiguration)\**'
TargetFolder: '$(build.artifactstagingdirectory)'
- task: PublishBuildArtifacts#1
displayName: 'Publish Artifact: drop'
inputs:
PathtoPublish: '$(build.artifactstagingdirectory)'