Flatten build output folders in Azure Pipelines - azure-devops

I have a solution in Visual Studio consisting of multiple report projects, and using Azure Pipelines to deploy the reports to my report server. This pipeline has served me faithfully for years, but my goal is to simplify it a bit.
Running MSBuild for the solution generates a directory structure like this:
- root
- Project A
- bin
- Release
- Report1.rdl
- Report2.rdl
- Project B
- bin
- Release
- Report3.rdl
- Report4.rdl
Question: how can I use either the Copy Files task in my pipeline or a subsequent PowerShell task to produce a slightly flattened structure like this, where the bin and Release folder for each project is removed?:
- root
- Project A
- Report1.rdl
- Report2.rdl
- Project B
- Report3.rdl
- Report4.rdl
Here is an outline of my current pipeline configuration:
- Build solution
- MSBuild arguments: none
- Configuration: $(BuildConfiguration)
- Copy files
- Source folder: $(build.sourcesdirectory)
- Contents: **\bin\$(BuildConfiguration)\**\*.rdl
- Target folder: $(Build.ArtifactStagingDirectory)
- Publish artifact
- Path to publish: $(Build.ArtifactStagingDirectory)

You can use something like that:
- Build solution
- MSBuild arguments: none
- Configuration: $(BuildConfiguration)
- Copy files
- Source folder: $(build.sourcesdirectory)
- Contents: **\Project A\bin\$(BuildConfiguration)\*.rdl
- Target folder: $(Build.ArtifactStagingDirectory)\Project A
- Flatten Folders: True
- Copy files
- Source folder: $(build.sourcesdirectory)
- Contents: **\Project B\bin\$(BuildConfiguration)\*.rdl
- Target folder: $(Build.ArtifactStagingDirectory)\Project B
- Flatten Folders: True
- Publish artifact
- Path to publish: $(Build.ArtifactStagingDirectory)
The Flatten folders option here:
OR
- Build solution
- MSBuild arguments: none
- Configuration: $(BuildConfiguration)
- Copy files
- Source folder: $(build.sourcesdirectory)\Solution Folder\Project A\bin\$(BuildConfiguration)
- Contents: *.rdl
- Target folder: $(Build.ArtifactStagingDirectory)\Project A
- Copy files
- Source folder: $(build.sourcesdirectory)\Solution Folder\Project B\bin\$(BuildConfiguration)
- Contents: *.rdl
- Target folder: $(Build.ArtifactStagingDirectory)\Project B
- Publish artifact
- Path to publish: $(Build.ArtifactStagingDirectory)

Related

What is the source directory of the build?

