This is the core CICD Server in version 4.\ For an implementation example, please have a look at https://github.com/bmoers/sn-cicd-example/tree/release/4.
The aim of this project is to CICD-enable ServiceNow. Where CICD is used heavily in professional application development these days, there is no such thing in ServiceNow out-of-the-box. As the number of projects we implemented in ServiceNow grow, as more we struggled with doing thing right. It is just too dangerous to oversee an unwanted record in an update set or not having a clue if a change would do any harm on the platform.\ The difference between 'classic' software development and the way it works in ServiceNow is how changes are captured. In ServiceNow that's the job of an 'update set' or a 'scoped application' (see it as db row-dump in XML) - the others just use GIT for that.
So how difficult must it be to extract all code inside an 'update set' into a GIT repo and send it to a CICD pipeline?
Actually not very....
With this CICD-Server we mimic a local developer working in its IDE and committing code to a GIT repo and pushing it to origin. Every update set is represented as a branch on which then also the build process runs (build on branch, merge to master). If the build on branch is successful, the update set is deployed to the integration ServiceNow environment (e.g. test or integrated dev). Have a look at the Process Flow for detailed information.
As the code is now in a GIT repo, standard tools like Bamboo or Jenkins etc can be used to trigger a longer pipeline with further stages to bring changes to production.
Export, Build, Test and Deploy an Service-Now Update-Set.
On request (received from Service-Now) do:
npm install
gulp
complete
Steps | Dev | Prod (master) | Code | Comment |
---|---|---|---|---|
Run CICD | ||||
Setup GIT repo on GIT host if required | lib\modules\run.js | Filter on commit message 'no-cicd' to avoid the build to trigger. | ||
Clone GIT | ||||
Extract files from prod into master branch (refresh in case changes made on prod without using this pipeline) | lib\modules\export-files-from-master.js | |||
Push master to GIT | Filter on commit message 'no-cicd' to avoid the build to trigger. | |||
Create branch for update set if not already exists | lib\modules\export-update-set.js | |||
Refresh update set branch with changes made on master. | To avoid merge collision later in the process. | |||
Export update set XML | ||||
Export update set files | ||||
Configure Lint / JsDoc / ATF | ||||
Push branch to GIT | This will cause CICD pipeline to start if build on branch is enabled. | |||
If CICD_EMBEDDED_BUILD is 'true' | ||||
Build the branch locally | lib\modules\build-project.js |
Steps | Dev (Source) | Test (Target) | Code | Comment |
---|---|---|---|---|
Gulp Init | lib\project-templates\gulpfile.js | Get build information from server (/build/config) | ||
Gulp Lint, Doc | Lint and jsDoc results are zipped and sent to the CICD server (/build/task) | |||
Gulp Test | Run ATF suites and tests | lib\project-templates\atf-wrapper.js | Start hidden browser as test runner on CICD server.Send zipped mocha results to CICD server (/build/task) | |
Gulp complete | lib\project-templates\gulpfile.js | Send build complete info to server (/build/complete). | ||
Build complete | lib\modules\build-complete.js | |||
If CICD_GIT_PR_ENABLED is 'true'. | ||||
Raise pull request | Raise PR in GIT system | |||
Else If deploy target information in place and CD_CD_DEPLOY_ON_BUILD_PASS is 'true' | ||||
Complete update set | Update set can now be moved | |||
Deploy to target | lib\modules\deploy-update-set.js | Deployment can be done either via update set pull from source or pull from GIT (CICD_CD_DEPLOY_FROM_GIT) | ||
Else notify via Slack build has completed |
Steps | Dev (Source) | Test (Target) | Code | Comment |
---|---|---|---|---|
Pull request completed | lib\cicd.js | PR information coming from GIT system (/pull_request) | ||
If pull request resolved | ||||
If CICD_GIT_DELETE_BRANCH_ON_MERGE remove local branch | Delete branch locally and remote | |||
Complete update set | Update set can now be moved | |||
If CICD_CD_DEPLOY_ON_PR_RESOLVE is 'true' | ||||
Deploy to target | lib\modules\deploy-update-set.js | Deployment can be done either via update set pull from source or pull from GIT (CICD_CD_DEPLOY_FROM_GIT) | ||
Checkout code from GIT\ Run
This will test the application on the default host (source). If configured it will also raise a pull request against master branch.
Checkout code from GIT\ Run
--commit-id: the commit ID of the build --on-host: the host on which the ATF test will run. If CICD_ATF_RUN_ON_PRODUCTION is 'false' it will not allow to run on the master environment.
Checkout code from GIT\ Run
--commit-id: the commit ID of the build
--git: if exists, update set will be taken and deployed from GIT
--deliver-to: the environment to deliver to
-- deliver-from: the environment from which to deliver. If GIT is enabled, this environment will act as a proxy to connect to GIT.
Checkout code from GIT\ Run
--commit-id: the commit ID of the build
--git: if exists, update set will be taken and deployed from GIT
--deploy-to: the environment to deploy to
--deploy-from: the environment from which to deploy. If GIT is enabled, this environment will act as a proxy to connect to GIT.
Method | POST |
URL | /deploy/us |
Header | "x-access-token": CICD_DEPLOY_ACCESS_TOKEN, "accept": "application/json" |
Body | {"commitId": <the commit ID of the build>, "from": <source-host>, "to": <target-host>, "deploy": <true = deploy\| false = deliver> [false], "git": <true = via git \| false = via source> [false] } |
Rest client must support long polling and follow the redirects in the response header.
Git clone might run long on large GIT repos and deployments time out. To avoid consider following settings:
More information about REST calls via MID server can be found here KB0694711
Please fork, please contribute.
The project is designed to use extensions. This core project contains all 'shared' features. Customization which are dedicated to your Service-Now environment or CICD pipeline shall be added to the 'extending' project (like https://github.com/bmoers/sn-cicd-example-v3)