Chapter 8. Triggering and modifying builds
The following sections outline how to trigger builds and modify builds using build hooks.
8.1. Build triggers
When defining a BuildConfig
, you can define triggers to control the circumstances in which the BuildConfig
should be run. The following build triggers are available:
- Webhook
- Image change
- Configuration change
8.1.1. Webhook triggers
Webhook triggers allow you to trigger a new build by sending a request to the OpenShift Container Platform API endpoint. You can define these triggers using GitHub, GitLab, Bitbucket, or Generic webhooks.
Currently, OpenShift Container Platform webhooks only support the analogous versions of the push event for each of the Git-based source code management systems (SCMs). All other event types are ignored.
When the push events are processed, the OpenShift Container Platform master host confirms if the branch reference inside the event matches the branch reference in the corresponding BuildConfig
. If so, it then checks out the exact commit reference noted in the webhook event on the OpenShift Container Platform build. If they do not match, no build is triggered.
oc new-app
and oc new-build
will create GitHub and Generic webhook triggers automatically, but any other needed webhook triggers must be added manually (see Setting Triggers).
For all webhooks, you must define a Secret
with a key named WebHookSecretKey
and the value being the value to be supplied when invoking the webhook. The webhook definition must then reference the secret. The secret ensures the uniqueness of the URL, preventing others from triggering the build. The value of the key will be compared to the secret provided during the webhook invocation.
For example here is a GitHub webhook with a reference to a secret named mysecret
:
type: "GitHub" github: secretReference: name: "mysecret"
The secret is then defined as follows. Note that the value of the secret is base64 encoded as is required for any data
field of a Secret
object.
- kind: Secret apiVersion: v1 metadata: name: mysecret creationTimestamp: data: WebHookSecretKey: c2VjcmV0dmFsdWUx
8.1.1.1. Using GitHub webhooks
GitHub webhooks handle the call made by GitHub when a repository is updated. When defining the trigger, you must specify a secret
, which will be part of the URL you supply to GitHub when configuring the webhook.
Example GitHub webhook definition:
type: "GitHub" github: secretReference: name: "mysecret"
The secret used in the webhook trigger configuration is not the same as secret
field you encounter when configuring webhook in GitHub UI. The former is to make the webhook URL unique and hard to predict, the latter is an optional string field used to create HMAC hex digest of the body, which is sent as an X-Hub-Signature
header.
The payload URL is returned as the GitHub Webhook URL by the oc describe
command (see Displaying Webhook URLs), and is structured as follows:
http://<openshift_api_host:port>/oapi/v1/namespaces/<namespace>/buildconfigs/<name>/webhooks/<secret>/github
Prerequisites
-
Create a
BuildConfig
from a GitHub repository.
Procedure
To configure a GitHub Webhook:
After creating a
BuildConfig
from a GitHub repository, run:$ oc describe bc/<name-of-your-BuildConfig>
This generates a webhook GitHub URL that looks like:
<https://api.starter-us-east-1.openshift.com:443/oapi/v1/namespaces/nsname/buildconfigs/bcname/webhooks/<secret>/github>.
- Cut and paste this URL into GitHub, from the GitHub web console.
-
In your GitHub repository, select Add Webhook from Settings
Webhooks & Services. - Paste the URL output (similar to above) into the Payload URL field.
-
Change the Content Type from GitHub’s default
application/x-www-form-urlencoded
toapplication/json
. Click Add webhook.
You should see a message from GitHub stating that your webhook was successfully configured.
Now, whenever you push a change to your GitHub repository, a new build will automatically start, and upon a successful build a new deployment will start.
NoteGogs supports the same webhook payload format as GitHub. Therefore, if you are using a Gogs server, you can define a GitHub webhook trigger on your
BuildConfig
and trigger it by your Gogs server as well.
Given a file containing a valid JSON payload, such as
payload.json
, you can manually trigger the webhook withcurl
:$ curl -H "X-GitHub-Event: push" -H "Content-Type: application/json" -k -X POST --data-binary @payload.json https://<openshift_api_host:port>/oapi/v1/namespaces/<namespace>/buildconfigs/<name>/webhooks/<secret>/github
The
-k
argument is only necessary if your API server does not have a properly signed certificate.
8.1.1.2. Using GitLab webhooks
GitLab webhooks handle the call made by GitLab when a repository is updated. As with the GitHub triggers, you must specify a secret
. The following example is a trigger definition YAML within the BuildConfig
:
type: "GitLab" gitlab: secretReference: name: "mysecret"
The payload URL is returned as the GitLab Webhook URL by the oc describe
command (see Displaying Webhook URLs), and is structured as follows:
http://<openshift_api_host:port>/oapi/v1/namespaces/<namespace>/buildconfigs/<name>/webhooks/<secret>/gitlab
Procedure
To configure a GitLab Webhook:
Describe the
BuildConfig
to get the webhook URL:$ oc describe bc <name>
-
Copy the webhook URL, replacing
<secret>
with your secret value. - Follow the GitLab setup instructions to paste the webhook URL into your GitLab repository settings.
Given a file containing a valid JSON payload, such as
payload.json
, you can manually trigger the webhook withcurl
:$ curl -H "X-GitLab-Event: Push Hook" -H "Content-Type: application/json" -k -X POST --data-binary @payload.json https://<openshift_api_host:port>/oapi/v1/namespaces/<namespace>/buildconfigs/<name>/webhooks/<secret>/gitlab
The
-k
argument is only necessary if your API server does not have a properly signed certificate.
Additional resources
8.1.1.3. Using Bitbucket webhooks
Bitbucket webhooks handle the call made by Bitbucket when a repository is updated. Similar to the previous triggers, you must specify a secret
. The following example is a trigger definition YAML within the BuildConfig
:
type: "Bitbucket" bitbucket: secretReference: name: "mysecret"
The payload URL is returned as the Bitbucket Webhook URL by the oc describe
command (see Displaying Webhook URLs), and is structured as follows:
http://<openshift_api_host:port>/oapi/v1/namespaces/<namespace>/buildconfigs/<name>/webhooks/<secret>/bitbucket
Procedure
To configure a Bitbucket Webhook:
Describe the 'BuildConfig' to get the webhook URL:
$ oc describe bc <name>
-
Copy the webhook URL, replacing
<secret>
with your secret value. - Follow the Bitbucket setup instructions to paste the webhook URL into your Bitbucket repository settings.
Given a file containing a valid JSON payload, such as
payload.json
, you can manually trigger the webhook withcurl
:$ curl -H "X-Event-Key: repo:push" -H "Content-Type: application/json" -k -X POST --data-binary @payload.json https://<openshift_api_host:port>/oapi/v1/namespaces/<namespace>/buildconfigs/<name>/webhooks/<secret>/bitbucket
The
-k
argument is only necessary if your API server does not have a properly signed certificate.
Additional resources
8.1.1.4. Using generic webhooks
Generic webhooks are invoked from any system capable of making a web request. As with the other webhooks, you must specify a secret, which will be part of the URL that the caller must use to trigger the build. The secret ensures the uniqueness of the URL, preventing others from triggering the build. The following is an example trigger definition YAML within the BuildConfig
:
type: "Generic"
generic:
secretReference:
name: "mysecret"
allowEnv: true 1
- 1
- Set to
true
to allow a generic webhook to pass in environment variables.
Procedure
To set up the caller, supply the calling system with the URL of the generic webhook endpoint for your build:
http://<openshift_api_host:port>/oapi/v1/namespaces/<namespace>/buildconfigs/<name>/webhooks/<secret>/generic
The caller must invoke the webhook as a
POST
operation.To invoke the webhook manually you can use
curl
:$ curl -X POST -k https://<openshift_api_host:port>/oapi/v1/namespaces/<namespace>/buildconfigs/<name>/webhooks/<secret>/generic
The HTTP verb must be set to
POST
. The insecure-k
flag is specified to ignore certificate validation. This second flag is not necessary if your cluster has properly signed certificates.The endpoint can accept an optional payload with the following format:
git: uri: "<url to git repository>" ref: "<optional git reference>" commit: "<commit hash identifying a specific git commit>" author: name: "<author name>" email: "<author e-mail>" committer: name: "<committer name>" email: "<committer e-mail>" message: "<commit message>" env: 1 - name: "<variable name>" value: "<variable value>"
- 1
- Similar to the
BuildConfig
environment variables, the environment variables defined here are made available to your build. If these variables collide with theBuildConfig
environment variables, these variables take precedence. By default, environment variables passed by webhook are ignored. Set theallowEnv
field totrue
on the webhook definition to enable this behavior.
To pass this payload using
curl
, define it in a file named payload_file.yaml and run:$ curl -H "Content-Type: application/yaml" --data-binary @payload_file.yaml -X POST -k https://<openshift_api_host:port>/oapi/v1/namespaces/<namespace>/buildconfigs/<name>/webhooks/<secret>/generic
The arguments are the same as the previous example with the addition of a header and a payload. The
-H
argument sets theContent-Type
header toapplication/yaml
orapplication/json
depending on your payload format. The--data-binary
argument is used to send a binary payload with newlines intact with thePOST
request.
OpenShift Container Platform permits builds to be triggered by the generic webhook even if an invalid request payload is presented (for example, invalid content type, unparsable or invalid content, and so on). This behavior is maintained for backwards compatibility. If an invalid request payload is presented, OpenShift Container Platform returns a warning in JSON format as part of its HTTP 200 OK
response.
8.1.1.5. Displaying webhook URLs
You can use the following command to display webhook URLs associated with a BuildConfig
. If the command does not display any webhook URLs, then no webhook trigger is defined for that build configuration. See Setting Triggers to manually add triggers.
Procedure
-
To display any webhook URLs associated with a
BuildConfig
$ oc describe bc <name>
8.1.2. Using image change triggers
Image change triggers allow your build to be automatically invoked when a new version of an upstream image is available. For example, if a build is based on top of a RHEL image, then you can trigger that build to run any time the RHEL image changes. As a result, the application image is always running on the latest RHEL base image.
Imagestreams that point to container images in v1 container registries only trigger a build once when the imagestreamtag becomes available and not on subsequent image updates. This is due to the lack of uniquely identifiable images in v1 container registries.
Procedure
Configuring an image change trigger requires the following actions:
Define an
ImageStream
that points to the upstream image you want to trigger on:kind: "ImageStream" apiVersion: "v1" metadata: name: "ruby-20-centos7"
This defines the imagestream that is tied to a container image repository located at <system-registry>/<namespace>/ruby-20-centos7. The <system-registry> is defined as a service with the name
docker-registry
running in OpenShift Container Platform.If an imagestream is the base image for the build, set the from field in the build strategy to point to the imagestream:
strategy: sourceStrategy: from: kind: "ImageStreamTag" name: "ruby-20-centos7:latest"
In this case, the
sourceStrategy
definition is consuming thelatest
tag of the imagestream namedruby-20-centos7
located within this namespace.Define a build with one or more triggers that point to imagestreams:
type: "imageChange" 1 imageChange: {} type: "imageChange" 2 imageChange: from: kind: "ImageStreamTag" name: "custom-image:latest"
- 1
- An image change trigger that monitors the
ImageStream
andTag
as defined by the build strategy’sfrom
field. TheimageChange
object here must be empty. - 2
- An image change trigger that monitors an arbitrary imagestream. The
imageChange
part in this case must include afrom
field that references theImageStreamTag
to monitor.
When using an image change trigger for the strategy imagestream, the generated build is supplied with an immutable Docker tag that points to the latest image corresponding to that tag. This new image reference will be used by the strategy when it executes for the build.
For other image change triggers that do not reference the strategy imagestream, a new build will be started, but the build strategy will not be updated with a unique image reference.
Since this example has an image change trigger for the strategy, the resulting build will be:
strategy: sourceStrategy: from: kind: "DockerImage" name: "172.30.17.3:5001/mynamespace/ruby-20-centos7:<immutableid>"
This ensures that the triggered build uses the new image that was just pushed to the repository, and the build can be re-run any time with the same inputs.
You can pause an image change trigger to allow multiple changes on the referenced imagestream before a build is started. You can also set the paused
attribute to true when initially adding an ImageChangeTrigger
to a BuildConfig
to prevent a build from being immediately triggered.
type: "ImageChange" imageChange: from: kind: "ImageStreamTag" name: "custom-image:latest" paused: true
In addition to setting the image field for all Strategy
types, for custom builds, the OPENSHIFT_CUSTOM_BUILD_BASE_IMAGE
environment variable is checked. If it does not exist, then it is created with the immutable image reference. If it does exist then it is updated with the immutable image reference.
If a build is triggered due to a webhook trigger or manual request, the build that is created uses the <immutableid>
resolved from the ImageStream
referenced by the Strategy
. This ensures that builds are performed using consistent image tags for ease of reproduction.
Additional resources
8.1.3. Configuration change triggers
A configuration change trigger allows a build to be automatically invoked as soon as a new BuildConfig
is created.
The following is an example trigger definition YAML within the BuildConfig
:
type: "ConfigChange"
Configuration change triggers currently only work when creating a new BuildConfig
. In a future release, configuration change triggers will also be able to launch a build whenever a BuildConfig
is updated.
8.1.3.1. Setting triggers manually
Triggers can be added to and removed from build configurations with oc set triggers
.
Procedure
To set a GitHub webhook trigger on a build configuration, use:
$ oc set triggers bc <name> --from-github
To set an imagechange trigger, use
$ oc set triggers bc <name> --from-image='<image>'
To remove a trigger, add
--remove
:$ oc set triggers bc <name> --from-bitbucket --remove
When a webhook trigger already exists, adding it again regenerates the webhook secret.
For more information, consult the help documentation with oc set triggers --help
8.2. Build hooks
Build hooks allow behavior to be injected into the build process.
The postCommit
field of a BuildConfig
object executes commands inside a temporary container that is running the build output image. The hook is executed immediately after the last layer of the image has been committed and before the image is pushed to a registry.
The current working directory is set to the image’s WORKDIR
, which is the default working directory of the container image. For most images, this is where the source code is located.
The hook fails if the script or command returns a non-zero exit code or if starting the temporary container fails. When the hook fails it marks the build as failed and the image is not pushed to a registry. The reason for failing can be inspected by looking at the build logs.
Build hooks can be used to run unit tests to verify the image before the build is marked complete and the image is made available in a registry. If all tests pass and the test runner returns with exit code 0, the build is marked successful. In case of any test failure, the build is marked as failed. In all cases, the build log will contain the output of the test runner, which can be used to identify failed tests.
The postCommit
hook is not only limited to running tests, but can be used for other commands as well. Since it runs in a temporary container, changes made by the hook do not persist, meaning that the hook execution cannot affect the final image. This behavior allows for, among other uses, the installation and usage of test dependencies that are automatically discarded and will be not present in the final image.
8.2.1. Configuring post commit build hooks
There are different ways to configure the post build hook. All forms in the following examples are equivalent and execute bundle exec rake test --verbose
.
Procedure
Shell script:
postCommit: script: "bundle exec rake test --verbose"
The
script
value is a shell script to be run with/bin/sh -ic
. Use this when a shell script is appropriate to execute the build hook. For example, for running unit tests as above. To control the image entry point, or if the image does not have/bin/sh
, usecommand
and/orargs
.NoteThe additional
-i
flag was introduced to improve the experience working with CentOS and RHEL images, and may be removed in a future release.Command as the image entry point:
postCommit: command: ["/bin/bash", "-c", "bundle exec rake test --verbose"]
In this form,
command
is the command to run, which overrides the image entry point in the exec form, as documented in the Dockerfile reference. This is needed if the image does not have/bin/sh
, or if you do not want to use a shell. In all other cases, usingscript
might be more convenient.Command with arguments:
postCommit: command: ["bundle", "exec", "rake", "test"] args: ["--verbose"]
This form is equivalent to appending the arguments to
command
.
Providing both script
and command
simultaneously creates an invalid build hook.
8.2.2. Using the CLI to set post commit build hooks
The oc set build-hook
command can be used to set the build hook for a build configuration.
Procedure
To set a command as the post-commit build hook:
$ oc set build-hook bc/mybc \ --post-commit \ --command \ -- bundle exec rake test --verbose
To set a script as the post-commit build hook:
$ oc set build-hook bc/mybc --post-commit --script="bundle exec rake test --verbose"