I have the following tasks:
steps:
- task: MSBuild#1
displayName: '$(ProjectName) .Net build | Build solution (No need to build test as well)'
inputs:
solution: '**/$(ProjectName)/*.csproj'
msbuildArchitecture: x64
configuration: Release
msbuildArguments: '/p:OutputPath=$(Build.ArtifactStagingDirectory)'
clean: true
steps:
- task: CopyFiles#2
displayName: 'Copy Files to: $(Build.ArtifactStagingDirectory)/Release'
inputs:
SourceFolder: '$(Build.ArtifactStagingDirectory)/$(ProjectName)'
Contents: |
bin/**
Bundles/**
Views/**
appsettings.json
appsettings.Development.json
*.txt
**/wwwroot/favicon-*.png
**/wwwroot/favicon-*.ico
TargetFolder: '$(Build.ArtifactStagingDirectory)/Release'
For some reason, the copy step fails with:
##[error]Error: Not found SourceFolder: D:\a\1\a\projectname
why is that?
My project output structure following a local VS build is something like this:
The pipeline .Net build step creates directories as follows:
Creating directory "D:\a\1\a\nl".
Creating directory "D:\a\1\a\cs".
Creating directory "D:\a\1\a\de".
...
2022-09-21T02:38:30.3292966Z Creating directory "D:\a\1\a\runtimes\win-arm\native".
2022-09-21T02:38:30.3293353Z Creating directory "D:\a\1\a\runtimes\win\lib\netcoreapp3.1".
2022-09-21T02:38:30.3293727Z Creating directory "D:\a\1\a\runtimes\win-arm64\native".
2022-09-21T02:38:31.1717424Z Creating directory "D:\a\1\a\refs".
2022-09-21T02:38:31.1717862Z Creating directory "D:\a\1\a\refs".
2022-09-21T02:38:31.1718174Z Creating directory "D:\a\1\a\refs".
so i assumed the source would be D:\a\1\a\projectname or SourceFolder: '$(Build.ArtifactStagingDirectory)/$(ProjectName)' but thats not working it seems.
My reasoning for this is before the dev upgraded the project to .NET6, in the older asp.NET model, the output was one wwwroot directory and so it would translate in the build log to something like:
Creating directory "D:\a\1\a\_PublishedWebsites\projectname\Content\...
so my copy task source would be SourceFolder: '$(Build.ArtifactStagingDirectory)/_PublishedWebsites/$(ProjectName)' and that normally worked.
but _PublishedWebsitesno longer appears to be part of .NET6 build output, so im not sure what the source would be now
To be sure about how the build is generating the directory structure, you can add the following task and check the output:
steps:
- task: MSBuild#1
displayName: '$(ProjectName) .Net build | Build solution (No need to build test as well)'
inputs:
solution: '**/$(ProjectName)/*.csproj'
msbuildArchitecture: x64
configuration: Release
msbuildArguments: '/p:OutputPath=$(Build.ArtifactStagingDirectory)'
clean: true
- powershell: |
Get-ChildItem $(Build.ArtifactStagingDirectory) -Recurse
displayName: 'Check agent directories'

Why are the Web.*env*.config files not being copied over to the artifact?

