Michal Checinski

Using files from other stage in Azure pipelines

April 20, 2020 , posted under Azure
Using files from other stage in Azure pipelines

When we build Azure pipeline using yaml we often need to use files that are generated in one stage in the next stage. Recently I stumbled upon this problem when I wanted to build project in the first stage of the pipeline and then publish output files in the next stage.

To use files from previous stages in Azure Pipelines you first need to ‘export’ them. This process is called publish artifact. It is done by adding this task at the end of the stage you want to use your files from:

steps:
- publish: $(System.DefaultWorkingDirectory)/build
  artifact: BuildedApp

Then in the stage that you want to use files from the stage above you need to download those files aka. artifact.

steps:
- download: current
  artifact: BuildedApp

Downloaded artifacts location caveat

So after downloading an artifact, they will be available to use in the next steps in a pipeline stage. But they are not located where you think they’d be. At least where I thought.

First I tried to access artifact in the default location where tasks start to execute: $(Build.Repository.LocalPath) (eg. c:\agent_work\1\s). So I added the following task to test it:

steps:
- download: current
  artifact: BuildedApp
- script: ls ./BuildedApp

Sadly I found out that the artifact is not there. After a few tries, it turned out that the artifacts are downloaded one folder above directory that your tasks start in the worker. So the solution will be to access them like that:

steps:
- download: current
  artifact: BuildedApp
- script: ls ../BuildedApp

But I don’t like using relative paths in scripts and pipelines. What if in the future someone will add commands or scripts that change directory before those tasks? The pipeline will fail because of relative paths. So I found a predefined variable containing path to a folder where artifacts are downloaded to. You can check other predefined variables in the docs. Using that variable, the pipeline will look like that:

steps:
- download: current
  artifact: BuildedApp
- script: ls $(Agent.BuildDirectory)/BuildedApp

Whole pipeline

The whole pipeline with export files from the Build stage and import artifact in Publish stage to use files in Publish stage generated in Build stage would look like:

stages:
  - stage: Build
    displayName: Build
    jobs:
      - job: Build
        displayName: Build
        pool:
          vmImage: 'ubuntu-latest'
        steps:
          - script: $(System.DefaultWorkingDirectory)/bin/build.sh
          - publish: $(System.DefaultWorkingDirectory)/build
            artifact: BuildedApp

  - stage: Publish
    displayName: Publish
    dependsOn:
      - Build
    jobs:
      - job: Publish
        displayName: Publish
        pool:
          vmImage: 'ubuntu-latest'
        steps:
          - download: current
            artifact: BuildedApp
          - script: $(System.DefaultWorkingDirectory)/bin/publish.sh $(Agent.BuildDirectory)/BuildedApp

In this post, I’ve shown you a solution for files generated in one stage to be used in another stage in the same Azure Pipeline.

Enjoy!