Skip to main content

Configuring a continuous integration (CI) tool

A continuous integration (CI) tool deploys software automatically to help you deliver new features without breaking existing functionality.

Examples of CI tools include Concourse, GitHub Actions, Circle and TeamCity.

Choose CI tool

You should choose a CI tool based on criteria such as:

  • product features
  • support offered
  • pricing
  • security

You should focus on how the tool encrypts and protects any sensitive information or secrets such as keys, usernames or passwords. You are responsible for the assurance of your own services and information.

Configure your CI tool accounts

You should create one or more dedicated PaaS user accounts for use by your CI tool.

Use a different account for each space you want to deploy your app to using your CI tool.

Assign a user role to each of these accounts. These user roles should have the minimum permissions needed for setting up your CI tool to automatically build and deploy your app.

The GOV.UK PaaS will lock your credentials if your CI tool makes multiple failed login attempts in a short period of time.

Push an app with GitHub Actions

Set up dedicated accounts

CI systems should not use normal user accounts. Find out more about configuring your CI tool accounts in GOV.UK PaaS.

Store credentials in GitHub Actions

You should store your sensitive credentials in GitHub Actions.

Store the username as CF_USERNAME and the password as CF_PASSWORD.

Implement a GitHub Actions workflow

Create a deploy.yml file in the .github/workflows within your repository. The workflow file tells GitHub Actions how to deploy your application.

name: Deploy

on:
  push:
    branches:
      - main

jobs:
  deploy:
    name: Deploy
    runs-on: ubuntu-latest

    env:
      CF_API: "https://api.london.cloud.service.gov.uk"
      CF_ORG: "ORG_NAME"
      CF_SPACE: "SPACE_NAME"

    permissions:
      contents: read

    steps:
      - name: Checkout Code
        uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579

      - name: Install the CF CLI
        run: |
          wget -q -O cf.tar.gz "https://packages.cloudfoundry.org/stable?release=linux64-binary&version=7.4.0&source=github-rel"
          sudo tar xzf cf.tar.gz --wildcards --directory /usr/local/bin/ "cf*"

      - name: Authenticate
        env:
          CF_USERNAME: ${{ secrets.CF_USERNAME }}
          CF_PASSWORD: ${{ secrets.CF_PASSWORD }}
        run: |
          echo "Logging into $CF_ORG/$CF_SPACE..."
          cf api "${CF_API}"
          cf auth
          cf target -o "${CF_ORG}" -s "${CF_SPACE}"

      - name: Deploy to PaaS
        run: |
          cf push -f manifest.yml --strategy rolling
          cf logout

Where ORG_NAME is the name of your org and SPACE_NAME is the name of your space.

This section in the file above is instructing GitHub Actions to run the workflow on pushes to the main branch.

on:
  push:
    branches:
      - main

The step Install CF CLI installs the Cloud Foundry CLI as the runner environments do not have it by default.

In the step Authenticate you should use CF Auth to avoid the use of plain text credentials.

The Deploy to PaaS step pushes the application defined in the manifest.yml file to Cloud Foundry to the org defined in CF_ORG and the space defined in CF_SPACE.

The --strategy rolling option performs a rolling deployment to avoid downtime.