Skip to content

Application Registry Continuous Integration

The Application Registry encourages the use of Continuous Integration for building and delivering applications to the Atlas Manager.

To support quickly integrating applications with the Atlas Manager, Bash and Powershell scripts are provided to integrate into your pipelines.

Atlas currently provides quick start templates for Bitbucket Pipelines, Github Actions, Gitlab and Jenkins but other CI servers capable of executing Bash and Powershell scripts may easily utilize the Atlas upload scripts.

WARNING

This document attempts to provide a high-level quick start, but server configuration and access may vary. For support please contact your internal Continuous Integration Service Manager or reach-out to Upswell for clarification.

Before You Begin

This document assumes that:

  • You have supported CI platform, or platform capable of executing Bash or Powershell scripts as part of a build process
  • Your application is available in a Git repository, or other source control platform accessible to your CI server
  • You have a CI Service Account assigned to the CI/CD group

CI Server Dependencies

The Atlas Upload Script requires the following dependencies. Some container based systems may be able to install these dependencies at build time, while others may require that the be installed on the host build system:

Linux

  • curl
  • jq
  • openssl
  • zip

For Debian based systems:

bash
sudo apt install curl jq openssl zip

Windows

For Windows based systems:

JQ

powershell
winget install jqlang.jq
# or
scoop install jq  --global
# or
choco install jq

Or see JQ Downloads for executables.

CI Scripts

To simplify the process of shipping builds to the Application Registry, the Experience Manager provides Bash and Powershell scripts to do the heavy lifting. These are directly accessible and executable via the Experience Manager.

Pre-check

The ci-pre-check.sh and ci-pre-check.ps1 scripts are optional, but encouraged. It is used to validate a build prior to running executing the build and upload steps in the pipeline.

The primary responsibility of the pre-check script is to verify that the assumed VERSION number to be built does not already exist. Builds within the Application Registry are immutable and cannot be overwritten with the exception of dev.

To obtain the pre-check URL (with pipeline and execution examples), locate your Application in the Experience Manager: Applications / Applications, select your application and then Continuous Integration.

bash
curl -fsSL "https://<host>/get/ci-pre-check/sh/<application id>/" | bash
powershell
irm "https://<host>/get/ci-pre-check/ps1/<application id>/" | iex

Build Uploader

The ci.sh and ci.ps1 scripts are user to deliver builds to the Experience Manager. Similar to the ci-pre-check.sh and ci-pre-check.ps1 scripts, it may directly executed from the Experience Manager, with each Application assigned it's own URL. The Experience Manager provides templates for the different Integration Platforms.

When using the uploader scripts, the build delivery process is automated for you. The build will be zipped, uploaded and a record will be created in the Experience Manager for the new version. This process may be customized based on your build sever and process, see: Customizing Builds.

bash
curl -fsSL "https://<host>/get/ci/sh/<application id>/" | bash
powershell
irm "https://<host>/get/ci/ps1/<application id>/" | iex

Integration Platforms

Bitbucket Pipelines

WARNING

Bitbucket Pipelines only support building with Linux based containers. Windows applications capable of using Wine, such as Electron may work on Bitbucket, but most Windows applications should be built in a Windows based build environment.

Bitbucket Pipelines assumes that your projects Git repository is hosted on Bitbucket.

Quick start Bitbucket Pipelines templates are available in the Experience Manager, navigate to Applications (/applications/applications/) and select your Application and then select Bitbucket. Copy the template and create a file called bitbucket-pipelines.yml in the root of your directory.

Setup

To get started with Bitbucket Pipelines, open your repository in Bitbucket and select Repository Settings / Settings and then select Enable Pipeline.

Once you have Service Account credentials, select Repository Settings / Repository Variables and add them as XM_USERNAME and XM_PASSWORD.

Build Step

This Pipeline uses the Debian based debian:11-slim and the node:22.16.0 image to upload builds to the Experience Manager. You may choose to specify a langauge specific container such as node:22.16.0 or python:3.11-slim-bullseye in the templates &build step to ensure you start with the appropriate build dependencies.

yaml
steps:
- step: &precheck
    name: Pre-check
    script:
        - apt-get update && apt-get install -y curl jq openssl zip
        - curl -sSf "https://<host>/get/ci-pre-check/sh/<application id>/" | bash
