47

I'm struggling to picture the folder structure of azure pipelines. I know there are some implicit directories like:

  • $(System.DefaultWorkingDirectory)
  • $(Build.ArtifactStagingDirectory)

Which are both folders on a specific build agent available from the pool.

Is there a way to view the folder structure and get a better understanding how things are laid out?

DreadedFrost
  • 2,602
  • 1
  • 11
  • 29
Cristian E.
  • 3,116
  • 7
  • 31
  • 61
  • The documentation gives examples of the folder structure. – Daniel Mann Jul 27 '20 at 17:48
  • 2
    See [Predefined variables](https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml) and [classic release variables](https://learn.microsoft.com/en-us/azure/devops/pipelines/release/variables?view=azure-devops&tabs=batch). The `$(System.DefaultWorkingDirectory)` has different values in release pipeline. – LoLance Jul 28 '20 at 07:45

7 Answers7

74

You can use CMD task to call tree command in Microsoft-Hosted windows agent to get the folder structure.

My script:

echo "Structure of work folder of this pipeline:"
tree $(Agent.WorkFolder)\1 /f

echo "Build.ArtifactStagingDirectory:" 

echo "$(Build.ArtifactStagingDirectory)"

echo "Build.BinariesDirectory:" 

echo "$(Build.BinariesDirectory)"

echo "Build.SourcesDirectory:"

echo "$(Build.SourcesDirectory)"

The result:

enter image description here

$(Agent.WorkFolder) represents the working folder for current agent, $(Agent.WorkFolder)\1 represents the working folder for current pipeline.(Normally the first pipeline will be put in $(Agent.WorkFolder)\1, and the second $(Agent.WorkFolder)\2...)

So it's obvious that for one pipeline run, it has four folders by default: a(artifact folder), b(binaries folder), s(source folder) and TestResults(Test results folder). The s folder is where the source code files are downloaded. For build pipeline: $(Build.SourcesDirectory),$(Build.Repository.LocalPath) and $(System.DefaultWorkingDirectory) represent the same folder. More details see predefined variables.

LoLance
  • 25,666
  • 1
  • 39
  • 73
19

Another option is to add this to a YAML pipeline:

- powershell: Get-ChildItem -Path 'Insert root path' -recurse

It will look something like:

Get-ChildItem -Path C:\Test\*.txt -Recurse -Force

Directory: C:\Test\Logs\Adirectory

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        2/12/2019     16:16             20 Afile4.txt
-a-h--        2/12/2019     15:52             22 hiddenfile.txt
-a----        2/13/2019     13:26             20 LogFile4.txt

    Directory: C:\Test\Logs\Backup

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        2/12/2019     16:16             20 ATextFile.txt
-a----        2/12/2019     15:50             20 LogFile3.txt

    Directory: C:\Test\Logs

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        2/12/2019     16:16             20 Afile.txt
-a-h--        2/12/2019     15:52             22 hiddenfile.txt
-a----        2/13/2019     13:26             20 LogFile1.txt

    Directory: C:\Test

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        2/13/2019     08:55             26 anotherfile.txt
-a----        2/12/2019     15:40         118014 Command.txt
-a-h--        2/12/2019     15:52             22 hiddenfile.txt
-ar---        2/12/2019     14:31             27 ReadOnlyFile.txt

Here is documentation on the Get-ChildItem command if you need more information

DreadedFrost
  • 2,602
  • 1
  • 11
  • 29
  • 1
    in my yaml I wanted to use the powershell@2 task (this is not formatted for yaml but you get the idea): `- task: PowerShell@2 inputs: targetType: inline script: Get-ChildItem -Path '$(Agent.WorkFolder)\*.*' -recurse -force` – Dorothy Hawley Oct 26 '22 at 12:56
  • 3
    This will not write the file name on linux agents – noontz Nov 08 '22 at 13:13
  • 1
    This is the way – bkwdesign Dec 21 '22 at 19:56
  • @noontz did you find a workaround? There seems to be an issue with unix and the console width -> https://stackoverflow.com/questions/71728509/azure-devops-powershell-not-showing-file-names-for-get-childitem – Tommy Mar 07 '23 at 14:01
  • @Tommy Scroll a little down ;) I added a link in a comment on your provided link e.g. https://stackoverflow.com/a/74316936/2050637 – noontz Mar 08 '23 at 19:34
  • As you are not sure what the current working directory is, it's worth using this as `Get-ChildItem -recurse` with no path specified. – frackham Jul 08 '23 at 17:22
