Skip to content
| Marketplace
Sign in
Azure DevOps>Azure Pipelines>PowerOn Pipelines
PowerOn Pipelines

PowerOn Pipelines

Libum

libum.io
|
22 installs
| (0) | Free
Deploy, install, and validate your PowerOns within your pipelines
Get it free

PowerOn Pipelines — CI/CD for the Symitar Core

PowerOn Pipelines is an extension for Azure DevOps which brings managed releases and version control to Symitar, the Jack Henry™ credit union core platform.

What can I do with PowerOn Pipelines?

Keep your organization's production code safe with the tasks in PowerOn Pipelines. With PowerOn Pipelines, you can begin to create true CI/CD for your PowerOn files—that deploy, install, and even validate your PowerOns all through an Azure Pipeline.

Symitar Integration

Connect to your Symitar core through an Azure Pipeline to validate PowerOns when a PR is opened or deploy & install when they're complete. Each task supports both connection methods:

Available Tasks:

  • SynchronizeDirectory - Synchronizes any Symitar directory (PowerOns, LetterFiles, DataFiles, or HelpFiles) with your repository. Choose between HTTPs (faster) or SSH connection.
  • ValidatePowerOn - Validates PowerOn files which have been modified between branches in your Symitar repository. Choose between HTTPs (fastest) or SSH connection.

Directory Types:

Type Symitar Directory Default Local Path Install Support
powerOns REPWRITERSPECS REPWRITERSPECS/ Yes
letterFiles LETTERSPECS LETTERSPECS/ No
dataFiles DATAFILES DATAFILES/ No
helpFiles HELPFILES HELPFILES/ No

All tasks include a connectionType picker that allows you to select:

  • HTTPs (faster) - Uses our fast API over HTTPs for rapid deployment and validation
  • SSH - Connects directly over SSH for maximum compatibility

All tasks also support a syncMethod option for file transfer transport:

  • SFTP (default) - Secure file transfer with concurrent uploads (configurable concurrency 1-20, default 4)
  • rsync - Faster for large directories, requires rsync + sshpass installed on the ADO agent

All synchronization tasks require specifying a syncMode:

  • Push - Upload local files to Symitar (one-way upload)
  • Pull - Download files from Symitar to local (one-way download)
  • Mirror - Make Symitar match the local directory exactly, including deleting extra files on Symitar

Server-managed files can be preserved during synchronization and validation:

  • Use the preserveServerFiles array in .poweron-pipelines/config.yml for repository-wide defaults.
  • Use the task preserveServerFiles input as a comma-delimited override when a single task needs a different list.
  • Use pullPreservedOnly with syncMode: pull to pull only preserved files from Symitar.
  • Use createPullRequest with syncMode: pull to commit pulled repository changes to a branch and open or reuse an Azure Repos PR. No commit is created during dry run.
  • Use commitPulledChanges only when the task should push directly to the checked-out branch.

Configuration

PowerOn Pipelines uses a configuration file to define branch-to-Sym mappings and other settings. Create a .poweron-pipelines/config.yml file in your repository root:

# .poweron-pipelines/config.yml

# Local directories for each Symitar directory type (must end with /)
inputs:
  powerOnsDirectory: REPWRITERSPECS/
  letterFilesDirectory: LETTERSPECS/
  dataFilesDirectory: DATAFILES/
  helpFilesDirectory: HELPFILES/

# Map branches to Sym numbers for validation and deployment
branchSymNumbers:
  main: 0        # Production Sym
  staging: 627   # Staging Sym

# PowerOns to install after synchronization (optional)
installPowerOns:
  - MYSPECFILE.INSTALL

# PowerOns to skip during validation (optional)
validateIgnorePowerOns:
  - TEST.PO
  - DEPRECATED.PO

# Files generated or managed by Symitar that should be preserved from the server (optional)
preserveServerFiles:
  - RD.*
  - PFR.*

Configuration Options

