Pull Request
This pipeline (pr-pipeline.yml) is invoked whenever you create or update a Pull Request (PR). Its purpose is to test that each of the added or updated PowerOns are valid.
trigger: none # This pipeline is triggered by pull requests via Branch Policies
# Dynamic variable group selection based on target branch
# PRs to main use prod credentials, PRs to stage use stage credentials, all others use dev
variables:
- ${{ if eq(variables['System.PullRequest.TargetBranch'], 'refs/heads/main') }}:
- group: symitar-prod
- ${{ elseif eq(variables['System.PullRequest.TargetBranch'], 'refs/heads/stage') }}:
- group: symitar-stage
- ${{ else }}:
- group: symitar-dev
pool:
name: ci-symitar
workspace:
clean: all
steps:
- checkout: self
fetchDepth: 0
# In the PR context, this will only validate changes between target and source branches
- task: ValidatePowerOn@1
displayName: 'Validate changed PowerOn files'
inputs:
connectionType: ssh
apiKey: $(apiKey)
symitarHostname: $(symitarHostname)
sshUsername: $(sshUsername)
sshPassword: $(sshPassword)
symitarUserNumber: $(symitarUserNumber)
symitarUserPassword: $(symitarUserPassword)
preserveServerFiles: RD.*,PFR.*
Merge Request
This pipeline (merge-pipeline.yml) is automatically invoked when PRs are merged to either main or stage branches and will do two things:
Validate Changed PowerOns
This is done by comparing the PR content relative to the target branch.
Prepare an Artifact
This will be referenced as "point in time" data to synchronize the Symitar host with during the release process
trigger:
branches:
include:
- main
- stage
# Dynamic variable group selection based on branch
variables:
- ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/main') }}:
- group: symitar-prod
- ${{ elseif eq(variables['Build.SourceBranch'], 'refs/heads/stage') }}:
- group: symitar-stage
- ${{ else }}:
- group: symitar-dev
pool:
name: ci-symitar
workspace:
clean: all
steps:
- checkout: self
fetchDepth: 0
# In the build context, this will validate differences between current state and what exists
# in the Sym number defined for the branch in .poweron-pipelines/config.yml
- task: ValidatePowerOn@1
displayName: 'Validate changed PowerOn files'
inputs:
connectionType: ssh
apiKey: $(apiKey)
symitarHostname: $(symitarHostname)
sshUsername: $(sshUsername)
sshPassword: $(sshPassword)
symitarUserNumber: $(symitarUserNumber)
symitarUserPassword: $(symitarUserPassword)
preserveServerFiles: RD.*,PFR.*
- task: ArchiveFiles@2
inputs:
rootFolderOrFile: '$(Build.SourcesDirectory)'
archiveFile: '$(Build.ArtifactStagingDirectory)/output.zip'
includeRootFolder: false
archiveType: zip
archiveFilePatterns: |
**/*
!.git/**
- task: PublishBuildArtifacts@1
displayName: 'Publish artifacts'
inputs:
pathtoPublish: '$(Build.ArtifactStagingDirectory)'
artifactName: 'output'
Release
This pipeline (release-pipeline.yml) is automatically invoked at the successful completion of our symitar-merge build pipeline which is just pointing to the merge-pipeline.yml file above. You'll notice it only triggers on main branch, since this pipeline includes both Stage and Prod deployments.
This pipeline has a bit more to it but can be split up in the following way:
Stage Validation -> Stage Deployment
All that you need to know here is that we're effectively doing the exact same thing only the *Validation stage is executing the SynchronizeDirectory task with isDryRun set to true so that we can visualize the prescribed changes prior to deployment and get any approvals necessary along the way.
Prod Validation -> Prod Deployment
For this section, we're doing the same work but for a different environment, Prod.
trigger: none
resources:
pipelines:
- pipeline: build
source: 'symitar-merge'
trigger:
branches:
include:
- main
stages:
# Stage Environment - Validate and deploy to Stage Sym first
- stage: StageValidation
displayName: 'Stage Validation (Dry Run)'
pool:
name: ci-symitar
variables:
- group: symitar-stage
jobs:
- deployment: ValidateStageSynchronization
displayName: 'Validate PowerOn Synchronization in Stage'
environment: 'Stage'
strategy:
runOnce:
deploy:
steps:
- download: build
artifact: output
- task: ExtractFiles@1
inputs:
archiveFilePatterns: '$(Pipeline.Workspace)/build/output/output.zip'
destinationFolder: '$(Build.ArtifactStagingDirectory)/repo'
- task: SynchronizeDirectory@1
displayName: 'Synchronize PowerOns to Stage (Dry Run)'
inputs:
directoryType: powerOns
syncMode: mirror
connectionType: ssh
isDryRun: true
artifactPath: 'repo'
symitarHostname: $(symitarHostname)
sshUsername: $(sshUsername)
sshPassword: $(sshPassword)
symitarUserNumber: $(symitarUserNumber)
symitarUserPassword: $(symitarUserPassword)
apiKey: $(apiKey)
preserveServerFiles: RD.*,PFR.*
- stage: StageDeployment
displayName: 'Stage Deployment'
dependsOn: StageValidation
condition: succeeded()
pool:
name: ci-symitar
variables:
- group: symitar-stage
jobs:
- deployment: SynchronizeStage
displayName: 'Synchronize PowerOns to Stage'
environment: 'Stage'
strategy:
runOnce:
deploy:
steps:
- download: build
artifact: output
- task: ExtractFiles@1
inputs:
archiveFilePatterns: '$(Pipeline.Workspace)/build/output/output.zip'
destinationFolder: '$(Build.ArtifactStagingDirectory)/repo'
- task: SynchronizeDirectory@1
displayName: 'Synchronize PowerOns to Stage'
inputs:
directoryType: powerOns
syncMode: mirror
connectionType: ssh
isDryRun: false
artifactPath: 'repo'
symitarHostname: $(symitarHostname)
sshUsername: $(sshUsername)
sshPassword: $(sshPassword)
symitarUserNumber: $(symitarUserNumber)
symitarUserPassword: $(symitarUserPassword)
apiKey: $(apiKey)
preserveServerFiles: RD.*,PFR.*
# Prod Environment - Requires manual approval via Azure DevOps Environment settings
- stage: ProdValidation
displayName: 'Prod Validation (Dry Run)'
dependsOn: StageDeployment
condition: succeeded()
pool:
name: ci-symitar
variables:
- group: symitar-prod
jobs:
- deployment: ValidateSynchronization
displayName: 'Validate PowerOn Synchronization'
environment: 'Prod'
strategy:
runOnce:
deploy:
steps:
- download: build
artifact: output
- task: ExtractFiles@1
inputs:
archiveFilePatterns: '$(Pipeline.Workspace)/build/output/output.zip'
destinationFolder: '$(Build.ArtifactStagingDirectory)/repo'
- task: SynchronizeDirectory@1
displayName: 'Synchronize PowerOns (Dry Run)'
inputs:
directoryType: powerOns
syncMode: mirror
connectionType: ssh
isDryRun: true
artifactPath: 'repo'
symitarHostname: $(symitarHostname)
sshUsername: $(sshUsername)
sshPassword: $(sshPassword)
symitarUserNumber: $(symitarUserNumber)
symitarUserPassword: $(symitarUserPassword)
apiKey: $(apiKey)
preserveServerFiles: RD.*,PFR.*
- stage: Prod
displayName: 'Prod Deployment'
dependsOn: ProdValidation
condition: succeeded()
pool:
name: ci-symitar
variables:
- group: symitar-prod
jobs:
- deployment: SynchronizePowerOns
displayName: 'Synchronize PowerOns in Prod'
environment: 'Prod'
strategy:
runOnce:
deploy:
steps:
- download: build
artifact: output
- task: ExtractFiles@1
inputs:
archiveFilePatterns: '$(Pipeline.Workspace)/build/output/output.zip'
destinationFolder: '$(Build.ArtifactStagingDirectory)/repo'
- task: SynchronizeDirectory@1
displayName: 'Synchronize PowerOns to Prod'
inputs:
directoryType: powerOns
syncMode: mirror
connectionType: ssh
isDryRun: false
artifactPath: 'repo'
symitarHostname: $(symitarHostname)
sshUsername: $(sshUsername)
sshPassword: $(sshPassword)
symitarUserNumber: $(symitarUserNumber)
symitarUserPassword: $(symitarUserPassword)
apiKey: $(apiKey)
preserveServerFiles: RD.*,PFR.*
Pull Server-Managed Files
This workflow pulls only files listed in preserveServerFiles, commits them to a reusable branch, and opens or updates an Azure Repos pull request. Use this when Symitar generates or rewrites files that should be reviewed before landing back in your repository.
trigger: none
pool:
name: ci-symitar
variables:
- group: symitar-prod
steps:
- checkout: self
persistCredentials: true
- task: SynchronizeDirectory@1
displayName: 'Pull server-managed PowerOns'
inputs:
directoryType: powerOns
syncMode: pull
connectionType: https
isDryRun: false
artifactPath: $(Build.SourcesDirectory)
repositoryPath: $(Build.SourcesDirectory)
symitarHostname: $(symitarHostname)
symitarAppPort: $(symitarAppPort)
sshUsername: $(sshUsername)
sshPassword: $(sshPassword)
symitarUserNumber: $(symitarUserNumber)
symitarUserPassword: $(symitarUserPassword)
apiKey: $(apiKey)
preserveServerFiles: RD.*,PFR.*
pullPreservedOnly: true
createPullRequest: true
pullRequestBranch: chore/symitar-pull
pullRequestTargetBranch: main
pullRequestTitle: 'chore: sync server-managed Symitar files'