michiel Thai
michiel Thai

Reputation: 597

Is it possible to import a script in a YAML Template

I have an Azure Repo called devops
My Pipeline has a resource declared called devops
Referencing to the template works:

 - template: templates/template.yaml@devops

in the devops/templates/template.yaml file I would like to add a step that executes a powershell script that is residing in devops/scripts/myscript.ps1

Is this possible? What would the syntax be in the template.yaml file?

I tried this, but it doesn't work:

steps:
  - task: PowerShell@2
    inputs:
      filePath: scripts/myscript.ps1@devops

Upvotes: 0

Views: 1318

Answers (3)

snydergd
snydergd

Reputation: 562

Another way you could accomplish this is through the REST API using System.AccessToken. You could have a reusable step template.

Example of what invoking the template could look like.

- template: ../steps/internal-run-template-powershell.yml
  parameters:
    scriptPath: stages-file-server-deploy/checkApprovals.ps1
    displayName: Check Approvers
    branch: my-branch

And the template itself could invoke the REST API could look like the following (note that in this case I am using PowerShell, but you could use whatever suits you best, and if you want it to be cross-platform without any special agent requirements you could always create a task extension with to use the built-in node.js).

parameters:
- name: scriptPath
  displayName: Where the script is located
  type: string
- name: displayName
  displayName: What you want this step to show up as
  default: Run script from pipeline
  type: string
- name: env
  displayName: Environment variables to pass to the script
  default: {}
  type: object
- name: repo
  displayName: Template repository
  default: your_template_repo_name
  type: string
- name: branch
  displayName: Template repository branch to use
  type: string

steps:
- task: PowerShell@2
  displayName: ${{ parameters.displayName }}
  inputs:
    targetType: inline
    script: |
      $templateRepo = "${{ parameters.repo }}"
      $script = "${{ parameters.scriptPath }}"
      $branch = "${{ parameters.branch }}"

      $authHeaders =  @{
          "Authorization" = "Basic " + ([convert]::ToBase64String([System.Text.Encoding]::UTF8.getBytes(":" + $env:SYSTEM_ACCESSTOKEN)))
      }

      $uri = "$env:SYSTEM_COLLECTIONURI/$env:SYSTEM_TEAMPROJECT/_apis/git/repositories/$templateRepo/items?path=$script&api-version=5.1"
      if ($branch -ne "") {
        $uri += "&versionDescriptor.version=$branch&versionDescriptor.versionType=branch"
      }
      "Running $uri"
      invoke-webrequest -outfile .script.ps1 -headers $authHeaders -UseBasicParsing `
          $uri
      & .script.ps1
  env:
    ${{ each v in parameters.env }}:
      ${{ v.key }}: ${{ v.value }}
    SYSTEM_ACCESSTOKEN: $(System.AccessToken)

This approach avoids the root template having to pass in the name of the resource, and also avoids the template itself having to rely on the root template for this.

Note that the system access token will need to have sufficient privilege for this. Privilege is determined by the user "Project Collection Build Service (account)".

Upvotes: 0

LoLance
LoLance

Reputation: 28096

Assuming these two repos are in same team project. Then:

Your template.yaml in devops repo should be:

steps:
  - task: PowerShell@2
    inputs:
      filePath: scripts/myscript.ps1

Your build definition in main repo should be:

resources:
  repositories:
    - repository: devops
      type: git
      name: ProjectName/devops

steps:
- checkout: devops
- template: template.yaml@devops

Since - checkout: devops will only download the content of the repos, scripts/myscript.ps1 is enough, we don't need scripts/myscript.ps1@devops. The direct cause of your issue is that Azure Devops Service won't automatically download the content of online devops repo to local agent. Just make sure the content of devops repo is download, and things will be ok.

Upvotes: 1

Krzysztof Madej
Krzysztof Madej

Reputation: 40573

Please try this:

#templates/template.yaml
parameters:
- name: repo  # defaults for any parameters that aren't specified
  default: ''

steps:
  - task: PowerShell@2
    inputs:
      filePath: ${{ parameters.repo }}/scripts/myscript.ps1

and build definition:

resources:
  repositories:
    - repository: devops
      type: github
      name: kmadof/devops-templates
      endpoint: kmadof

steps:
- checkout: self
- checkout: devops
- template: templates/template.yaml@devops
  parameters:
    repo: devops-templates

If you removed checkout: self you will get content of them devops repo directly in (Agent.BuildDirectory). Please take a look here for more info.

Upvotes: 2

Related Questions