Option Description Default
inputs.powerOnsDirectory Directory containing PowerOn files (must end with /) REPWRITERSPECS/
inputs.letterFilesDirectory Directory containing LetterFiles (must end with /) LETTERSPECS/
inputs.dataFilesDirectory Directory containing DataFiles (must end with /) DATAFILES/
inputs.helpFilesDirectory Directory containing HelpFiles (must end with /) HELPFILES/
branchSymNumbers Map of branch names to Sym numbers {}
installPowerOns PowerOn files to install after sync []
validateIgnorePowerOns PowerOn files to skip during validation []
preserveServerFiles Exact filenames or glob patterns to preserve from the server []

Usage

This section provides a quick overview of the primary use cases for the tasks available in PowerOn Pipelines. Be sure to also check out our official PowerOn Pipeline Docs

With PowerOn Pipelines, your organization gains version control for the Symitar environment and the ability to have managed releases through native Azure DevOps role-based approvals. We will also soon be releasing Deployment Protections within PowerOn Pro giving your org the flexibility to prevent deployments to target Syms and gate everything through Azure DevOps using Prod, UAT, and Staging environments.

The Symitar repository

Your organization will need to have a central Symitar repository which will be the source of truth for what should exist on your remote Symitar host.

Azure DevOps Symitar repository

In the repository, you can place all PowerOn files under a configurable directory. In the screenshot above, we chose to take the default REPWRITERSPECS/ which mirrors the remote directory name on the Symitar host.

Making PowerOn changes

The intent behind our validation tasks is that prior to checking in a PR, and when creating an official build, the updated PowerOns can be validated to ensure they function properly after deployment.

Invalid PowerOn in Azure DevOps pull request

If you've managed to forget to validate a PowerOn prior to upstreaming the changes, these tasks will prevent those changes from getting too far in the development lifecycle. Once you've identified if any PowerOn needs attention, you can publish new changes to get them fixed.

Passing merge validation in Azure DevOps pull request

After completing the PR, you can also do a final check for changed PowerOns between check ins when creating the Official Build for Symitar.

Passing validation when creating a Symitar Official Build

Deploying PowerOn to different stages

Manage the state of any Sym using build artifacts from your Symitar repository that works both forwards and backwards in time. Additionally, you can run in a dry run mode to observe the changes prior to physically deploying them.

Dry run synchronization of a Sym

Create a classic release pipeline to deploy build artifacts to your Prod, UAT, and Staging environments. As mentioned above, you can include a Validation stage that instructs an engineer to view & sign-off on the dry run results prior to giving the final deployment approval.

Symitar release pipeline for Production

Pipeline Examples

Validate PowerOns on Pull Request

# azure-pipelines-pr.yml
trigger: none

pr:
  branches:
    include:
      - main
      - staging

variables:
  - group: symitar

pool:
  name: ci-symitar

steps:
  - checkout: self
    fetchDepth: 0  # Required for git diff

  - task: ValidatePowerOn@1
    displayName: Validate PowerOn files
    inputs:
      connectionType: https
      syncMethod: sftp           # Optional: sftp (default) or rsync
      symitarHostname: $(SYMITAR_HOSTNAME)
      symitarAppPort: $(SYMITAR_APP_PORT)
      sshUsername: $(SSH_USERNAME)
      sshPassword: $(SSH_PASSWORD)
      symitarUserNumber: $(SYMITAR_USER_NUMBER)
      symitarUserPassword: $(SYMITAR_USER_PASSWORD)
      apiKey: $(API_KEY)

When preserveServerFiles is configured in .poweron-pipelines/config.yml, matched files are skipped during PR validation and build validation. You can override the repository list for a specific task with a comma-delimited input:

- task: ValidatePowerOn@1
  displayName: Validate PowerOn files
  inputs:
    connectionType: https
    symitarHostname: $(SYMITAR_HOSTNAME)
    symitarAppPort: $(SYMITAR_APP_PORT)
    sshUsername: $(SSH_USERNAME)
    sshPassword: $(SSH_PASSWORD)
    symitarUserNumber: $(SYMITAR_USER_NUMBER)
    symitarUserPassword: $(SYMITAR_USER_PASSWORD)
    apiKey: $(API_KEY)
    preserveServerFiles: RD.*,PFR.*

