Different CI systems expose a variety of an array of information in environment variables for you to access, for example commit hash, branch, etc which is handy if you are writing CI tooling. Some of them even seek to standardize these conventions.
This post is primarily about collating that info into a single source for lookup. Ideally if you are writing tooling that you want a lot of people use you should support multiple CI systems to increase adoption.
As we look at each the first thing we need to do is tell which system is running, each CI platform has a convention to allow you to do this that we’ll talk about first
Below is a table of each Major build system and example bash of how to detect that the process is running in them, as a well as link to documentation on Env Vars that the system exposes.
Jenkins | “$JENKINS_URL” != “” |
Travis | “$CI” = “true” “$TRAVIS” = “true” |
AWS Codebuild | “$CODEBUILD_CI” = “true” |
Teamcity | “$TEAMCITY_VERSION” != “” |
Circle CI | “$CI” = “true” “$CIRCLECI” = “true” |
Semaphore CI | “$CI” = “true” “$SEMAPHORE” = “true” |
Drone CI | “$CI” = “drone” “$DRONE” = “true” |
Heroku | “$CI” = “true” “$HEROKU_TEST_RUN_BRANCH” != “” |
Appveyor CI | “$CI” = “true” || “$CI” = “True” “$APPVEYOR” = “true” || “$APPVEYOR” = “True” |
Gitlab CI | “$GITLAB_CI” != “” |
Github Actions | “$GITHUB_ACTIONS” != “” |
Azure Pipelines | “$SYSTEM_TEAMFOUNDATIONSERVERURI” != “” |
Bitbucket | “$CI” = “true” “$BITBUCKET_BUILD_NUMBER” != “” |
Below is 4 commonly used Parameters as an example, there are much more available, but as you can see form this list there is a lot of commonality.
Build System | branch | commit | PR # | Build ID |
Jenkins | ghprbSourceBranch GIT_BRANCH BRANCH_NAME | ghprbActualCommit GIT_COMMIT | ghprbPullId CHANGE_ID | BUILD_NUMBER |
Travis | TRAVIS_BRANCH | TRAVIS_PULL_REQUEST_SHA | TRAVIS_PULL_REQUEST | TRAVIS_JOB_NUMBER |
AWS Codebuild | CODEBUILD_WEBHOOK_HEAD_REF | CODEBUILD_RESOLVED_SOURCE_VERSION | CODEBUILD_SOURCE_VERSION | CODEBUILD_BUILD_ID |
Teamcity | BUILD_VCS_NUMBER | TEAMCITY_BUILD_ID | ||
Circle CI | CIRCLE_BRANCH | CIRCLE_SHA1 | CIRCLE_PULL_REQUEST | CIRCLE_BUILD_NUM |
Semaphore CI | SEMAPHORE_GIT_BRANCH | REVISION | PULL_REQUEST_NUMBER | SEMAPHORE_WORKFLOW_NUMBER |
Drone CI | DRONE_BRANCH | DRONE_PULL_REQUEST | DRONE_BUILD_NUMBER | |
Heroku | HEROKU_TEST_RUN_BRANCH | HEROKU_TEST_RUN_COMMIT_VERSION | HEROKU_TEST_RUN_ID | |
Appveyor CI | APPVEYOR_REPO_BRANCH | APPVEYOR_REPO_COMMIT | APPVEYOR_PULL_REQUEST_NUMBER | APPVEYOR_JOB_ID |
Gitlab CI | CI_BUILD_REF_NAME CI_COMMIT_REF_NAME | CI_BUILD_REF CI_COMMIT_SHA | CI_BUILD_ID CI_JOB_ID | |
Github Actions | GITHUB_REF | GITHUB_SHA | can get from Ref | GITHUB_RUN_ID |
Azure Pipelines | BUILD_SOURCEBRANCH | BUILD_SOURCEVERSION | SYSTEM_PULLREQUEST_PULLREQUESTID SYSTEM_PULLREQUEST_PULLREQUESTNUMBER | BUILD_BUILDID |
Bitbucket | BITBUCKET_BRANCH | BITBUCKET_COMMIT | BITBUCKET_PR_ID | BITBUCKET_BUILD_NUMBER |
For Teamcity a common work around to it’s lack of env vars is to place a root level set of parameters that will inherit to every config on the server
example
env.TEAMCITY_BUILD_BRANCH = %teamcity.build.branch%
env.TEAMCITY_BUILD_ID = %teamcity.build.id%
env.TEAMCITY_BUILD_URL = %teamcity.serverUrl%/viewLog.html?buildId=%teamcity.build.id%
env.TEAMCITY_BUILD_COMMIT = %system.build.vcs.number%