Continuous Integration Details

Before Solano CI will actually start a CI build, you need to perform the following configuration tasks:

  1. Notify Solano CI of new commits (in a post-receive hook).
  2. Allow Solano CI to connect to your SCM via SSH to pull your changes.
  3. Allow Solano CI to push your changes via SSH to your SCM to your CI server.
  4. Optionally configure which commits Solano CI should build.

Build Trigger WebHook Integrations

Your source control system can be configured to run a “hook” on repo events (for example, in a Git repo, the post-receive hook will run each time you push to the repository).

To hook up CI with Solano CI, you configure a hook that contacts Solano CI via a “Web Hook” that sends an HTTPS POST.

Then when you push to your Git repository, the Solano CI server will be notified, pull your changes, run your tests, and optionally push to your destination.

Each repository configured in Solano CI has a keyed URL where Web Hook posts should be sent.

You can find the webhook URL for initiating a build in CI (and the SSH pull key associated with the Repo) in your Solano CI Dashboard:

  1. Click on the gear icon next to the repository you wish to configure
  2. Select CI Setup.
  3. The post commit webhook URL is displayed under POST-COMMIT WEBHOOK URL. Note that full support for some hosting providers requires using a host-provider specific endpoint (i.e. replacing builds with a provider-specific string such as github).

The POST body is optional. If one is supplied, Solano CI will interpret it according to the webhook formats produced by a number of popular code hosting sites:

Hosting Provider Support Level
GitHub Multiple repos and branches, Single-Sign-On, Automatic configuration, Github Status Updates
Bitbucket Multiple repos and branches, Git and Mercurial Repos
Repository Hosting Multiple repos and branches
Atlassian Stash Multiple repos and branches
Gitlab Multiple repos and branches
Gerrit Multiple repos, branches, and code reviews
Beanstalk Multiple repos and branches
Unfuddle Only one branch at a time, per repo
Assembla Only one branch at a time, per repo
Generic Multiple repos and branches, Git and Mercurial Repos

Configuring GitHub Repos Manually

If you are using GitHub, you can set up the post-receive hook for Solano CI by going to

https://github.com/USER/REPOSITORY/admin/hooks

and clicking the “Add Webhook” button in the top left of the page. Paste the POST-COMMIT WEBHOOK URL (see above instructions for locating this URL) into the “Payload URL” input. Make sure “Content Type” is set to application/json and that the “Secret” field is left blank. Solano CI only performs actions on 4 individual GitHub events:

  1. Push (Git push to a repository.)
  2. Create (Branch, or tag created.)
  3. Pull Request (Pull Request opened, closed, assigned, labeled, or synchronized.)
  4. Delete (Branch, or tag deleted.)

You can select these 4 events by clicking the “Let me select individual events” radio button.

../../_images/github-webhooks.png

Finish creating the webhook by clicking the “Add webhook” button at the bottom of the page.

After creating the hook, GitHub will attempt to test the connection automatically for you. If you select the webhook URL from your list of webhooks, a list of “Recent Deliveries”. If you have set everything up correctly, you should see a request with a 200 - Success response code listed.

Note: seeing a 422-Unprocessable Entity response means that Solano CI received your webhook, but something was incorrectly configured. Double check that your ‘POST-COMMIT WEBHOOK URL’ is correct, and that you’re sending the correct 4 events

Your own Git server

If you are running a Git repository on a Unix server, you can install the post-receive hook yourself. Create the file <repo>/.git/hooks/post-commit, make it executable, and paste the following script into it, then substitute the correct URL:

#!/bin/sh
read oldrev newrev refname