10

enter image description here

source: user comment from this blog

Note that your full path may look different based on your environment.

For example: your Build.StagingDirectory path could be c:\agent_work\1\a OR
/home/vsts/work/1/a/

This is based on Agent.BuildDirectory or Pipeline.Workspace variable.(c:\agent_work\1 or /home/vsts/work/1 or /a/1 or something similar)

more in azure docs

ns15
  • 5,604
  • 47
  • 51
10

@LoLance's answer is perfect for Windows agents. For Linux agents, the syntax is slightly different (reverse the slash, and remove the /f flag):

    - task: CmdLine@2
      inputs:
        script: |
          echo "Structure of work folder of this pipeline:"
          tree $(Agent.WorkFolder)/1

          echo "Build.ArtifactStagingDirectory:" 
          echo "$(Build.ArtifactStagingDirectory)"

          echo "Build.BinariesDirectory:" 
          echo "$(Build.BinariesDirectory)"

          echo "Build.SourcesDirectory:"
          echo "$(Build.SourcesDirectory)"
Mike
  • 207
  • 3
  • 10
  • thx for the linux variation.. I was using powershell Get-ChildItem, but for some reason "my" linux agent does not print the filename.. – noontz Nov 08 '22 at 13:21
4

The documentation gives you examples of the folder structure. If that's not enough, add a PowerShell step that runs gci -rec -directory | select-object fullname or similar.

Daniel Mann
  • 57,011
  • 13
  • 100
  • 120
2

It looks more like this(work directory of an Agent):

enter image description here

Vidhya Sagar Reddy
  • 1,521
  • 1
  • 13
  • 25
1

Hi I was working in DevOps pipeline for AKS application deployment. I was not able to find the exact path of my deployment.yml and service.yml

My azure-pipeline.yml code is the following

trigger:
- master

resources:
- repo: self

variables:
  imageRepo: inboundapi
  tag: '$(Build.BuildId)'

stages:
- stage: Build
  displayName: Build image
  jobs:
  - job: Build
    displayName: Build
    pool:
      vmImage: ubuntu-latest
    steps:
    - task: Docker@2
      displayName: Build an image
      inputs:
        containerRegistry: 'msdacrconnect'
        repository: '$(imageRepo)'
        command: 'buildAndPush'
        Dockerfile: '**/Dockerfile'
        tags: |
          $(tag)
          latest
    - task: PublishPipelineArtifact@1
      inputs:
        targetPath: '$(Pipeline.Workspace)/s/manifests'
        artifact: 'manifests'
        publishLocation: 'pipeline'

- stage: Deploy
  displayName: Deploy image
  dependsOn: Build
  variables:
    acrsecret: aksacrsecret
  jobs:
    - job: Deploy
      displayName: Deploy to AKS
      pool:
        vmImage: ubuntu-latest
      steps:
        - task: DownloadPipelineArtifact@2
          inputs:
            buildType: 'current'
            artifactName: 'manifests'
            targetPath: '$(Pipeline.Workspace)/manifests'
        - task: KubernetesManifest@0
          inputs:
            action: 'createSecret'
            kubernetesServiceConnection: 'aksclustersvccon'
            namespace: 'inboundapiapp'
            secretType: 'dockerRegistry'
            secretName: '$(acrsecret)'
            dockerRegistryEndpoint: 'msdacrconnect'      
        - task: KubernetesManifest@0
          inputs:
            action: 'deploy'
            kubernetesServiceConnection: 'aksclustersvccon'
            namespace: 'default'
            manifests: |
              $(Pipeline.Workspace)/manifests/deployment.yml
              $(Pipeline.Workspace)/manifests/service.yml
          
          

It was showing me the following error

##[error]No manifest file(s) matching /home/vsts/work/1/s/'/home/vsts/work/1/deployment.yml','/home/vsts/work/1/service.yml' was found.

suddenly I got this post and checked with the following yml. It's work and I found my artifact path.

trigger:
- master

resources:
- repo: self

variables:
  imageRepo: inboundapi
  tag: '$(Build.BuildId)'

stages:
- stage: Deploy
  displayName: Deploy image
  variables:
    acrsecret: aksacrsecret
  jobs:
    - job: Deploy
      displayName: Deploy to AKS
      pool:
        vmImage: ubuntu-latest
      steps:        
        - task: CmdLine@2
          inputs:
            script: |
              echo "$(Pipeline.Workspace)"
              tree $(Pipeline.Workspace)
Sapnandu
  • 620
  • 7
  • 9