Skip to content

Examples⁠

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'