Setting up continuous integration with a GitHub repository using GitHub Actions

Last updated:

If you work as part of a web development team, you may wish to have your entire production codebase source of truth in version control. This way, your team of developers can use your favorite version control system to collaborate, track and easily roll-back changes. Learn more about developer workflows on the HubSpot CMS by following the Creating an efficient developer workflow guide


This guide walks through setting up continuous integration with a GitHub repository utilizing GitHub Actions. Learn more about GitHub Actions. This guide assumes you are familiar with git and GitHub, as well as building websites using the CMS CLI. If you don’t have that set up yet, follow the Local Development Tooling: Getting Started guide.

Get your developer file system in GitHub

Utilizing the CMS CLI, you can fetch your entire developer file system. Running hs fetch project root to copy your Design Manager project to your local environment. 

If you are starting a new project, you can simply clone, or fork, the CMS Theme Boilerplate, which is designed to give developers a head start on new HubSpot CMS projects. This project has Actions set up to deploy merges to master of https://github.com/HubSpot/cms-theme-boilerplate to https://boilerplate.hubspotcms.com

Follow this GitHub help article on adding your project to a GitHub repository.

Add dependencies to your package.json file

If you do not already have one, create a package.json file at your project root. Add the @hubspot/cms-cli and js-yaml as devDependencies. This should look something like:

JSON
// package.json
{
  "name": "my-website-theme",
  "version": "0.0.1",
  "devDependencies": {
    "@hubspot/cms-cli": "^1.0.2",
    "js-yaml": "^3.13.1",
  }
}

Write your files to be run on deploy

At your project’s root, create a bin directory (refer to the CMS Theme Boilerplate’s implementation). In this directory, create two files:

  1. deploy.sh - a shell command which will run the deploy script

Enter the following in this file:

Shell script
#!/bin/bash
npx hs upload src cms-theme-boilerplate

Notice line two is the CMS CLI upload command. Replace src (the location of your projects source files to be uploaded to HubSpot) and cms-theme-boilerplate (the destination name of your project in your HubSpot CMS account.

Note: if files are removed from your project, they will need to be manually deleted within the HubSpot Design Manager. 

  1. generate-config.js - a node script to generate an authentication file to deploy to your production HubSpot CMS account.

Enter the following in this file:

JavaScript
#!/usr/bin/env node

const path = require('path');
const fs = require('fs');
const yaml = require('js-yaml');

const portalId = process.env.HUBSPOT_PORTAL_ID;
const apiKey = process.env.HUBSPOT_API_KEY;

const portalConfig = {
  name: 'PROD',
  portalId,
  apiKey,
};

const config = {
  defaultPortal: 'PROD',
  portals: [portalConfig],
};

fs.writeFileSync(
  path.join(process.cwd(), 'hubspot.config.yml'),
  yaml.safeDump(config)
);

No edits to this file are required.

Make the scripts executable

To make these scripts executable, run the following command in your terminal from your projects root:

Shell script
chmod +x bin/generate-config.js;chmod +x bin/deploy.sh

For Windows users, try this snippet below:

Shell script
git update-index --chmod=+x path/to/file

Create your GitHub action workflow

GitHub Actions allows you to run a workflow on any GitHub event. In your project root, create a file at .github/workflows/deploy.yml

Our deploy workflow is going to occur on pushes to the master branch. Paste the following in your deploy.yml file:

YAML
on:
  push:
    branches:
    - master
jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v1
    - name: Use Node.js
      uses: actions/setup-node@v1
      with:
        node-version: 10.x
    - name: Install NPM deps
      run: |
          npm install
    - name: Generate hubspot.config.yml and deploy
      env:
        HUBSPOT_PORTAL_ID: ${{ secrets.HubSpotPortalId }}
        HUBSPOT_API_KEY: ${{ secrets.HubSpotApiKey }}
      run: |
        bin/generate-config.js
        bin/deploy.sh

Replace ENTER_YOUR_ACCOUNT_ID with your HubSpot account ID. If you need help finding your HubSpot account ID, see Manage multiple HubSpot accounts. ${{ secrets.HubSpotApiKey }} will add your API key secret as an environmental variable in the deploy process, without having to store your API key visibly in source control. Follow the next step to create the HubSpotApiKey secret.

You can refer to the GitHub Actions documentation to learn more about various events you can use to trigger workflows.

Create a secret for your HubSpot account’s API Key and account id

To ensure your HubSpot account’s API key is not visible and stored in source control, we will create a secret for it, that will be passed into the deploy script as an environmental variable. In your GitHub repository, navigate to Settings > Secrets and select “Add a new secret”. Name your new secret HubSpotApiKey, and then enter your HubSpot account’s API key as the value. You can get the API key for your account by navigating to Settings > Integrations > API key, selecting "Create key," and then copying the key. Select “Add secret” to save your secret.

This key will be passed into ${{ secrets.HubSpotApiKey }} from your .github/workflows/deploy.yml file. If you name your secret something other than HubSpotApiKey, make sure to update the ${{ secrets.HubSpotApiKey }} variable with the secret name you set.

While your HubSpot account id is not a true secret, it is useful to repeat this process to add your account id(sometimes referred to as a portal id) as a GitHub Secret.  Create a new secret with the name HubSpotPortalId.  Here's how to get your account id. After doing this you will now be able to reference your account id anywhere in this project using  ${{secrets.HubSpotPortalId}}.

Commit your new folders and files to master

If you have not already committed your new .github/workflows/deploy.yml, bin/deploy.sh and bin/generate-config.js files to your master branch. 

Create, and merge a pull request in master

Now that your secrets, workflows, and scripts are in your GitHub repository, create a pull request, and merge it into master. Once you merge the pull request, navigate to Actions, and you should see your deploy action kick-off and your project deploy to your HubSpot CMS account.

github_action_Deploy

 

Lock your project in the Design Manager

Because the source of truth for your project now lives in GitHub, and master represents your live website, it is important to prevent edits made directly in the Design Manager. Changes to your live developer file system should only come through your deploy action. You can lock projects within the Design Manager by right-clicking on a folder and selecting “Lock folder” to prevent anyone from editing files in the Design Manager.

design_manager_locked_folder