Synchronize PowerOns on Release

# azure-pipelines-release.yml
trigger:
  branches:
    include:
      - main

variables:
  - group: symitar

pool:
  name: ci-symitar

steps:
  - task: SynchronizeDirectory@1
    displayName: Synchronize PowerOns (Dry Run)
    inputs:
      directoryType: powerOns
      connectionType: https
      syncMode: mirror
      syncMethod: sftp           # Optional: sftp (default) or rsync
      sftpConcurrency: 4         # Optional: 1-20, default 4
      isDryRun: true
      artifactPath: $(Build.ArtifactStagingDirectory)/drop
      symitarHostname: $(SYMITAR_HOSTNAME)
      symitarAppPort: $(SYMITAR_APP_PORT)
      sshUsername: $(SSH_USERNAME)
      sshPassword: $(SSH_PASSWORD)
      symitarUserNumber: $(SYMITAR_USER_NUMBER)
      symitarUserPassword: $(SYMITAR_USER_PASSWORD)
      apiKey: $(API_KEY)

Preserve Server-Managed Files During Sync

Use preserveServerFiles for files generated or forcibly updated by Symitar. In push and mirror mode, matched files are not overwritten or deleted from the server.

- task: SynchronizeDirectory@1
  displayName: Mirror PowerOns while preserving server-managed files
  inputs:
    directoryType: powerOns
    connectionType: https
    syncMode: mirror
    isDryRun: false
    artifactPath: $(Build.ArtifactStagingDirectory)/drop
    symitarHostname: $(SYMITAR_HOSTNAME)
    symitarAppPort: $(SYMITAR_APP_PORT)
    sshUsername: $(SSH_USERNAME)
    sshPassword: $(SSH_PASSWORD)
    symitarUserNumber: $(SYMITAR_USER_NUMBER)
    symitarUserPassword: $(SYMITAR_USER_PASSWORD)
    apiKey: $(API_KEY)
    preserveServerFiles: RD.*,PFR.*

Pull Preserved Files Back to Git

Use pullPreservedOnly to pull only server-managed files. If the preserve list is empty, the task is a no-op.

The preferred repository update flow is createPullRequest: true. It commits pulled changes to a reusable source branch and opens or reuses an Azure Repos PR, so branch policies and reviewers stay in the loop. The pipeline needs checkout: self with persistCredentials: true for the Git push, and the build service identity needs permission to contribute to the PR branch and create pull requests.

- checkout: self
  persistCredentials: true

- task: SynchronizeDirectory@1
  displayName: Pull server-managed PowerOns
  inputs:
    directoryType: powerOns
    connectionType: https
    syncMode: pull
    isDryRun: false
    artifactPath: $(Build.ArtifactStagingDirectory)/drop
    repositoryPath: $(Build.SourcesDirectory)
    symitarHostname: $(SYMITAR_HOSTNAME)
    symitarAppPort: $(SYMITAR_APP_PORT)
    sshUsername: $(SSH_USERNAME)
    sshPassword: $(SSH_PASSWORD)
    symitarUserNumber: $(SYMITAR_USER_NUMBER)
    symitarUserPassword: $(SYMITAR_USER_PASSWORD)
    apiKey: $(API_KEY)
    preserveServerFiles: RD.*,PFR.*
    pullPreservedOnly: true
    createPullRequest: true
    pullRequestBranch: chore/symitar-pull
    pullRequestTargetBranch: main
    pullRequestTitle: 'chore: sync server-managed Symitar files'

For repositories where direct pushes are acceptable, use commitPulledChanges: true instead of createPullRequest: true.

- checkout: self
  persistCredentials: true

