CI Pipeline Usage Guide
PALISADE's CI pipelines are defined in ".gitlab-ci.yml", and are designed to work with GitLab's CI. Portability and usage in alternative CI workflows is neither guaranteed nor supported at this time.
This guide is intended to serve as an overview of PALISADE's own CI pipelines, for more information on the GitLab CI system itself, please use the GitLab CI documentation.
For this guide, CI/CD must be enabled for your repository, and you must have a UNIX-based shell "runner" capable of compiling and installing PALISADE. If you need more information on setting up GitLab's Runner Servers, please use the GitLab Runner Documentation.
By default, the CI system will not start a pipeline on a push, unless it is to the branch ref master
, or for a merge request via the GitLab site. Both of these actions initiate the same pipeline of tasks.
If you want to run a pipeline on any other branch, pipelines can only be manually instantiated via the GitLab site.
There is only one type of non-automatic CI Pipeline available; Manual (Full) CI.
Triggering the Manual (Full) CI
The Manual Full CI pipeline, labeled manual
in the code, runs all tests and benchmarks in the master
pipeline.
To start a pipeline via the GitLab site, navigate to the "Run Pipeline" page, which can be located at the following URL: https://gitlab.com/\${COMPANY}/\${REPOSITORY}/pipelines/new
, substituting your company and repository name appropriately.
Once there, set the variable DO_CI
to Y
or YES
, and run the pipeline. The interface before running should look similar to this image
Structure of the CI system
The ".gitlab-ci.yml" contains all pipelines, CI pipelines are split up into stages, which in turn are split into jobs. It is our intention for ".gitlab-ci.yml" to reflect this in its structure. Pipelines are defined in blocks of the file which are separate from other pipeline blocks, and they share no stages or jobs. Likewise, jobs for specific stages, like build
or unit_test
, are kept together.
As a rule of thumb jobs with _manual
are part of the manual CI pipeline, and jobs without it are part of the default pipeline.
Build-specific jobs also have unique identifiers of the build prefixed to their job name (test_pke
is default_test_pke
for default_build
).
When extending the CI, it is recommended to follow a similar format.
Supported builds for PALISADE:
Build Name | Description |
---|---|
default_build | The default build for the library. |
noflag_mb4_build | Build using Math Backend 4, with no additional flags |
debug_mb2_build | Build using Math Backend 2, with debug mode on |
debug_mb4_build | Build using Math Backend 4, with debug mode on |
ntl_mb6_build | Build using Math Backend 6, which requires the NTL lib |
tcm_mb2_build | Build using Math Backend 2 and tcmalloc |
tcm_mb4_build | Build using Math Backend 4 and tcmalloc |
tcm_ntl_mb6_build | Build using Math Backend 6, tcmalloc, and NTL |
debug_tcm_ntl_mb6_build | Build using Math Backend 6, tcmalloc, and NTL, with debug mode on |
When adding jobs which are being executed for multiple builds, this table may be a helpful reference.
Extending the CI
There are a few principal ways to extend the CI: adding a new build, adding a new test, or adding a new pipeline.
Adding a new test
- Copy the following template and edit in your test name and executable instructions/path
default_${CUSTOM_TEST_NAME}_test:
stage: unit_test
only:
refs:
- master
- merge_requests
script:
- ./${CUSTOM_TEST_PATH}
artifacts:
paths:
- test_detail.xml
expire_in: 2 days
dependencies:
- default_build
Once complete, add it to the unit_test
stage for the default branch.
- Copy your customized template from Step 1 and create new jobs for all builds. You will need to replace the
dependencies
section with the target build, and you'll also need to make a unique job name for each job. The pattern we use is to prefix the build's name to the standard job name (pke_test
->default_pke_test
fordefault_build
). Here is a list of the builds included in the CI:
- default_build
- noflag_mb4_build
- debug_mb2_build
- debug_mb4_build
- ntl_mb6_build
- tcm_mb2_build
- tcm_mb4_build
- tcm_ntl_mb6_build
- debug_tcm_ntl_mb6_build
Descriptions can be located in the "Supported Builds for PALISADE" section above.
When complete, append these tests to unit_test
stage of the target pipeline (the template is intended for use with the default pipeline).
- To add your test to the Manual CI, you will need to copy the jobs from the previous steps and replace the
only
section in the following way.
only:
refs:
- master
- merge_requests
becomes
only:
variables:
- $DO_CI
for the new set of tests. You will also need to provide a unique name for the job. The format we use is appending _manual
to the job names (default_pke_test
becomes default_pke_test_manual
). Append them to the end of the unit_test stage for the Manual Pipeline when complete.
Adding new builds
Lets say you're adding a new build to the CI, named my_new_build
.
- Create a new build job using the following format:
my_new_build:
stage: build
only:
refs:
- master
- merge_requests
script:
- ./my_build_script.sh
artifacts:
paths:
- build/third-party/lib
- build/lib
- build/unittest
- build/bin/benchmark
expire_in: 1 day
dependencies: []
Replace the script
section with the shell instructions for the new build. Also, if your build generates binaries outside of the normal build
directory, add the path to the directory/files to the artifacts: paths:
section.
Append this job to the build
stage of the default pipeline.
- To add unit tests for your build, copy the unit tests from another build and change the
dependencies
job ref to your new build, in this examplemy_new_build
. For example, my_new_build_test_pke would be:
my_new_build_test_pke:
stage: unit_test
only:
refs:
- master
- merge_requests
script:
- build/unittest/pke_tests --gtest_output=xml
artifacts:
paths:
- test_detail.xml
expire_in: 2 days
dependencies:
- my_new_build
To ensure a unique job name, we recommend prefixing the job name with some identifier of the build (like default
for default_build
). When complete, these jobs should be placed into the unit_test
stage of the default pipeline.
- To add the build to the Manual CI, copy all jobs from the previous steps, place them in the appropriate stages (
build
->build
) of the Manual CI pipeline, and replace theonly
section.
only:
refs:
- master
- merge_requests
becomes
only:
variables:
- $DO_CI
for the new set of jobs (builds and tests). You will also need to provide a unique name for the job. The format we use is appending _manual
to the job names (my_new_build
becomes my_new_build_manual
).
Adding a new pipeline
- If you're interested in making a new pipeline using, or partially using, an existing set of jobs, you'll first need to decide the conditions you want the pipeline to run for. This will determine the constraint you set in the
only
section of your jobs. Is there a specific branch ref you want this pipeline to run on? Use theonly: refs:
constrains
only:
refs:
- my_target_branch
Are you trying to have a manually/conditionally triggered branch? Use only:variables:
constraint
only:
variables:
- $DO_MY_PIPELINE
- After you've decided on your constraint, you'll need to copy the build jobs you want to a new pipeline block, and edit their constraints appropriately. For example, to add the default build to a branch running only on branch ref
my-stable-release
default_build_stable_release:
stage: build
only:
refs:
- my-stable-release
script:
- mkdir -p build
- cd build
- CC=gcc CXX=g++ cmake ..
- make -j $(nproc) all
artifacts:
paths:
- build/third-party/lib
- build/lib
- build/unittest
- build/bin/benchmark
expire_in: 1 day
dependencies: []
Additionally, you'll need to give the job a unique name. We use the pattern of appending some pipeline identifier to the end of the job name (default_build
becomes default_build_manual
for manual CI pipeline)
- After adding your builds, you can copy the rest of the jobs to the same pipeline block. Similar to the builds, we'll need to change both the constraints section as well as creating a new, unique name for the job. All jobs related to or using the build though will need to add the build names to the
dependencies
section. For a jobdefault_pke_test_stable_release
default_test_pke_stable_release:
stage: unit_test
only:
refs:
- my-stable-release
script:
- build/unittest/pke_tests --gtest_output=xml
artifacts:
paths:
- test_detail.xml
expire_in: 2 days
dependencies:
- default_build_stable_release