Answers: <p>I think I see what you are after. Build variables created in the Variables tab of the GUI designer are scoped to the entire definition. But you can set a Job Scoped variable from a script within a <a href="https://docs.microsoft.com/en-us/azure/devops/pipelines/process/variables?view=azure-devops&amp;tabs=classic%2Cpowershell#set-variables-in-scripts" rel="nofollow noreferrer">GUI based pipeline</a>. </p>
  
  <p>So within the context of each of the Agent Jobs you have defined above, you would add a powershell task that would allow you to set the variable(s) that you then use for the automagic variable substitution in your xml.</p>
  
  <h3>YAML is better</h3>
  
  <p>If you want to go the <a href="https://docs.microsoft.com/en-us/azure/devops/pipelines/get-started/pipelines-get-started?view=azure-devops&amp;tabs=yaml" rel="nofollow noreferrer">YAML definition</a> route you can actually create Job scoped variables directly in yaml. This example below substitutes against a JSON file but the concepts are similar for xml.</p>
  
  <p>This is the Json file it substitutes against <code>test.json</code>.</p>
  
  <pre><code>{
      "menu": {
          "id": "file",
          "value": "File"
      }
  }
  </code></pre>
  
  <pre><code>trigger:
  - master
  
  pool:
    vmImage: 'ubuntu-latest'
  
  jobs:
  - job: Production
    variables:
      - name: menu.id # Substituting this value in test.json
        value: 'productionValue'
    steps:
      - task: FileTransform@1
        displayName: 'File Transform:'
        inputs:
          folderPath: '$(System.DefaultWorkingDirectory)'
          fileType: json
          targetFiles: test.json
      - task: PowerShell@2
        inputs:
            targetType: 'inline'
            script: |
              Get-Content -Path test.json
  
  - job: Staging
    variables:
      - name: menu.id  # Substituting this value in test.json
        value: 'stagingValue'
    steps:
      - task: FileTransform@1
        displayName: 'File Transform:'
        inputs:
          folderPath: '$(System.DefaultWorkingDirectory)'
          fileType: json
          targetFiles: test.json
      - task: PowerShell@2
        inputs:
            targetType: 'inline'
            script: |
              Get-Content -Path test.json
  </code></pre>
  
  <h3>Custom Conditions</h3>
  
  <p>Another thing you might want to dig into is that Azure DevOps exposes task level <a href="https://docs.microsoft.com/en-us/azure/devops/pipelines/process/conditions?view=azure-devops&amp;tabs=classic" rel="nofollow noreferrer">custom conditions</a>. You could add both transform tasks for Stage and Production to the pipeline definition and then only conditionally run the step you want. You could potentially collapse this into just one job and only build what you need to.</p>
  
  <p>You need to decide on what that condition is. For example, you could do it based on the source branch (probably better) or just a variable that you can set at queue time. </p>
  
Answers: CC BY-SA 4.0
Answers: 2020-01-25T09:35:06.903Z
Answers: 2020-01-25T09:41:39.143Z
Answers: 2020-01-25T09:41:39.143Z
Answers: Eric Smith
Body: <p>On Azure DevOps I need to build and deploy a ClickOnce application. Because this application needs to be signed (including config) I must create a build for staging and a build for production. </p>
  
  <p>I decided to create an artifact for my App with 2 tasks:</p>
  
  <p><a href="https://i.sstatic.net/GLriv.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/GLriv.png" alt="enter image description here"></a></p>
  
  <p>At the moment I'm using the XML transformation to apply my specific staging or production settings. It is working fine but I would like to use the Variables substitution system build in Azure DevOps. I already use it in Deployment part for all my IIS project deployment. But in Deployment I have "stage" and I can easily tell the system to use my staging variable in staging stage and production one for my production stage. I cannot do that in Build Pipeline section.</p>
  
  <p>What can I do? Should I create 2 separate builds with 2 separate artifact?</p>
  
Tags: <azure-devops><azure-pipelines>
Title: How to arrange builds for staging and production with Azure DevOps?
UserDisplayName: Bastien Vandamme
ThreadText: # How to arrange builds for staging and production with Azure DevOps?
  
  (Asked by: username_0 on 2020-01-14)
  
  On Azure DevOps I need to build and deploy a ClickOnce application. Because this application needs to be signed (including config) I must create a build for staging and a build for production.
  
  I decided to create an artifact for my App with 2 tasks:
  
  [![enter image description here](https://i.sstatic.net/GLriv.png)](https://i.sstatic.net/GLriv.png)
  
  At the moment I'm using the XML transformation to apply my specific staging or production settings. It is working fine but I would like to use the Variables substitution system build in Azure DevOps. I already use it in Deployment part for all my IIS project deployment. But in Deployment I have "stage" and I can easily tell the system to use my staging variable in staging stage and production one for my production stage. I cannot do that in Build Pipeline section.
  
  What can I do? Should I create 2 separate builds with 2 separate artifact?
  
  **Tags:** azure-devops, azure-pipelines
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2020-01-25. Score: 1
  
  I think I see what you are after. Build variables created in the Variables tab of the GUI designer are scoped to the entire definition. But you can set a Job Scoped variable from a script within a [GUI based pipeline](https://docs.microsoft.com/en-us/azure/devops/pipelines/process/variables?view=azure-devops&tabs=classic%2Cpowershell#set-variables-in-scripts).
  
  So within the context of each of the Agent Jobs you have defined above, you would add a powershell task that would allow you to set the variable(s) that you then use for the automagic variable substitution in your xml.
  
  ### YAML is better
  
  If you want to go the [YAML definition](https://docs.microsoft.com/en-us/azure/devops/pipelines/get-started/pipelines-get-started?view=azure-devops&tabs=yaml) route you can actually create Job scoped variables directly in yaml. This example below substitutes against a JSON file but the concepts are similar for xml.
  
  This is the Json file it substitutes against `test.json`.
  
  ```
  {
      "menu": {
          "id": "file",
          "value": "File"
      }
  }
  
  ```
  
  ```
  trigger:
  - master
  
  pool:
    vmImage: 'ubuntu-latest'
  
  jobs:
  - job: Production
    variables:
      - name: menu.id # Substituting this value in test.json
        value: 'productionValue'
    steps:
      - task: FileTransform@1
        displayName: 'File Transform:'
        inputs:
          folderPath: '$(System.DefaultWorkingDirectory)'
          fileType: json
          targetFiles: test.json
      - task: PowerShell@2
        inputs:
            targetType: 'inline'
            script: |
              Get-Content -Path test.json
  
  - job: Staging
    variables:
      - name: menu.id  # Substituting this value in test.json
        value: 'stagingValue'
    steps:
      - task: FileTransform@1
        displayName: 'File Transform:'
        inputs:
          folderPath: '$(System.DefaultWorkingDirectory)'
          fileType: json
          targetFiles: test.json
      - task: PowerShell@2
        inputs:
            targetType: 'inline'
            script: |
              Get-Content -Path test.json
  
  ```
  
  ### Custom Conditions
  
  Another thing you might want to dig into is that Azure DevOps exposes task level [custom conditions](https://docs.microsoft.com/en-us/azure/devops/pipelines/process/conditions?view=azure-devops&tabs=classic). You could add both transform tasks for Stage and Production to the pipeline definition and then only conditionally run the step you want. You could potentially collapse this into just one job and only build what you need to.
  
  You need to decide on what that condition is. For example, you could do it based on the source branch (probably better) or just a variable that you can set at queue time.
  
  
  ---
  
  