0

I am creating a custom task for Azure pipeline using TypeScript.

I have defined a filePath input:

{
    "name": "myFile",
    "label": "file to read",
    "type": "filePath",
    "required": true,
    "groupName": "files",
    "helpMarkDown": "file to read",
    "defaultValue": "",
    "visibleRule": "getFile = true"
},

The user is supposed to be able to define an unknown number of paths in the task.

  1. Is there a way to somehow generate the input dynamically in the task in a way that if a user browse a path, the gui will present another filePath input? If there is an option like that, how can I also iterate over them and download all the files to the pipeline?

  2. An alternative to 1 - I can have a simple string input in which I instruct the user to enter several paths. In this scenario how does a user extract the path of the file in the repo without the help of the browse button that the filePath input gives you?

jessehouwing
  • 106,458
  • 22
  • 256
  • 341
CodeMonkey
  • 11,196
  • 30
  • 112
  • 203
  • In general you'd set the textbox to multiline and then use the wildcard search support. https://github.com/microsoft/azure-devops-extension-tasks/blob/main/BuildTasks/PackageExtension/task.json#L57-L68 then either use the delimited input: https://github.com/microsoft/azure-devops-extension-tasks/blob/main/BuildTasks/Common/Common.ts#L44-L46 and optionally add wildcard support: https://github.com/microsoft/azure-devops-extension-tasks/blob/main/BuildTasks/Common/Common.ts#L75-L82 – jessehouwing Jun 23 '21 at 13:45
  • @jessehouwing the multi line and delimited input is exactly what I was aiming for, but I didn't understand so much the last part with the wild card.. could you please elaborate on that? Also, I am not sure what path does the user is supposed to give in the pipeline.. is there a special folder representing the root folder of the repo? If he has for example a file "myfile.yaml" in the root of the repo, what will be the path he needs to put in the input? – CodeMonkey Jun 23 '21 at 20:15
  • Your task can specify a root directory in it's task.json https://github.com/jessehouwing/azure-pipelines-tfvc-tasks/blob/main/tf-vc-checkin/v2/task.json#L217 the paths, by default, are relative from that directory. If a user enters an absolute path, the wokingdirectory prefix is ignored. – jessehouwing Jun 24 '21 at 12:48
  • @jessehouwing if you perhaps want to summarize it all to one answer which includes everything you showed me, I'll accept it – CodeMonkey Jun 25 '21 at 19:28
  • And it was accepted as promised – CodeMonkey Jun 28 '21 at 09:32

1 Answers1

0

Most tasks offer a multi-line textbox (optionally resizable), you can set this in the task.json:

{
      "name": "patternManifest",
      "type": "multiLine",
      "properties": {
        "resizable": true,
        "rows": "1"
      },
      "label": "Manifest file(s)",
      "defaultValue": "vss-extension.json",
      "required": false,
      "helpMarkDown": "Specify the pattern for manifest files. One file per line."
    },

Then in the task itself you use the tl.getDelimitedInput() and pass in the delimiters you want to support, in this task I require them to use newlines \n:

const globsManifest = tl.getDelimitedInput("patternManifest", "\n", false);

The tasklibrary has support for wildcard matching as well, that way people can add *, ** and ? to their inputs and the task will resolve these to actual files, then use the tl.findMatch() option.

            if (vsixFilePattern.indexOf("*") >= 0 || vsixFilePattern.indexOf("?") >= 0) {
                tl.debug("Pattern found in vsixFile parameter.");
                matchingVsixFile = tl.findMatch(process.cwd(), vsixFilePattern);
            }
            else {
                tl.debug("No pattern found in vsixFile parameter.");
                matchingVsixFile = [vsixFilePattern];
            }

The paths are relative by default and use the task's workingdirectory. When none is specified the working directory depends on the context of the task (build vs deploy pipeline):

  "execution": {
    "PowerShell3": {
      "target": "$(currentDirectory)\\TfvcCheckin.v3.ps1",
      "workingDirectory": "$(Build.SourcesDirectory)"
    }
  }

The user can always enter an absolute path instead of a relative one. And they can always add variables like $(Build.SourcesDirectory)\a\b\c to root the path to a predefined location.

jessehouwing
  • 106,458
  • 22
  • 256
  • 341