- task: SynchronizeDirectory@1
  displayName: Pull and directly commit server-managed PowerOns
  inputs:
    directoryType: powerOns
    connectionType: https
    syncMode: pull
    isDryRun: false
    artifactPath: $(Build.ArtifactStagingDirectory)/drop
    repositoryPath: $(Build.SourcesDirectory)
    symitarHostname: $(SYMITAR_HOSTNAME)
    symitarAppPort: $(SYMITAR_APP_PORT)
    sshUsername: $(SSH_USERNAME)
    sshPassword: $(SSH_PASSWORD)
    symitarUserNumber: $(SYMITAR_USER_NUMBER)
    symitarUserPassword: $(SYMITAR_USER_PASSWORD)
    apiKey: $(API_KEY)
    preserveServerFiles: RD.*,PFR.*
    pullPreservedOnly: true
    commitPulledChanges: true
    commitBranch: main

Detect Server-Side Drift While Pulling Preserved Files

When syncMode: pull and pullPreservedOnly: true, the task reports server files that differ from the repository but do not match preserveServerFiles. These outliers are not pulled. The task logs a warning and exposes output variables so the pipeline can fail or notify reviewers.

- checkout: self
  persistCredentials: true

- task: SynchronizeDirectory@1
  name: pull
  displayName: Pull server-managed PowerOns and detect drift
  inputs:
    directoryType: powerOns
    connectionType: https
    syncMode: pull
    isDryRun: false
    artifactPath: $(Build.ArtifactStagingDirectory)/drop
    repositoryPath: $(Build.SourcesDirectory)
    symitarHostname: $(SYMITAR_HOSTNAME)
    symitarAppPort: $(SYMITAR_APP_PORT)
    sshUsername: $(SSH_USERNAME)
    sshPassword: $(SSH_PASSWORD)
    symitarUserNumber: $(SYMITAR_USER_NUMBER)
    symitarUserPassword: $(SYMITAR_USER_PASSWORD)
    apiKey: $(API_KEY)
    preserveServerFiles: RD.*,PFR.*
    pullPreservedOnly: true
    createPullRequest: true
    pullRequestBranch: chore/symitar-pull
    pullRequestTargetBranch: main
    pullRequestTitle: 'chore: sync server-managed Symitar files'

- pwsh: |
    Write-Error "Server-side drift detected outside preserved patterns: $(pull.outlierFiles)"
  displayName: Fail on server-side drift
  condition: ne(variables['pull.outliersCount'], '0')

Synchronize Multiple Directory Types

# Synchronize PowerOns and LetterFiles
steps:
  - task: SynchronizeDirectory@1
    displayName: Synchronize PowerOns
    inputs:
      directoryType: powerOns
      connectionType: https
      syncMode: mirror
      isDryRun: false
      artifactPath: $(Build.ArtifactStagingDirectory)/drop
      # ... connection inputs ...

  - task: SynchronizeDirectory@1
    displayName: Synchronize LetterFiles
    inputs:
      directoryType: letterFiles
      connectionType: https
      syncMode: mirror
      isDryRun: false
      artifactPath: $(Build.ArtifactStagingDirectory)/drop
      # ... connection inputs ...

Custom Local Directory Path

# Use a custom local directory path instead of the default
steps:
  - task: SynchronizeDirectory@1
    displayName: Synchronize PowerOns from custom path
    inputs:
      directoryType: powerOns
      localDirectoryPath: src/poweron/  # Custom path instead of REPWRITERSPECS/
      connectionType: https
      syncMode: mirror
      isDryRun: false
      artifactPath: $(Build.ArtifactStagingDirectory)/drop
      # ... connection inputs ...

Using Task Outputs

The ValidatePowerOn task provides output variables you can use in subsequent steps:

- task: ValidatePowerOn@1
  name: validate
  inputs:
    # ... inputs ...

- script: |
    echo "Files validated: $(validate.filesValidated)"
    echo "Files passed: $(validate.filesPassed)"
    echo "Files failed: $(validate.filesFailed)"
  displayName: Show validation results

Contributing

We at Libum are committed to improving the software development process of Jack Henry™ credit unions. The best way for you to contribute / get involved is communicate ways we can improve the PowerOn Pipelines feature set.

Please share your thoughts with us through our Feedback Portal, on our Libum Community Discord, or at development@libum.io

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2026 Microsoft