case "$refname" in
refs/heads/*)
  branch=`echo $refname | sed -e 's;^refs/heads/;;'`
  wget --post-data "branch=$branch&head=$newrev" 'https://hooks.solanolabs.com/1/builds/APIKEY'
  # curl --data "branch=$branch&head=$newrev" -X POST https://hooks.solanolabs/1/builds/APIKEY
  ;;

*)
  # Log some kind of error message
esac

Your own Mercurial server

If you are running a Mercurial repository on a Unix server, you can install a changegroup hook yourself.

The changegroup hook should issue a POST with a JSON body to the webhook URL displayed in your Solano repo settings page, and it should use the following format for its payload:

Content-Type: application/json
Accept: application/json

{
  "source": "solano",
  "op": "push",
  "force": false,
  "head: GLOBAL_REVISION_ID,
  "branch": BRANCH_NAME,
  "ref": BRANCH_NAME
}

Replace:

  • GLOBAL_REVISION_ID with the revision hash identifier for the latest commit in this changegroup
  • BRANCH_NAME with the branch associated with the commit

Heroku

See Heroku Help on setting up a deploy hook.

BitBucket

Solano CI understands BitBucket’s POST Hook format. See BitBucket’s POST Hook setup documentation for more information.

Atlassian Stash

Support for Atlassian Stash’s POST Hook format is in limited beta. See Atlassian’s documentation for technical details on the POST body. To enable full support for Stash, you should use the Stash-specific endpoint:

https://hooks.solanolabs.com/1/stash/TOKEN

Gerrit

Gerrit Code Review is a git hosting and code review tool that is commonly integrated with Continuous Integration servers. Solano CI supports triggering builds in response to Gerrit changes using the Gerrit patchset-created hook.

Note

Solano CI does not yet automatically report back to Gerrit with build results. You can implement your own Gerrit reporting using Solano CI’s Build Notification Web Hooks (Outgoing) or Post-Build Hooks.

For an example patchset-created hook implementation, see our integrations repo on Github.

Gitlab

Support for Gitlabs’s POST Hook format is in limited beta. See Gitlab’s documentation for technical details on the POST body. To enable full support for Gitlab, you should use the Gitlab-specific endpoint:

https://hooks.solanolabs.com/1/gitlab/TOKEN

Beanstalk

Support for Beanstalk’s POST Hook format is supported. See Beanstalks’s documentation for technical details on the POST body. To enable full support for Beanstalk, you should use the Beanstalk-specific endpoint:

https://hooks.solanolabs.com/1/beanstalk/TOKEN

Unfuddle & Assembla

Both Unfuddle and Assembla support commit hooks or callbacks, and both (as of this writing) have the limitation that the hook payload delivered for a commit does not include information about the associated branch.

Solano CI allows you to specify a branch to build on receiving a commit hook as a URL parameter.

For example, to build the develop branch, set up a callback URL with a branch=develop parameter added to the repo’s hook URL:

https://hooks.solanolabs.com/1/hooks/<KEY>?branch=develop

More details:

Repository Hosting

Here’s how you can configure RepositoryHosting:

  • Get Solano CI’s CI hook URL and public key by running “tddium suite”.
  • Install the public key by visiting repositoryhosting.com, going to “My Profile”, then selecting “Public Keys”, “New Key”. Name the key “tddium-{repo}” and save it.
  • Configure the hook by selecting your project, clicking on “settings”, then “Notifications”. Check “Custom POST Callback” and enter the hook URL under URL. Leave username and password blank.

Make sure you delete any whitespace from the end of the URL. RepositoryHosting will not send the POST if the URL contains a trailing space.

Pulling from your repository

Solano CI needs SSH access to your repository in order to pull your data. You will need to authorize Solano CI’s SSH public key. Github and Heroku help links follow; contact your repository administrator for access if you’re using another system.

Controlling Which Commits Are Built

You can control which commits are built from a repository’s settings page. To get to the settings page, follow the link at the far right of the repo summary bar in the dashboard. The CI Setup menu item contains entries to build only pull request commits, collapse multiple commits on a branch into a single build (CI squash), and black list branches by name or pattern. You can also toggle individual branches from the Branches menu item. Branches are automatically hidden when a branch delete event is received unless they are locked to the visible state. Commits containing @wip in the commit message are skipped.

Putting it all together

A build looks like this:

  1. Git pull (or clone) from the pull URL.
  2. If the repo has changed, run all tests that match the default pattern configured in the suite.
  3. Collect test results.
  4. Push your changes to a configured CI server (if enabled).
  5. Post the results of your tests to Campfire or HipChat (if enabled).
  6. Email build notification to your account email address.

Solano CI will only run one build at at time for each suite (= repo/branch). If your repo sees a large number of commits, builds will queue and run in sequence.

Skipping Builds

You can tell Solano CI to skip a build with the following tags in the first line of a commit message:

  • @wip
  • [no-ci]
  • [no ci]

Sensitive Data

If you need to supply your CI builds with sensitive information, like API keys, read our setup guide.

Troubleshooting

There are a few ways to test the CI hook, depending on how you will normally trigger it.

If you’ve configured a hook via Github or Heroku, you can use their management interfaces to trigger a test.

If you want to manually trigger the hook for the master branch, just POST to it, for example with curl:

# Replace URL with the URL you were given from tddium suite.
$ curl -d '' URL

# Alternatively, to force the build even if it has already run:
$ curl -d 'force=true' URL

If you haven’t configured a suite for the master branch, you’ll get a response of DROPPED with an HTTP status of 422.

To trigger the hook for a suite configured for the “myapp” repo on branch “develop”, try:

# Replace URL with the URL you were given from tddium suite.
$ curl -d 'payload={"ref":"refs/heads/master"}&force=true' URL