Jenkins¶
-
Add the webhook
If you are using Jenkins and you want your builds to auto trigger on push, go ahead and add a webhook in your github repo for your jenkins server
Add the repo to your Jenkins installation
Use the blueocean plugin, it makes adding new repos very convienent.
Let’s create the pipeline
Adding the agent
pipeline { options { timeout(time: 1, unit: 'HOURS') } agent { docker { image 'hashmapinc/sqitch:snowflake-dev' args "-u root -v /var/run/docker.sock:/var/run/docker.sock --entrypoint=''" } }
Here we are giving a
timeoutoption of one hour. We are also specifying the docker container that will act as theagentfor running the job. And we also specify that we want to run this as therootuser.Deploying the change
stages { stage('Installing Latest snowsql') { steps { sh 'snowsql --help' } } stage('Deploy changes') { steps { withCredentials(bindings: [usernamePassword(credentialsId: 'snowflake_creds', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) { sh ''' sqitch deploy "db:snowflake://$USERNAME:$PASSWORD@hashmap.snowflakecomputing.com/flipr?Driver=Snowflake;warehouse=sqitch_wh" ''' } } }
Here we re-install the latest version of
snowsqlfor therootuser.And then deploy the change to the target database.
withCredentials(bindings: [usernamePassword(credentialsId: 'snowflake_creds', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')])
We use the credentials stored in credentials manager to authenticate to snowflake
sqitch deploy "db:snowflake://$USERNAME:$PASSWORD@hashmap.snowflakecomputing.com/flipr?Driver=Snowflake;warehouse=sqitch_wh"
Sqitch requires the connection string to connect to snowflake which contains
username variable
$USERNAMEpassword variable
$PASSWORDSnowflake Account address
hashmap.snowflakecomputing.comDriver name
Driver=SnowflakeDatabase name
fliprand the warehouse
warehouse=sqitch_whVerifying the change
stage('Verify changes') { steps { withCredentials(bindings: [usernamePassword(credentialsId: 'snowflake_creds', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) { sh ''' sqitch verify "db:snowflake://$USERNAME:$PASSWORD@hashmap.snowflakecomputing.com/flipr?Driver=Snowflake;warehouse=sqitch_wh" ''' } }
Again we use the credentials from the credentials manager to authenticate to snowflake and here we verify if our changes were successfully deployed.
Cleaning Up
post { always { sh 'chmod -R 777 .' } }
Since we ran the container with root user, jenkins won’t we able to clean up the workspace if don’t change the permissions on the files created by it.
So we run a chmod -R 777 . on the working directory. And we put this stage in post bock with always condition, so that this is executed in every case and workspace can be cleaned. If this is not done, all consecutive builds will fail.
Add the jenkinsfile in your code
pipeline { options { timeout(time: 1, unit: 'HOURS') } agent { docker { image 'hashmapinc/sqitch:snowflake-dev' args "-u root -v /var/run/docker.sock:/var/run/docker.sock --entrypoint=''" } } stages { stage('Installing Latest snowsql') { steps { sh 'snowsql --help' } } stage('Deploy changes') { steps { withCredentials(bindings: [usernamePassword(credentialsId: 'snowflake_creds', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) { sh ''' sqitch deploy "db:snowflake://$USERNAME:$PASSWORD@hashmap.snowflakecomputing.com/flipr?Driver=Snowflake;warehouse=sqitch_wh" ''' } } } stage('Verify changes') { steps { withCredentials(bindings: [usernamePassword(credentialsId: 'snowflake_creds', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) { sh ''' sqitch verify "db:snowflake://$USERNAME:$PASSWORD@hashmap.snowflakecomputing.com/flipr?Driver=Snowflake;warehouse=sqitch_wh" ''' } } } } post { always { sh 'chmod -R 777 .' } } }
Commit your changes and push to github
For information on how to add changes via sqitch, visit Introduction to Sqitch on Snowflake.
Once you push the changes, the webhook added in github will send a
POSTmessage to jenkins and the pipeline will be triggered.You should see something like this in the logs
[Pipeline] // stage [Pipeline] stage [Pipeline] { (Deploy changes) [Pipeline] withCredentials [Pipeline] { [Pipeline] sh [owflake-sqitch-ci-cd_master-4KRIUCFJ5X7PGMBERRN6PYWQF2S5EEPCMF6ULWY3K4N5SP2RPD5A] Running shell script + sqitch deploy db:snowflake://****:****@hashmap.snowflakecomputing.com/flipr?Driver=Snowflake;warehouse=sqitch_wh Adding registry tables to db:snowflake://****:@hashmap.snowflakecomputing.com/flipr?Driver=Snowflake;warehouse=sqitch_wh Deploying changes to db:snowflake://****:@hashmap.snowflakecomputing.com/flipr?Driver=Snowflake;warehouse=sqitch_wh + appschema .. ok + users ...... ok [Pipeline] } [Pipeline] // withCredentials [Pipeline] } [Pipeline] // stage [Pipeline] stage [Pipeline] { (Verify changes) [Pipeline] withCredentials [Pipeline] { [Pipeline] sh [owflake-sqitch-ci-cd_master-4KRIUCFJ5X7PGMBERRN6PYWQF2S5EEPCMF6ULWY3K4N5SP2RPD5A] Running shell script + sqitch verify db:snowflake://****:****@hashmap.snowflakecomputing.com/flipr?Driver=Snowflake;warehouse=sqitch_wh Verifying db:snowflake://****:@hashmap.snowflakecomputing.com/flipr?Driver=Snowflake;warehouse=sqitch_wh * appschema .. ok * users ...... ok Verify successful [Pipeline] } [Pipeline] // withCredentials
As you can see the changes have been deployed successfully, and sqitch is also able to verify those changes.
Reverting
For Reverting your changes, you can either go in the Jenkinsfile and change the deploy command to revert
Your deploy block should look something like this
stage('Revert changes') { steps { withCredentials(bindings: [usernamePassword(credentialsId: 'snowflake_creds', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) { sh ''' sqitch revert "db:snowflake://$USERNAME:$PASSWORD@hashmap.snowflakecomputing.com/flipr?Driver=Snowflake;warehouse=sqitch_wh" ''' } }
Or you can add a new step in your sqitch plan to drop the change and you can continue without having to edit the pipeline
Deploying to Production
Once, you are sure of the changes, and want to deploy to production, just change the connection string to target your production database and you are good to go.
stage('Deploy changes to Production') { steps { withCredentials(bindings: [usernamePassword(credentialsId: 'snowflake_creds', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) { sh ''' sqitch deploy "db:snowflake://$USERNAME:$PASSWORD@hashmap.snowflakecomputing.com/flipr_prod?Driver=Snowflake;warehouse=sqitch_wh" ''' } } }
