I have multiple Azure DevOps pipeline files with many stages like this:
...
- stage: 'qa'
dependsOn:
- dev
condition: |
and
(
condition1,
condition2,
...,
startswith(variables['Build.SourceBranch'], 'refs/heads/development')
)
# This needs to stay the same
- stage: 'uat'
dependsOn:
- dev
condition: |
and
(
condition1,
condition2,
...,
startswith(variables['Build.SourceBranch'], 'refs/heads/development')
)
...
Now we are updating all these files to new deployment strategy and I need to change two things - the dependsOn clause and the source branch refs/heads/development
in the condition - but only for the qa stage.
The result should look like this
...
- stage: 'qa'
dependsOn:
- build
condition: |
and
(
condition1,
condition2,
...,
startswith(variables['Build.SourceBranch'], 'refs/heads/main')
)
# This needs to stay the same
- stage: 'uat'
dependsOn:
- dev
condition: |
and
(
condition1,
condition2,
...,
startswith(variables['Build.SourceBranch'], 'refs/heads/development')
)
...
I am able to do the first part quite easily - I know there is always just one item in that array. So this will work sed "/stage: 'qa'/{ n; n; s/dev/build/g }" pipeline.yaml
But the second part is harder, there can be multiple conditions and I don't exactly know how many lines to skip.
Is there any way how to tell sed
to replace a string only in part of the file, lets say from 4 to 10 lines below occurrence of the stage: 'qa'
string?
For structured data, use structure-aware processors, not text processors that can only manipulate the textual representation without seeing/understanding the underlying logic).
Although the pipeline is yaml, that condition is not yaml so I would still need some text edit tool.
You could use the YAML processor mikefarah/yq, which also has text-processing capabilities (applicable to the condition):
yq 'map(select(.stage == "qa").condition |= sub("refs/heads/development"; "refs/heads/main"))'
- stage: 'qa'
dependsOn:
- build
condition: |
and
(
condition1,
condition2,
...,
startswith(variables['Build.SourceBranch'], 'refs/heads/main')
)
# This needs to stay the same
- stage: 'uat'
dependsOn:
- dev
condition: |
and
(
condition1,
condition2,
...,
startswith(variables['Build.SourceBranch'], 'refs/heads/development')
)