3

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

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?

0

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.

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 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. 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.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.