Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Storing script output as a list in azure devops build pipeline

In my project i use nrwl Nx monorepo for angular.

When you run the command nx affected:apps <args> it shows the apps your code change has affected in the last commit or the pullrequest changes (this is handled by the args)

For example (this is looking back 20 commits to find the changes):

Output of nx affected:apps

Resume and test are both names of apps.

What I want from my build:

  • npm install
  • Run nx affected and store output in a variable 'affectedApps'
  • Run nx affected --target=build (this builds all affected projects)
  • Foreach( app in affectedApp)
    • Add appname in a buildtag (not in my code yet)
    • Build and push the buildouput for the specific app in docker

I have a hard time understanding how i can get the output of nx affected in a variable that I can loop over

Here is what I ended up with:

    trigger:
  - main
pr:
  - main

variables:
  ${{ if eq(variables['Build.SourceBranchName'], 'main') }}:
    NX_BRANCH: 'main'
  ${{ if ne(variables['Build.SourceBranchName'], 'main') }}:
    NX_BRANCH: $(System.PullRequest.PullRequestNumber)
  # - name: affectedApps
  #   value: [] 

jobs:
  - job: main
    pool:
      vmImage: 'ubuntu-latest'
    condition: ne(variables['Build.Reason'], 'PullRequest')
    steps:
      - script: npm i
        workingDirectory: Clients/Web/

      - bash: |
            affectedApps=$(node node_modules/@nrwl/cli/bin/nx.js affected:apps  --base=HEAD~10  --head=HEAD | grep -E '( - )(\w|-|\d|_)+' | sed -E 's/ - //g')
            echo "##vso[task.setvariable variable=affectedApps;isOutput=true]${affectedApps}"
            
        workingDirectory: Clients/Web/
           # echo "##vso[task.setvariable variable=affectedApps;isOutput=true]${affectedApps}"
      - bash: |
            echo "${affectedApps}"
      - bash: |
            echo $(affectedApps)
        workingDirectory: Clients/Web/
      - script: npx nx affected --base=HEAD~10 --target=build --parallel --max-parallel=3
        workingDirectory: Clients/Web/
      - script: echo $(affectedApps)
      # - template: /Clients/Web/Deployment/Pipelines/dockerPush.task.yml
      #   parameters:
      #     apps: $(affectedApps)
      #     tag: $(tag)

The commented out template I made has the following code: (/Clients/Web/Deployment/Pipelines/dockerPush.task.yml)

parameters:
  - name: "apps"
    type: object
    default: []
  - name: "tag"
    type: string
    default: "latest"
 
steps:
  - ${{ each app in parameters.apps }}:
      - task: Docker@2
        displayName: "Build & Push ${{app}}"
        inputs:
          containerRegistry: 'Digital Ocean  Registry'
          repository: 'registry/Apps/${{app}}'
          command: 'buildAndPush'
          Dockerfile: 'Clients/Web/Deployment/Dockerfile'
          buildContext: '$(Build.SourcesDirectory)'
          tags: ${{tag}}
          arguments: '--build-arg project=${{app}}' 

Can someone show me the way?

like image 711
RoXaS Avatar asked Nov 20 '25 12:11

RoXaS


1 Answers

echo "##vso[task.setvariable variable=affectedApps;isOutput=true]${affectedApps}"

Above command is correct to set the variable, but as you have marked the isoutput to true, to use the same variable you will need to use $(stepname.variablename) expression. isoutput is used when you want to use the variable in subsequent jobs or stages. If you want to use the variable in subsequent steps/scripts tasks then do not set isoutput=true, then you can use the expression $(variableName) in subsequent steps

ref: https://learn.microsoft.com/en-us/azure/devops/pipelines/scripts/logging-commands?view=azure-devops&tabs=bash#examples-1

https://learn.microsoft.com/en-us/azure/devops/pipelines/process/expressions?view=azure-devops#job-to-job-dependencies-within-one-stage

like image 119
scorpio Avatar answered Nov 23 '25 03:11

scorpio