Skip to content

Building an OutSystems pipeline with Jenkins

duarte-castano edited this page Sep 25, 2023 · 25 revisions

This guide provides a step-by-step description of how to implement a recommended continuous delivery pipeline for OutSystems applications by leveraging the LifeTime Deployment API along with Jenkins, an open-source automation server.

Prerequisites

Please confirm that you have the following prerequisites before following the steps described in this guide:

Jenkins Plugins

Ensure that you have the following Jenkins plugins installed:

Plugin Name Version used for this guide
Blue Ocean 1.17.0
JUnit 1.28
Lockable Resources 2.7
Pyenv Pipeline 2.1.1
Pipeline Utility Steps 2.15.2
Workspace Cleanup Plugin 0.45

You can install these plugins through the Jenkins Plugin Manager.

Other Requirements

In addition to the Jenkins plugins, you must also meet the following requirements:

Jenkins Remote Access API

Make sure that LifeTime is able to make calls to the Jenkins Remote Access API.

Jenkins Agent

You should have at least one Jenkins agent with:

  • Python 3 installed

  • Access to PyPI.org

  • HTTPS connectivity with LifeTime

  • HTTPS connectivity with the front-end servers that are going to run test suites

Note:

Ensure that you also install the pip package installer in your agent.
Additionally, for Windows OS agents, make sure to activate the option "Add Python to PATH" in the installation wizard.

Step-by-step configuration guide

1. Register LifeTime Authentication Token as Jenkins Credential

You need to create a LifeTime service account and generate an authentication token to authenticate all requests to the Deployment API.

This token can then be configured as a Jenkins credential, allowing it to be reused throughout your pipelines via the corresponding credential ID, while keeping it secure and accessible only by authorized users.

From the Jenkins Dashboard, go to Credentials, select System and Global credentials (unrestricted) (or you can opt to store the credential in a different domain).

Select Add Credentials and provide the following configuration values:

  • Kind: Secret text
  • Scope: Global
  • Secret: <your LifeTime authentication token>
  • ID: LifeTimeServiceAccountToken
  • Description: Authentication token required for invoking LifeTime Deployment API.

Add Credentials

2. Publish OutSystems Forge Components

2.1 Publish Properties Services in all environments (Optional)

Properties Services allows you to get and set Site Properties, Timers, REST References, and SOAP Reverences from the pipelines.

To install the Properties Services, download the Properties Services and publish it on every environment that you'd like to have this functionality using Service Center. Alternatively, you can install the component directly from the Service Studio interface.

properties-services

2.2 Publish Properties Management in the LifeTime environment (Optional)

Properties Management provides the APIs to externally use the Properties Services component.

To install the Properties Management, download the Properties Management and publish it on the LifeTime environment using Service Center. Alternatively, you can install the component directly from the Service Studio interface.

properties-management

2.3 Publish CI/CD probe in the Regression environment

To retrieve environment-specific information that is required when running the continuous delivery pipeline, the CI/CD Probe Forge component must be installed on the Regression environment of your deployment pipeline.

To install the CI/CD probe, download the CI/CD Probe matching your Platform Server version and publish it on the Regression environment using Service Center. Alternatively, you can install the component directly from the Service Studio interface.

cicd-probe

Note

For the time being, the CI/CD Probe is only used for discovering the endpoints of existing BDD test scenarios in the target environment. Additional functionality may be added to the CI/CD Probe in future iterations.

3. Create Jenkins Pipeline using template definition file

To orchestrate the flow of activities for the continuous delivery pipeline you’ll need to create a Jenkins pipeline. The easiest way to do this is by providing a Jenkinsfile text file containing the pipeline definition.

A template Jenkinsfile for the OutSystems continuous delivery pipeline is provided here.

Create your own copy of the supplied Jenkinsfile template and make sure that the following pipeline environment variables are properly set inside the newly created Jenkinsfile:

Name Value Example value
LifeTimeHostname <Hostname of LifeTime environment> lifetime.example.com
LifeTimeAPIVersion <Version of LifeTime Deployment API to use> 2
DevelopmentEnvironmentLabel <Name of Development environment as defined on LifeTime> Development
RegressionEnvironmentLabel <Name of Regression environment as defined on LifeTime> Regression
AcceptanceEnvironmentLabel <Name of Acceptance environment as defined on LifeTime> Acceptance
PreProductionEnvironmentLabel <Name of Pre-Production environment as defined on LifeTime> Pre-Production
ProductionEnvironmentLabel <Name of Production environment as defined on LifeTime> Production
AuthorizationToken <ID of Jenkins credential that stores the LifeTime authentication token> -
CICDProbeEnvironmentURL <URL of environment where CI/CD probe is deployed> https://regression-env.acmecorp.com/
BDDFrameworkEnvironmentURL <URL of environment where BDD tests will run automatically> https://regression-env.acmecorp.com/

It is highly advisable to store your custom Jenkinsfile using a version control system such as Git, as this ensures that you are able to keep track of any changes made to your pipeline definition going forward. Additionally, any other supporting artifacts that you may need to run your continuous delivery pipeline can also be stored in a single location alongside the Jenkinsfile, and synced to the pipeline workspace folder on every run.

From the Jenkins Dashboard, go to New Item, select Pipeline and name it <YourApp>-CD-Pipeline.

Jenkins Pipeline

Note

To better organize your Jenkins dashboard you can opt to create the Jenkins pipeline inside an existing Folder.

In the Pipeline section, select option Pipeline script from SCM in the Definition field and provide the following configuration values:

  • SCM: <Source control management system that hosts the Jenkinsfile pipeline definition>
  • Repository URL: <URL of the Jenkinsfile in the source control management system>
  • Credentials: <Credentials used by Jenkins to fetch content from the source control management system>

