0

I am wondering actually more confused when to use the hypen in a YAML file in this case for use in Azure DevOps. I included the below YAML file as a demonstration of what I mean.

I hopefully am correct that I found out that hypens - are used when we use list items. So if I look at jobs: there are more jobs so each job is preceded with a -

Steps have tasks so the individual tasks ate preceded with a -

But when I look at variables. I would have expected them to be some sort of list ( i am not a developer) so what are they? Because the individual variables are not preceded with a -

Same as Pool: it doesn't have a hypen.

Same with inputs: I would have expected a - here as well for the individual inputs. So maybe a better question is to ask what are the indivdual pool, variables and inputs seen as why no hypen is used. I just can't seem to find an answer.

I hope I explained it clearly enough.

Regards,

John

trigger:
- none
stages:

- stage: Build
pool:
  vmImage: 'windows-latest'


jobs:
- job: Build


  variables:
    solution: '**/*.sln'
    buildPlatform: 'Any CPU'
    buildConfiguration: 'Release'

  steps:
  - task: NuGetToolInstaller@1

  - task: NuGetCommand@2
    inputs:
      restoreSolution: '$(solution)'

  - task: VSBuild@1
    inputs:
      solution: '$(solution)'
      msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:DesktopBuildPackageLocation="$(build.artifactStagingDirectory)\WebApp.zip" /p:DeployIisAppPath="Default Web Site"'
      platform: '$(buildPlatform)'
      configuration: '$(buildConfiguration)'


  - task: PublishPipelineArtifact@1
    inputs:
      targetPath: '$(Pipeline.Workspace)'
      artifact: 'drop'
      publishLocation: 'pipeline'

- stage: Deploy
pool:
  vmImage: 'windows-latest'

jobs:
- job: Deploy

  steps:

  - task: DownloadPipelineArtifact@2
    inputs:
      buildType: 'current'
      artifactName: 'drop'
      targetPath: '$(Pipeline.Workspace)'


  - task: AzureWebApp@1
    inputs:
      azureSubscription: 'tofreewebapp'
      appType: 'webApp'
      appName: 'freewebappdave'
      package: '$(Pipeline.Workspace)/drop/*.*'
      deploymentMethod: 'auto'












John
  • 53
  • 4
  • Hi John, If Flyx's answer is perfect to explain your question, you could Accept it as an Answer, it could help others to find this answer when they have the same confusion, thank you. – Edward Han-MSFT Apr 06 '21 at 01:48

1 Answers1

2

YAML has two kinds of collection nodes: sequences and mappings. When you use -, you indicate a sequence item. Sequence items are the content of sequences.

You use sequences when the identifying attribute of the contained values is their position. For example, for jobs, you have a first job, a second job and so on. Their order is meaningful and important.

Mappings on the other hand are collections that contain key-value-pairs. The key usually being a scalar (i.e. a textual value, like pool or vmImage) and the value being any kind of YAML node. For mappings, the identifying attribute of a value is its key. For example for variables, their order is not important, but their name is.

Mapping keys are usually indicated by a : after a scalar. So for example, jobs: is a mapping key jobs and indicates that its value follows. In our case, the value follows by means of a sequence.

Something that YAML does which can confuse people is that additional indentation for sequences is not necessary. For example, in this YAML

a:
  b: c
d:
e:

it is obvious that the key a has the value b: c, which is a nested mapping. The key d has an empty value becauset the following key e is at the same level.

However, with sequences you can do

a:
  - b
c:
- d
e:

Now, a's value is obviously - b, i.e. a nested sequence. However, c's values is, less obviously, also the nested sequence - d, while e: stops the previous sequence and starts a new value. This is important to understand the structure of your YAML file.

Now if you have a line like - job: Build, there are actually two things going on: - starts a sequence item, and job: starts a mapping which will be the value of this sequence item.

Mappings have two different uses: One use is that they identify substructures, such that for example a job has variables and steps. you cannot put a line droggeljug: in a job with some value, as that is not the name of a substructure. In variables, the mapping has a different use: You define any number of freely chosen names with corresponding values. It is a lookup table which you can later use to say „please give me the value mapped to solution“, and you will get **/*.sln.

So a YAML mapping is used for two different use-cases: Named substructures, and lookup tables (which is where the name mapping comes from). Even the root node of your YAML file is a mapping, with keys such as trigger, stages, pool etc.

Coming back to the question of why variables is not a list (or, in YAML terms, sequence): Variable names should be unique. In a sequence, you could have two items with identical name:

variables:
  - solution: '**/*.sln'
  - solution: 'droggeljug'

In a YAML mapping, identical keys are forbidden. We don't use a sequence to clearly indicate that the keys must be unique.

The answer to the question of why pool: doesn't contain a sequence is a different one: This is a known substructure that just isn't a sequence. It is a structure that can contain a name, demands and vmImage, therefore it is given as YAML mapping. There cannot be multiple pools in here, so a sequence would make no sense.

flyx
  • 35,506
  • 7
  • 89
  • 126
  • 1
    Thank you so much Flyx it all makes perfect sense now. I appreciate the extra depth you provided and examples given. – John Mar 30 '21 at 13:18