Does your current development process involve constantly going back and forth updating statuses between applications? Do your developers have to initiate a build after they make changes, or wait until source control is polled for the build to initiate? Do you feel like you are manually configuring many parts of your release as changes are made? Webhooks may be able to alleviate some of these tedious tasks.
FlexDeploy includes support for incoming and outgoing webhooks, enhancing the ability to integrate FlexDeploy with other DevOps tools like source control, issue tracking, and change management. A variety of use cases for webhooks can be implemented, from a simple trigger of a build to automating your entire release configuration. Today, I will share a simple yet common use case for webhooks, which will build affected projects based on a push event in GitLab.
Creating a Webhook Provider
The first step in our webhook setup is creating a provider. Each provider has a Groovy match script to verify an incoming webhook is from the provider, based on incoming request information like headers and query parameters. When a webhook is received by FlexDeploy, each match script is executed until one returns true, indicating a match. Shown below is a GitLab provider which identifies a webhook being from GitLab by the webhook’s secret token and IP address. We create provider properties and define them as expected values for secret token and IP block.
Provider Match Script
// match GitLab by secret token LOG.info('Gitlab - evaluating'); def gitlabSecret = HTTP_HEADERS.get('x-gitlab-token'); def ip = HTTP_HEADERS.get('x-forwarded-for'); if (gitlabSecret.equals(GITLAB_SECRET_TOKEN)) { if (ip.contains(IP_BLOCK)) { LOG.info('GitLab - success!'); return true; } } LOG.info('GitLab - no match'); return false;
Creating a Webhook Function
Then, a webhook function can be created, which will be executed when a GitLab webhook is received at the listed URI. For our function, we want to build relevant FlexDeploy projects whenever a push happens in our GitLab repository. Here are the function details:
The initial steps of a function generally involve getting necessary information from the received payload. See GitLab’s documentation for more information on what the payload will look like. In this case, the function gets the repository name and branch where the push event took place, along with commit ids for the first and last commits in the payload. Next, there is a method called to get the polling result. This step is not required, but sending the polling result in the findProjectsForChange and buildProject methods will improve performance. Then the findProjectsForChange method is called to find all relevant projects for this SCM change. Once we have a list of projects to build, we just have to get the stream id and we are able to submit a build request for each project by calling the buildProject method.
Function Script
def functionName = "BuildProject"; LOG.info("Running function: ${functionName}"); // get necessary information from payload def repoName = PAYLOAD.project.path_with_namespace; def branch = PAYLOAD.ref - 'refs/heads/'; def numCommits = PAYLOAD.total_commits_count; def fromRevision = PAYLOAD.commits[numCommits-1].id; def currentRevision = PAYLOAD.commits[0].id; LOG.info("Processing message for ${repoName} and branch ${branch}"); // find affected projects and build def pollingResult = FLEXDEPLOY.findLocalChangeLogs(PAYLOAD.project.git_http_url, branch, currentRevision, fromRevision); def projects = FLEXDEPLOY.findProjectsForChange(repoName, branch, pollingResult); LOG.info("Found projects ${projects} for this push"); for (def project : projects) { def streamId = FLEXDEPLOY.findStreamId(project, branch); FLEXDEPLOY.buildProject(streamId, project, pollingResult); }
Enable Webhooks on Projects
The projects returned from the findProjectsForChange method will only include projects relevant to the SCM change. This means:
- The project has webhooks enabled
- There is a webhook trigger for the stream in which the SCM event took place
- The change(s) took place within the sparse checkout folder configured on the project
For all projects we want to use webhooks for, we will need to set Webhooks Enabled on the CI tab and verify there is a webhook trigger for intended streams.
GitLab Setup
After the webhook provider and function setup is completed in FlexDeploy, we can continue by completing setup in GitLab. Webhooks in GitLab are defined individually by project, and can be found in project settings. We will need to define a URL (making sure to match the webhook function URI), a secret token, and select the checkbox to subscribe only to push events.
Testing!
Now we are ready to test our webhook. Try pushing a change to source control. We can check a webhook was sent from GitLab by clicking to edit the webhook and viewing the Recent Deliveries section. In FlexDeploy, we can view the Webhook Messages page to see the result of the received webhook. For this webhook, a webhook message was delivered and a build request was submitted for one project.
From this example, we can already start to see the value in adding webhooks to FlexDeploy. This is just the beginning of what can be accomplished with webhooks. See Part II for a more advanced example on using webhooks to manage FlexDeploy releases.