Using GitHub Actions to Deploy on IBM Cloud Code Engine

I have a set of applications I run on IBM Cloud Code Engine. A common theme found across these applications is they all have a UI component, an API component and the source code resides on GitHub. Some of these applications will interact with IBM Cloud Services, while others are self-contained. I needed a method to review these applications running in Code Engine following changes submitted via a pull request.

I chose to use a GitHub Actions workflow to build and deploy the application to Code Engine upon the submission of a pull request. If you are not already familiar with GitHub Actions, you can review their documentation page.

A high-level view of the typical process I follow to deploy and manage my applications is below:

Architecture

  1. A developer can submit a pull request to the repository. This action triggers a GitHub Actions workflow.
  2. A container image is built from the source in the pull request and published to a container registry.
  3. A version of the application is currently available in its own project. It has a URL (URL-y), configmaps and environments (config-y).
  4. If used by the application, IBM Cloud Services are expected to have been previously deployed and configured. However, binding to these services is required.
  5. The GitHub Actions creates a temporary project and deploys the code to a new application with a URL (URL-x) and configmaps (config-x). Once the pull request is approved and merged, the temporary project is deleted, and the existing application is updated.

I started off building a simple GitHub Actions workflow as depicted below:

Workflow

I quickly realized that I could not easily copy that same workflow from one application to another because every application required a different set of configurations and cloud services. My "Deploy to Code Engine" section of the workflow was growing in complexity and becoming tedious to implement across multiple applications.

A pair of custom Actions to the rescue

To address this issue, I ended up creating two GitHub Actions that are now available in the GitHub Marketplace. These two actions generalized most of the activities I would need to perform when deploying an application to Code Engine. They also help simplify the creation of workflows in current and future applications with a simple copy and paste and modification of inputs.

Workflow

Set up the IBM Cloud CLI

This first action installs the latest version of the IBM Cloud Command Line Interface (CLI). It takes the following input parameters.

.github/workflows/workflow-sample.yml
steps:
  - name: Configure IBM Cloud CLI
    uses: dprosper/[email protected]
    with:
      API_KEY: ${{ secrets.API_KEY }}
      INSTALL_PLUGINS: [email protected],container-service
  • API_KEY is the API Key that will log in to IBM Cloud and has the appropriate access level for the operations you intend to perform.
  • INSTALL_PLUGINS is a comma-separated list of plugins that will be installed. You can specify a specific version of a plugin to use.

Additional parameters like REGION and RESOURCE_GROUP can be included to target a specific region or resource group. For a complete list of available parameters, check out the Usage section for the action.

Create, update and delete to IBM Cloud Code Engine

As shown in the above workflow, this second action supports multiple paths via the CE_ACTION parameter: create, delete and update:

  • Create: Used to create a project and deploy a temporary instance of the application used for validation of code changes.
  • Delete: Used to delete the project once it is no longer needed.
  • Update: Used to modify the current version of the application with the now merged code.

Deploy an application to Code Engine

.github/workflows/workflow-sample.yml
build_publish_deploy:
  if: github.event.action == 'opened'
  name: Create
  runs-on: ubuntu-latest
  steps:
    - name: Deploy to IBM Cloud Code Engine
      uses: dprosper/[email protected]
      with:
        CE_ACTION: create
        IMAGE: ${{ env.REGISTRY_ORG_NAMESPACE }}/${{ env.REGISTRY_REPOSITORY }}:${{ github.event.pull_request.head.sha }}
        CE_PROJECT_NAME: projecta-${{ github.event.pull_request.head.sha }}
        CE_APP_NAME: appa-${{ github.event.pull_request.head.sha }}
  • IMAGE is the name of the container image that is used for the application.
  • CE_PROJECT_NAME is the name of the project to create in Code Engine.
  • CE_APP_NAME is the name of the application to create in the project.

Additional parameters like APP_PORT (port number to use for the application) and APP_SECRET (a secret used inside the application) can be included. This action also supports creating configmaps, environments and service bindings based on the content of an ice-xxx-config.json file. For a complete list of available options, check out the Usage section for the action.

Once the application deployment is successful, a comment is added to the pull request with the URL to access the application. That URL is used to validate the code changes submitted via the pull request:

Workflow

Delete a project in Code Engine

.github/workflows/workflow-sample.yml
delete:
  if: github.event.action == 'closed'
  name: Delete
  runs-on: ubuntu-latest
  steps:
    - name: Delete from IBM Cloud Code Engine
      uses: dprosper/[email protected]
      with:
        CE_ACTION: delete
        CE_PROJECT_NAME: projecta-${{ github.event.pull_request.head.sha }}
        ISSUE_NUMBER: ${{ github.event.pull_request.number }}
  • CE_PROJECT_NAME is the name of the project to delete.
  • ISSUE_NUMBER is not required; it is supplied simply to update the comment that was added during the previous deployment and remove the URL to the application as it will not be valid once the project is deleted.

Workflow

Update an application in Code Engine

.github/workflows/workflow-sample.yml
update:
  if: github.event.pull_request.merged == true
  name: Update
  runs-on: ubuntu-latest
  steps:
    - name: Update in IBM Cloud Code Engine
      uses: dprosper/[email protected]
      with:
        CE_ACTION: update
        CE_PROJECT_NAME: projecta-current
        CE_APP_NAME: appa-current
        IMAGE: ${{ env.REGISTRY_ORG_NAMESPACE }}/${{ env.REGISTRY_REPOSITORY }}:v1.2.0

It is not always a happy path — in the event of an error during processing, an appropriate comment is added to the PR:

Workflow

And a new issue is created in the repository for necessary action:

Workflow

Getting started

I hope you will find these actions useful in your own projects. Note that these are community actions and are not supported IBM offerings, however these actions leverage the official IBM Cloud Command Line Interface CLI and Plugins. To get started, review the Usage section on each. Some examples of using these two actions are also available here.

Questions and feedback

The GitHub repositories for these actions have an Issues tab where you can comment on the content and code.