- step: &build
    name: Build
    image: node:22.16.0
    caches:
        - node
    script:
        - yarn
        - yarn build
    artifacts:
        - dist/**
- step: &upload
    name: Upload
    script:
        - apt-get update && apt-get install -y curl jq openssl zip
        - curl -sSf "https://<host>/get/ci/sh/<application id>/" | bash

Github Actions

Github Actions supports building applications for multiple operating systems including Windows, Linux, and macOS. The platform uses YAML-based workflows stored in your repository.

Quick start Github Actions templates are available in the Experience Manager, navigate to Applications (/applications/applications/) and select your Application and then select Github Actions. Copy the template and create a file in your repository at .github/workflows/atlas-ci.yml.

Setup

To get started with Github Actions, your repository must be hosted on Github. Github Actions is enabled by default for most repositories.

Once you have Service Account credentials, navigate to your repository on Github and select Settings / Secrets and variables / Actions. Add your credentials as ATLAS_CI_USERNAME and ATLAS_CI_PASSWORD using the New repository secret button.

Build Step

The provided template uses Windows runners (runs-on: windows-latest) and PowerShell for build execution. The pipeline consists of three main steps: Pre-Check, Build, and Upload. You can customize the build step to match your application's requirements:

yaml
steps:
  - name: Pre-Check
    shell: pwsh
    run: |
      irm "https://<host>/get/ci-pre-check/ps1/<application id>/" | iex
    env:
      XM_USERNAME: ${{ secrets.ATLAS_CI_USERNAME }}
      XM_PASSWORD: ${{ secrets.ATLAS_CI_PASSWORD }}

  - name: Build
    shell: pwsh
    run: |
      npm install
      npm run build

  - name: Upload
    shell: pwsh
    run: |
      irm "https://<host>/get/ci/ps1/<application id>/" | iex
    env:
      XM_USERNAME: ${{ secrets.ATLAS_CI_USERNAME }}
      XM_PASSWORD: ${{ secrets.ATLAS_CI_PASSWORD }}

For cross-platform builds, create additional jobs with different runs-on values:

yaml
jobs:
  build-windows:
    name: Build Windows
    runs-on: windows-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Pre-Check
        shell: pwsh
        run: |
          irm "https://<host>/get/ci-pre-check/ps1/<application id>/" | iex
        env:
          XM_USERNAME: ${{ secrets.ATLAS_CI_USERNAME }}
          XM_PASSWORD: ${{ secrets.ATLAS_CI_PASSWORD }}

      - name: Build
        shell: pwsh
        run: |
          npm install
          npm run build

      - name: Upload
        shell: pwsh
        run: |
          irm "https://<host>/get/ci/ps1/<application id>/" | iex
        env:
          XM_USERNAME: ${{ secrets.ATLAS_CI_USERNAME }}
          XM_PASSWORD: ${{ secrets.ATLAS_CI_PASSWORD }}

  build-linux:
    name: Build Linux
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Pre-Check
        shell: bash
        run: |
          curl -sSf "https://<host>/get/ci-pre-check/sh/<application id>/" | bash
        env:
          XM_USERNAME: ${{ secrets.ATLAS_CI_USERNAME }}
          XM_PASSWORD: ${{ secrets.ATLAS_CI_PASSWORD }}

      - name: Build
        shell: bash
        run: |
          npm install
          npm run build

      - name: Upload
        shell: bash
        run: |
          curl -sSf "https://<host>/get/ci/sh/<application id>/" | bash
        env:
          XM_USERNAME: ${{ secrets.ATLAS_CI_USERNAME }}
          XM_PASSWORD: ${{ secrets.ATLAS_CI_PASSWORD }}

  build-macos:
    name: Build macOS
    runs-on: macos-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Pre-Check
        shell: bash
        run: |
          curl -sSf "https://<host>/get/ci-pre-check/sh/<application id>/" | bash
        env:
          XM_USERNAME: ${{ secrets.ATLAS_CI_USERNAME }}
          XM_PASSWORD: ${{ secrets.ATLAS_CI_PASSWORD }}

      - name: Build
        shell: bash
        run: |
          npm install
          npm run build

      - name: Upload
        shell: bash
        run: |
          curl -sSf "https://<host>/get/ci/sh/<application id>/" | bash
        env:
          XM_USERNAME: ${{ secrets.ATLAS_CI_USERNAME }}
          XM_PASSWORD: ${{ secrets.ATLAS_CI_PASSWORD }}

TIP

Github Actions provides hosted runners for Windows, Linux, and macOS. You can also use self-hosted runners if needed. See Github's documentation for available runner specifications.

WARNING

Each application has a different Application ID: /get/ci/ps1/00000000-0000-0000-0000-000000000000/. Ensure that when building an application for multiple OS's, you provide a different Application ID for each OS.

Gitlab

Gitlab CI/CD provides the ability to build applications for multiple OS's and architectures with one job so long as runners are available for those systems.

Quick start Gitlab CI/CD templates are available in the Experience Manager, navigate to Applications (/applications/applications/) and select your Application and then select Gitlab. Copy the template and create a file called .gitlab-ci.yml in the root of your repository.

When working with Gitlab, it is assumed that you are familiar with configuring Gitlab CI/CD via a .gitlab-ci.yml and that your Gitlab server has access to the Git repository for your application.

Setup

Once your repository is setup in Gitlab, you will need to provide your Service Account credentials. Navigate to your project in Gitlab and select Settings / CI/CD / Variables. Click Add variable and add the credentials as ATLAS_CI_USERNAME and ATLAS_CI_PASSWORD.

TIP

Mark these variables as Protected and Masked to ensure they are only available on protected branches and are not exposed in job logs.

Build Step

The provided template uses Windows runners with PowerShell and is configured to run on main and dev branches. The pipeline consists of three stages: pre-check, build, and upload. You can customize the build step to match your application's requirements:

yaml
pre-check:
  stage: pre-check
  tags: [windows]
  script:
    - irm "https://<host>/get/ci-pre-check/ps1/<application id>/" | iex
  rules:
    - if: '$CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "dev"'

build:
  stage: build
  tags: [windows]
  script:
    - npm install
    - npm run build
  artifacts:
    paths:
      - dist/
    expire_in: 1 hour
  rules:
    - if: '$CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "dev"'

upload:
  stage: upload
  tags: [windows]
  script:
    - irm "https://<host>/get/ci/ps1/<application id>/" | iex
  rules:
    - if: '$CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "dev"'

The template is setup to support parallel builds for multiple OS's and architectures. Additional stages may be added by changing the tags to match the appropriate Gitlab runner:

yaml
pre-check_windows_x86_64:
  stage: pre-check
  tags: [windows, x86_64]
  script:
    - irm "https://<host>/get/ci-pre-check/ps1/<application id>/" | iex
  rules:
    - if: '$CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "dev"'

build_windows_x86_64:
  stage: build
  tags: [windows, x86_64]
  script:
    - npm install
    - npm run build
  artifacts:
    paths:
      - dist/
    expire_in: 1 hour
  rules:
    - if: '$CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "dev"'

upload_windows_x86_64:
  stage: upload
  tags: [windows, x86_64]
  script:
    - irm "https://<host>/get/ci/ps1/<application id>/" | iex
  rules:
    - if: '$CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "dev"'

pre-check_linux_x86_64:
  stage: pre-check
  tags: [linux, x86_64]
  script:
    - curl -sSf "https://<host>/get/ci-pre-check/sh/<application id>/" | bash
  rules:
    - if: '$CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "dev"'

build_linux_x86_64:
  stage: build
  tags: [linux, x86_64]
  script:
    - npm install
    - npm run build
  artifacts:
    paths:
      - dist/
    expire_in: 1 hour
  rules:
    - if: '$CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "dev"'

upload_linux_x86_64:
  stage: upload
  tags: [linux, x86_64]
  script:
    - curl -sSf "https://<host>/get/ci/sh/<application id>/" | bash
  rules:
    - if: '$CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "dev"'

pre-check_macos_arm:
  stage: pre-check
  tags: [macos, arm]
  script:
    - curl -sSf "https://<host>/get/ci-pre-check/sh/<application id>/" | bash
  rules:
    - if: '$CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "dev"'

build_macos_arm:
  stage: build
  tags: [macos, arm]
  script:
    - npm install
    - npm run build
  artifacts:
    paths:
      - dist/
    expire_in: 1 hour
  rules:
    - if: '$CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "dev"'

upload_macos_arm:
  stage: upload
  tags: [macos, arm]
  script:
    - curl -sSf "https://<host>/get/ci/sh/<application id>/" | bash
  rules:
    - if: '$CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "dev"'

TIP

Take note of the label indicating which Gitlab should be used to build the application this will be different on your system. Consult with your Gitlab Service Manager, or review your Gitlab Runner tags under Settings / CI/CD / Runners, scroll down to Available specific runners or Shared runners to determine the appropriate labels.

WARNING

Each application has a different Application ID: /get/ci/ps1/00000000-0000-0000-0000-000000000000/. Ensure that when building an application for multiple OS’s, you provide a different Application ID for each OS.

Jenkins

Jenkins provides the ability to build applications for multiple OS's and architectures with one job so long as the build Nodes are available for those systems. As Jenkins is commonly used for building Windows applications, containers are not used in the pipeline examples and it is assumed that all build dependencies are installed on each Jenkins build Node.

Quick start Jenkins Pipeline templates are available in the Experience Manager, navigate to Applications (/applications/applications/) and select your Application and then select Jenkins. Copy the template and create a file called Jenkinsfile in the root of your repository.

When working with Jenkins, it is assumed that you are familiar with configuring Jenkins Pipelines via a Jenkinsfile and that your Jenkins server has access to the Git repository for your application.

Setup

If your Jenkins server does not already have stored Service Account credentials, select Manage Jenkins / Credentials and then select the global domain and + Add Credentials.

For each credential:

  1. On the New credentials screen, for Kind select Secret text
  2. For ID enter ATLAS_CI_USERNAME (or ATLAS_CI_PASSWORD)
  3. Provide the corresponding value in the Secret field
  4. Click Create

Repeat this process for both ATLAS_CI_USERNAME and ATLAS_CI_PASSWORD.

From here you may create a new Multibranch Pipeline pointing to your repository.

Build Step

The provided template uses Windows nodes with PowerShell and is configured to run on main and dev branches. The pipeline consists of three stages: Pre-Check, Build, and Upload, each with parallel execution support. You can customize the build step to match your application's requirements:

groovy
stage('Pre-Check') {
    when {
        anyOf {
            branch 'main'
            branch 'dev'
        }
    }
    parallel {
        stage('Windows x86_64') {
            agent {
                label 'windows'
            }
            steps {
                checkout scm
                powershell '''
                irm "https://<host>/get/ci-pre-check/ps1/<application id>/" | iex
                '''
            }
        }
    }
}

stage('Build') {
    when {
        anyOf {
            branch 'main'
            branch 'dev'
        }
    }
    parallel {
        stage('Windows x86_64') {
            agent {
                label 'windows'
            }
            steps {
                checkout scm
                powershell '''
                npm install
                npm run build
                '''
            }
        }
    }
}

stage('Upload') {
    when {
        anyOf {
            branch 'main'
            branch 'dev'
        }
    }
    parallel {
        stage('Windows x86_64') {
            agent {
                label 'windows'
            }
            steps {
                checkout scm
                powershell '''
                irm "https://<host>/get/ci/ps1/<application id>/" | iex
                '''
            }
        }
    }
}

The template is setup to support parallel builds for multiple OS's and architectures. Add additional sub-stages within the Pre-Check, Build and Upload stages:

groovy
// Pre-Check stage
parallel {
    stage('Windows x86_64') {
        agent {
            label 'windows'
        }
        steps {
            checkout scm
            powershell '''
            irm "https://<host>/get/ci-pre-check/ps1/<application id>/" | iex
            '''
        }
    }
    stage('Linux x86_64') {
        agent {
            label 'linux'
        }
        steps {
            checkout scm
            sh '''
            curl -sSf "https://<host>/get/ci-pre-check/sh/<application id>/" | bash
            '''
        }
    }
    stage('Linux ARM') {
        agent {
            label 'linux arm'
        }
        steps {
            checkout scm
            sh '''
            curl -sSf "https://<host>/get/ci-pre-check/sh/<application id>/" | bash
            '''
        }
    }
}

// Build stage
parallel {
    stage('Windows x86_64') {
        agent {
            label 'windows'
        }
        steps {
            checkout scm
            powershell '''
            npm install
            npm run build
            '''
        }
    }
    stage('Linux x86_64') {
        agent {
            label 'linux'
        }
        steps {
            checkout scm
            sh '''
            npm install
            npm run build
            '''
        }
    }
    stage('Linux ARM') {
        agent {
            label 'linux arm'
        }
        steps {
            checkout scm
            sh '''
            npm install
            npm run build
            '''
        }
    }
}

// Upload stage
parallel {
    stage('Windows x86_64') {
        agent {
            label 'windows'
        }
        steps {
            checkout scm
            powershell '''
            irm "https://<host>/get/ci/ps1/<application id>/" | iex
            '''
        }
    }
    stage('Linux x86_64') {
        agent {
            label 'linux'
        }
        steps {
            checkout scm
            sh '''
            curl -sSf "https://<host>/get/ci/sh/<application id>/" | bash
            '''
        }
    }
    stage('Linux ARM') {
        agent {
            label 'linux arm'
        }
        steps {
            checkout scm
            sh '''
            curl -sSf "https://<host>/get/ci/sh/<application id>/" | bash
            '''
        }
    }
}

TIP

Take note of the label indicating which Jenkins Node should be used to build the application this will be different on your system. Consult with your Jenkins Service Manager, or review your Jenkins Node Labels under Manage Jenkins / Nodes to determine the appropriate labels.

WARNING

Each application has a different Application ID: /get/ci/ps1/00000000-0000-0000-0000-000000000000/. Ensure that when building an application for multiple OS’s, you provide a different Application ID for each OS.

Customizing Builds

DEBUG_CI (Linux Only)

When building on Linux, with Bash, set DEBUG_CI to any value to trace each command as it runs.

DIR_DIST

The Experience Manager upload script assumes that your build distribution will be located in the ./dist directory. You may override this behavior in your Pipelines by setting the DIR_DIST environment variable. The DIR_WORKING (Bash) and $dir_working (Powershell) variables are available for use to build an absolute path to your build.

bash
export DIR_DIST="${DIR_WORKING}/my_build_directory"
powershell
$dir_dist="${DIR_WORKING}/my_build_directory"

DIR_WORKING

The DIR_WORKING variable ensures that the upload script is running from the right location. When using one of the supported Integration Platforms, DIR_WORKING will be set automatically and will default to the abolute path to the root folder of your version controlled project.

The default DIR_WORKING behavior may be changed by setting the DIR_WORKING variable, or environment variable prior to executing the upload script.

bash
export DIR_WORKING=/workspace/my-project/src/
powershell
$dir_working = "/workspace/my-project/src/"  # or
$env:DIR_WORKING = "/workspace/my-project/src/"

VERSION

The Atlas CI Upload Script will automatically manage the version number of your application unless you choose to override the VERSION environment variable and provide the application version.

By default, the application VERSION will be set to dev when built from branches named devor develop indicating the the build is a development pre-release.

TIP

dev is the only version in the Experience Manager that may be overwritten – overwritting other versions will raise an error.

For non-development branches, the build number will automatically be set to the CI server build number for that CI job/task. The incrementing behavior varies from playform to platform, but the build number will at minimum increment up +1 per build or per-branch build.

TIP

The default versioning behavior does not follow MAJOR.MINOR.PATCH semantic versioning. Versions will be a single integer only (i.e. 12).

You may choose to manage the version number by setting the VERSION environment variable. For instance, if you have a file named VERSION in the root of your propject, you could extract the version as follows:

bash
export VERSION=$(cat VERSION)

WARNING

When using VERSION you are responsible for all versioning, including dev builds.

ZIP_FILE_PATH

By default, the CI scripts will zip the contents of the DIR_DIST directory. This is unnecessary when building with tools like electron-builder that zip the completed bundles.

The ZIP_FILE_PATH var when set indicates to the script that the application is already zipped and ready to upload, skipping the zip bundle set.

For example, with electron-builder on Linux set:

sh
# Debian x64
export ZIP_FILE_PATH="${WORKSPACE}/dist/Upswell Cloud Web Wrapper-${VERSION}.zip"

# Debian arm64
export ZIP_FILE_PATH="${WORKSPACE}/dist/Upswell Cloud Web Wrapper-${VERSION}-arm64.zip"

Or for electron-builder on Windows set:

powershell
$env:ZIP_FILE_PATH = "$env:WORKSPACE\dist\Upswell Cloud Web Wrapper-$version-win.zip"

Atlas, Hybrid cloud, on-premesis platform for large scale media program development, delivery and operation.