Search code examples
powershellazure-devopsazure-pipelinesdevopsazure-pipelines-yaml

Read a variable from a .ps1 file and run a .ps1 script inside Pipeline with Git Repo


I am using Azure DevOps repos, and I am working on a pipeline. I want it to read a variable from config.ps1 file and set a env variable with it. After that I want to run a powershell script. It gives errors with the path and reading the parameters.

I would like to instead of reading this config.yml and install this module, I would like to have something more straightforward like a config.ps1 just stating the variable. Then retrieve that variable here and assign it to an env variable.

trigger:
- main
- test

pool:
  vmImage: 'windows-latest'

variables:
  MES_SERVER_USERNAME: '$(SERVER_USERNAME)'
  MES_SERVER_PASSWORD: '$(SERVER_PASSWORD)'
  TEST_SERVER_IP: '$(TEST_IP)'
  PROD_SERVER_IP: '$(PROD_IP)'

stages:
  - stage: DeployToServer
    jobs:
      - deployment: DeployToTest
        displayName: 'Deploy to Test Deployment Group'
        condition: eq(variables['Build.SourceBranch'], 'refs/heads/test')
        environment: 'TestEnvironment'
        strategy:
          runOnce:
            deploy:
              steps:
                - powershell: |
                    Install-Module -Name powershell-yaml -Force -Scope CurrentUser
                    $config = Import-Yaml -Path "../config.yml"
                    $env:TGRP_FOLDER_PATH = $config.variables.TGRP_FOLDER_PATH

                    $organization = "$(System.CollectionUri)"
                    $project = "$(System.TeamProject)"
                    $buildId = "$(Build.BuildId)"
                    $patToken = "$(System.AccessToken)"

                    $uri = "$organization/$project/_apis/build/builds/$buildId/changes?api-version=6.0"
                    $headers = @{ Authorization = "Bearer $patToken" }

                    $changedFiles = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers |
                                    ForEach-Object { $_.value.items.path }

                    Write-Host "Changed files:"
                    $changedFiles | ForEach-Object { Write-Host $_ }

                    $changedFilesPath = "$(System.DefaultWorkingDirectory)/changedFiles.txt"
                    $changedFiles | Out-File -FilePath $changedFilesPath

                    $scriptPath = "$(System.DefaultWorkingDirectory)/scripts/update-aip.ps1"
                    Write-Host "Running PowerShell script at: $scriptPath"
                    & $scriptPath -ChangedFilesPath $changedFilesPath
                  displayName: 'Get Changed Files and Run PowerShell script'
                  env:
                    SYSTEM_DEFAULTWORKINGDIRECTORY: $(System.DefaultWorkingDirectory)
                    MES_SERVER_USERNAME: $(MES_SERVER_USERNAME)
                    MES_SERVER_PASSWORD: $(MES_SERVER_PASSWORD)
                    TEST_SERVER_IP: $(TEST_SERVER_IP)
                    PROD_SERVER_IP: $(PROD_SERVER_IP)

      - deployment: DeployToMain
        displayName: 'Deploy to Main Deployment Group'
        condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
        environment: 'MainEnvironment'
        strategy:
          runOnce:
            deploy:
              steps:
                - powershell: |
                    Install-Module -Name powershell-yaml -Force -Scope CurrentUser
                    $config = Import-Yaml -Path "../config.yml"
                    $env:TGRP_FOLDER_PATH = $config.variables.TGRP_FOLDER_PATH

                    $organization = "$(System.CollectionUri)"
                    $project = "$(System.TeamProject)"
                    $buildId = "$(Build.BuildId)"
                    $patToken = "$(System.AccessToken)"

                    $uri = "$organization/$project/_apis/build/builds/$buildId/changes?api-version=6.0"
                    $headers = @{ Authorization = "Bearer $patToken" }

                    $changedFiles = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers |
                                    ForEach-Object { $_.value.items.path }

                    Write-Host "Changed files:"
                    $changedFiles | ForEach-Object { Write-Host $_ }

                    $changedFilesPath = "$(System.DefaultWorkingDirectory)/changedFiles.txt"
                    $changedFiles | Out-File -FilePath $changedFilesPath

                    $scriptPath = "$(System.DefaultWorkingDirectory)/scripts/update-aip.ps1"
                    Write-Host "Running PowerShell script at: $scriptPath"
                    & $scriptPath -ChangedFilesPath $changedFilesPath
                  displayName: 'Get Changed Files and Run PowerShell script'
                  env:
                    SYSTEM_DEFAULTWORKINGDIRECTORY: $(System.DefaultWorkingDirectory)
                    MES_SERVER_USERNAME: $(MES_SERVER_USERNAME)
                    MES_SERVER_PASSWORD: $(MES_SERVER_PASSWORD)
                    TEST_SERVER_IP: $(TEST_SERVER_IP)
                    PROD_SERVER_IP: $(PROD_SERVER_IP)

Solution

  • I want it to read a variable from config.ps1 file and set a env variable with it.

    I want to read a static value from a file

    Instead of using the following snippet:

    $config = Import-Yaml -Path "../config.yml"
    $env:TGRP_FOLDER_PATH = $config.variables.TGRP_FOLDER_PATH
    

    Try using a variable defined in the pipeline or a in a variables template?

    For example, a variable defined as follows:

    variables:
      - name: TGRP_FOLDER_PATH
        value: /my/folder/
    

    Will be accessible as an environment variable using macro syntax $(TGRP_FOLDER_PATH).

    Example

    Using variables templates for each environment:

    # /pipelines/variables/main-variables.yaml
    
    variables:
      - name: TGRP_FOLDER_PATH
        value: /my/main/folder/
    
    # /pipelines/variables/test-variables.yaml
    
    variables:
      - name: TGRP_FOLDER_PATH
        value: /my/test/folder/
    

    Using each template in a different job:

    # /pipelines/my-pipeline.yaml
    
    stages:
      - stage: DeployToServer
        jobs:
          - deployment: DeployToTest
            displayName: 'Deploy to Test Deployment Group'
            condition: eq(variables['Build.SourceBranch'], 'refs/heads/test')
            environment: 'TestEnvironment'
            variables:
              - template: /pipelines/variables/test-variables.yaml # <---------- reference variables template
            strategy:
              runOnce:
                deploy:
                  steps:
                    - checkout: none
                    - powershell: |
    
                        echo "$(TGRP_FOLDER_PATH)" # Output: /my/test/folder/
    
                        # rest of the script here
                      displayName: 'Get Changed Files and Run PowerShell script'
    
          - deployment: DeployToMain
            displayName: 'Deploy to Main Deployment Group'
            condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
            environment: 'MainEnvironment'
            variables:
              - template: /pipelines/variables/main-variables.yaml # <---------- reference variables template
            strategy:
              runOnce:
                deploy:
                  steps:
                    - checkout: none
                    - powershell: |
    
                        echo "$(TGRP_FOLDER_PATH)" # Output: /my/main/folder/
    
                        # rest of the script here
                      displayName: 'Get Changed Files and Run PowerShell script'