I'm finding something strange with the copy task in the build CI pipeline of a .NET app. lets call it JJ.
For some reason, the Web.Dev.config, Web.Test.config, and Web.Prod.config files aren't being copied to the artifact. I have another pipeline for a similarly designed app so the pipeline is setup the same way, and I confirmed that with that other app, let's call it EE, those files are getting copied in the artifact, but with JJ they are not being copied for some reason.
EE app artifact (other app that copy task is working):
JJ app artifact (app in question, only Web.config is copied):
even though there is Dev/Test/Prod configs clearly in the directory
JJ copy task YAML:
steps:
- task: CopyFiles#2
displayName: 'Copy Files to: $(Build.ArtifactStagingDirectory)/Release'
inputs:
SourceFolder: '$(Build.ArtifactStagingDirectory)/_PublishedWebsites/JJDashboard'
Contents: |
assets/**
bin/**
Bundles/**
Content/**
Scripts/**
Views/**
Web.config
Web.Dev.config
Web.Test.config
Web.Prod.config
ApplicationInsights.config
*.asax
*.ico
*.txt
TargetFolder: '$(Build.ArtifactStagingDirectory)/Release'
EE copy task YAML (the app that config files are being copied just fine):
steps:
- task: CopyFiles#2
displayName: 'Copy Files to: $(Build.ArtifactStagingDirectory)/Release'
inputs:
SourceFolder: '$(Build.ArtifactStagingDirectory)/_PublishedWebsites/EEDashboard'
Contents: |
assets/**
bin/**
Bundles/**
Content/**
Scripts/**
Views/**
Web.config
Web.Dev.config
Web.Test.config
Web.Prod.config
ApplicationInsights.config
*.asax
*.ico
*.txt
TargetFolder: '$(Build.ArtifactStagingDirectory)/Release'
The copy task YAMLs are pretty identical as you can observe, as is the repo structures/file locations. So why is it working for EE but not JJ?
Edit
Comparing JJ .csproj file vs EE .csproj file we observe the web.dev.config, web.test.config, and web.prod.config file references in JJ .csproj file are missing the tag: <content Include>
Enabling this property for the files in the project resolves the issue:
Check that the new web.env.config -files are included in the JJDasboard-project .csproj (or .sln) -file, so they will be published with the build results.
The most apparent problem would be that the builds produce different results, ie. EE app's build copies all the different configs to output directory, where as JJ app's build only copies the web.config (as it does by default).

Folder missing in artifact - GitHub Actions

I have the following steps to copy files to artifact and publish artifact:
- name: copy FA function arm templates
run: Copy 'Service/Project/Hosts/FA/Infrastructure/' 'upload/functions_arm_templates/FA/Infrastructure'
shell: powershell
- name: copy FB function arm templates
run: Copy 'Service/Project/Hosts/FB/Infrastructure/' 'upload/functions_arm_templates/FB/Infrastructure'
shell: powershell
- name: publish artifact
uses: actions/upload-artifact#v2
with:
name: ${{github.run_number}}
path: upload/**
The Build succeeded however after downloading the artifact, I don't see a folder named functions_arm_templates. What am I missing?
You are only copying the folder without its contents.
Use copy 'Service/Project/Hosts/FA/Infrastructure/' 'upload/functions_arm_templates/FA/Infrastructure/' -recurse to copy the folder with its contents.

gitlab ci: sbt recompiles in each stage

I am trying to make my first gitlab ci pipeline with sbt.
i am trying to make build and test stages.
the problem is that although i compile the project at build, it compiles again at test stage before running the tests.
can someone help me to understand why this is happening and how to solve it?
sbt version: 1.2.7
this is my gitlab-ci.yml file:
image: docker-registry:5000/sbt-docker:latest
variables:
SBT_OPTS: "-Dsbt.global.base=sbt-cache/sbtboot -Dsbt.boot.directory=sbt-cache/boot -Dsbt.ivy.home=sbt-cache/ivy Dsbt.coursier.home=sbt-cache/coursier -Dsbt.io.jdktimestamps=true"
COURSIER_CACHE: sbt-cache/coursier
stages:
- build
- test
cache:
paths:
- "sbt-cache/ivy/cache"
- "sbt-cache/boot"
- "sbt-cache/sbtboot"
- "sbt-cache/coursier"
build:
stage: build
script:
- sbt -J-Xmx2G clean core/compile core/package
artifacts:
untracked: true
paths:
- "target/"
test:
stage: test
dependencies:
- build
script:
- sbt core/test
allow_failure: true
You need to cache the target/ folders of your project. I'm not familiar with CircleCI, it seems that there is a cache:paths key available, which sounds nice as long as the cache is per branch.

VSTS Yaml vraiables and path contradicting with classic editor

I am facing an issue when setting VSTS classic editor parameters when compare with current yaml file which is working as expected.
Below is working fine (Build pipeline)
- task: CopyFiles#2
displayName: "Copy Files to: $(Build.ArtifactStagingDirectory)"
inputs:
contents: '$(Build.SourcesDirectory)/src/xxx.EndToEnd.Integration.Tests/**'
targetFolder: $(Build.ArtifactStagingDirectory)
- task: DotNetCoreCLI#2
displayName: "dotnet e2e tests"
inputs:
command: publish
publishWebProjects: false
projects: '**/*.csproj'
arguments: --output $(Build.ArtifactStagingDirectory)/src/xxx.EndToEnd.Integration.Tests
zipAfterPublish: false
But same setting as per below find 0 files
2019-04-06T10:02:57.5303667Z found 0 files
2019-04-06T10:02:57.5376614Z ##[section]Finishing: Copy Files to: $(Build.ArtifactStagingDirectory)
I have changed the / to \ as well, but same outcome.
Below is designer pipeline
Same results in dotnet publish task also in Path to project(s) parameter **\**\*.csprojgives below error, but above yaml file works as expected.
2019-04-06T10:02:58.7896707Z ##[error]Project file(s) matching the specified pattern were not found.
In the release pipeline the variables Build.SorucesDirectory and Build.ArtifactSatgingDirectory are not available, these variables are only for build pipelines.
In fact, in the release agent folder there is not "Soruces" folder, but only "Artifact" folder. for example: C:\agent\_work\r1\a, the variable to get the value is: System.ArtifactDirectory or Agent.ReleaseDirectory.
More details about release variables you can find here.