The Jenkins pipeline created using the provided pipeline definition file contains 6 sequential stages, each one performing one or more actions as described in the following table:

Stage Actions performed
Install Python Dependencies Install required Python dependencies for running pipeline activities.
Get and Deploy Latest Tags Fetch the latest versions (tags) in DEV for the configured Applications and deploy them to REG environment.
Run Regression Generate Python script for running BDD test scenarios using unittest module.

Run unit test suite and publish test results report.
Accept Changes Deploy the latest versions (tags) for the configured applications (excluding test apps) from REG to ACC environment.

Wait for input from an authorized user to accept changes and proceed until production.
Deploy Dry-Run Deploy the latest versions (tags) for the configured applications from ACC to PRE environment.
Deploy Production If the dry-run is successful, immediately trigger the deployment to PRD of the latest versions (tags) for the configured applications.

Note

Most of the workload throughout the pipeline is performed by calling a set of functions from the outsystems-pipeline Python package, distributed by OutSystems on the Python Package Index (PyPI) repository.

The following picture shows a successful pipeline run using the Blue Ocean plugin:

Successful pipeline run

By leveraging the test-execution REST API, the Jenkins pipeline is able to run tests written with the BDD Framework in the list of configured test applications. The outcome of this action is presented as a JUnit test report that seamlessly integrates with the Jenkins UI, as shown in the following picture:

Test report

Whenever the Run Regression fails, the ongoing pipeline run is marked as unstable and all subsequent stages are skipped, thus preventing a release candidate version to proceed further down the pipeline. The pipeline test report displays which tests failed and why, for easier troubleshooting of the regression errors.

Pipeline run with failed regression

Test report with failed regression test

Whenever the pipeline reaches the Accept Changes stage, Jenkins halts the pipeline execution until an authorized user makes the decision to either accept or reject the release candidate version and proceed until production without further human intervention.

Pipeline run waiting for the decision of an authorized user

Jenkins UI waiting for input of an authorized user

This step in the pipeline definition serves as the "push-button" device mentioned in the Introduction section, where all the necessary actions for successfully deploying to production a release candidate that has gone through the deployment pipeline are carried out by pushing a button.

4. Trigger pipeline execution remotely

Triggering subsequent pipeline runs can be made directly from the Jenkins UI, as needed. This approach, however, is not desirable as it would require provisioning a Jenkins user account for each person that is allowed to trigger the pipeline - in the worst-case scenario, a Jenkins account per developer.

On the other hand, the purpose of the deployment pipeline is to reduce the amount of manual work required throughout the pipeline’s flow of activities.

To address this issue, the Trigger Pipeline LifeTime plugin available on the OutSystems Forge automatically detects when new versions (tags) are available for a configured subset of LifeTime applications and triggers an associated Jenkins pipeline by leveraging the Jenkins REST API.

4.1 Install the Trigger Pipeline LifeTime plugin

To install the Trigger Pipeline plugin, download the Trigger Pipeline plugin matching your Platform Server version and publish it to your LifeTime environment using Service Center. Alternatively, you can install the component directly from the Service Studio interface.

Trigger Pipeline on OutSystems Forge

4.2 Configure the Trigger Pipeline LifeTime plugin

Configure the Trigger plugin module in your Lifetime Service Center using the following steps.

4.2.1 Integrations configuration

Access the integrations tab and configure the following REST APIs:

  • LifeTimeAPI: https://your-lifetime-example.com/lifetimeapi/rest/v2
  • PropertiesAPI: https://your-lifetime-example.com/PropertiesAPI/rest/v1

4.2.2 Site Properties configuration

Access the Site Properties tab and configure the following properties:

  • Feature_UseTriggerManifest: True
  • ServiceAccountToken: <your LifeTime authentication token>

Note:

If you wish to tag changes on the fly when triggering the pipeline, the Service Account must have at least Change & Deploy permissions on the target environment.

4.3 Configure the plugin Default Server Settings

After the plugin is successfully published in the LifeTime environment, select Configure Triggers from the plugin landing page in LifeTime and configure the following parameters:

  • Source Environment: <Select your OutSystems Development environment>
  • Pipeline Server Type: Jenkins
  • Pipeline Server Address: <Your Jenkins instance base URL>
  • Pipeline Server Credentials: <Username and API token for Jenkins user account with enough permissions for running pipeline jobs>

Trigger Pipeline configuration

One or more pipeline triggers can be configured by providing the following data:

  • Pipeline: <Unique name that identifies the pipeline in Jenkins (including folders)>
  • Applications: <List of LifeTime applications that will trigger the CI/CD pipeline, identifying which ones are Test applications>

Configure applications that trigger the CI/CD pipeline

After the Trigger Pipeline plugin is properly configured, the dashboard screen will show the list of pipeline triggers, along with the current versions in Development of the LifeTime applications defined for each pipeline scope.

Once there are new application versions available for triggering a pipeline, a button is shown that allows running the pipeline on-demand without the need to log in to Jenkins.

List of pipelines that can be triggered on-demand

Alternatively, pipelines can be triggered automatically through the CheckNewVersionsForPipeline timer that periodically checks if there are new application versions in Development within the scope of each configured pipeline.

To enable this timer, go to the Service Center console of your LifeTime environment and configure a desirable schedule. The minimum configurable interval is 5 minutes.

Configure timer CheckNewVersionsForPipeline

Note

A pipeline cannot be triggered while there are still pending changes (within the pipeline scope) that have not yet been tagged in LifeTime. The reason for this is to avoid running the pipeline while the changeset is still open and the commit stage has not yet been finalized.