Skip to main content
HubSpot provides a set of GitHub Actions for automating common project tasks, including uploading, deploying, and validating your projects. You can use these actions to build a CI/CD pipeline that keeps your HubSpot project in sync with your repository automatically. This guide covers how to set up:
  • A basic deployment workflow that uploads your project to HubSpot on every push to main.
  • A multi-environment setup that uses config profiles and multiple workflows to deploy to separate QA and production accounts based on the target branch.
For the full list of available actions and reference documentation, see the hubspot-project-actions repository and GitHub Marketplace page.

Prerequisites

To set up automation with GitHub Actions, you’ll need the following:
  • A GitHub repository with write access for creating repository secrets.
  • An existing HubSpot project built on platform version 2025.2 or higher. For older versions, see the migration steps in the expandable section below.

Set up a basic action

To set up GitHub Actions, you’ll first create the GitHub secrets used for connecting the repository to your HubSpot account, then create a workflow file that runs the HubSpot project action:
  • In your GitHub repository, create repository secrets for the following HubSpot details, which you’ll later reference in your workflow file:
    • HUBSPOT_ACCOUNT_ID: the ID of your HubSpot account.
    • HUBSPOT_PERSONAL_ACCESS_KEY: your personal access key.
  • In your local HubSpot project, create a .github/workflows/ directory if one doesn’t already exist, then create a main.yml file within it. You can give the file any name you’d like, as long as it uses the .yml or .yaml extension.
  • Paste the following code into the file:
.github/workflows/main.yml
on:
  push:
    branches:
      - "main"
env:
  DEFAULT_ACCOUNT_ID: ${{ secrets.HUBSPOT_ACCOUNT_ID }}
  DEFAULT_PERSONAL_ACCESS_KEY: ${{ secrets.HUBSPOT_PERSONAL_ACCESS_KEY }}
  DEFAULT_CLI_VERSION: "8.0.0" # Optional
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Upload to HubSpot
        uses: HubSpot/hubspot-project-actions@v1.1.0
KeyDescription
onConfigures the workflow to trigger on any push to the main branch. You can replace main with your default branch name as needed.
env
  • Stores your GitHub secrets as environment variables so the action can authenticate with your HubSpot account.
  • Specifies a version of the CLI to use for workflow execution. By default, a predetermined stable version is used. When specifying a version, it’s recommended to use a version number (e.g., "8.0.0") rather than "latest" or "next" to prevent new releases from impacting your CI/CD pipeline.
Please note: never set the HUBSPOT_ACCOUNT_ID or HUBSPOT_PERSONAL_ACCESS_KEY secret values directly in this file. Authentication-related values should only be stored as GitHub secrets.
jobsDefines a deploy job, which uses HubSpot project actions to validate and upload the project to your HubSpot account. For more information about each action, check out the hubspot-project-actions repository.
  • With your action defined, push your changes to GitHub.
Moving forward, every push to the main branch will trigger an upload to your target HubSpot account. You can verify that the workflow ran successfully by checking your workflow logs in GitHub and reviewing the project’s build and deploy logs in HubSpot.

Set up multi-environment workflows

If you want to deploy your HubSpot project to separate environments (e.g., a QA account for testing and a production account for live deployments), you can combine HubSpot’s config profiles with multiple workflows. In this type of setup, the config profiles let you define environment-specific settings in your project, including which HubSpot account to target. By pairing each profile with its own workflow file, you can control which HubSpot account gets updated based on which branch you push to. For example:
  • QA workflow: when you push to the qa branch, deploy the project to your test HubSpot account.
  • Production workflow: when you push to main, deploy the project to your production HubSpot account.
A push is one of many available workflow triggers. Learn more in GitHub’s documentation.

Define config profiles

Before configuring your workflows, create a config profile for each environment you want to target. See build with config profiles for setup instructions. For a standard two-environment setup, you might create:
  • A qa profile targeting your test HubSpot account
  • A prod profile targeting your production HubSpot account
After defining config profiles in your project, commit the hsprofile.*.json files to your repository. Each workflow references its profile by name and resolves it from these committed files at upload time.

Create GitHub secrets for each environment

In your GitHub repository, create a pair of secrets for each environment. Each pair should contain the account ID and personal access key for that environment’s HubSpot account. Each environment’s account ID secret must match the accountId defined in that profile’s hsprofile.*.json file. For example:
  • For a qa profile targeting account 12345:
    • HUBSPOT_QA_ACCOUNT_ID = 12345
    • HUBSPOT_QA_PERSONAL_ACCESS_KEY = <personal access key for account 12345>
  • For a prod profile targeting account 67890:
    • HUBSPOT_PROD_ACCOUNT_ID = 67890
    • HUBSPOT_PROD_PERSONAL_ACCESS_KEY = <personal access key for account 67890>

Create a workflow file for each environment

In your project, create a dedicated workflow file for each environment. Each workflow targets a different branch and passes the profile name along with its credentials as explicit with inputs to the project-upload sub-action, as shown below.
Please note: when using profiles, you must pass credentials as with inputs to the project-upload action. The env variable approach used in the basic setup does not propagate correctly when using profiles.
QA workflow: deploys the project to your test HubSpot account when changes are pushed to the qa branch.
deploy-qa.yml
on:
  push:
    branches:
      - "qa"
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Upload to HubSpot (QA)
        uses: HubSpot/hubspot-project-actions/project-upload@v1.1.0
        with:
          profile: "qa"
          account_id: ${{ secrets.HUBSPOT_QA_ACCOUNT_ID }}
          personal_access_key: ${{ secrets.HUBSPOT_QA_PERSONAL_ACCESS_KEY }}
Production workflow: deploys the project to your production HubSpot account when changes are pushed to the main branch.
deploy-prod.yml
on:
  push:
    branches:
      - "main"
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Upload to HubSpot (PROD)
        uses: HubSpot/hubspot-project-actions/project-upload@v1.1.0
        with:
          profile: "prod"
          account_id: ${{ secrets.HUBSPOT_PROD_ACCOUNT_ID }}
          personal_access_key: ${{ secrets.HUBSPOT_PROD_PERSONAL_ACCESS_KEY }}
With this setup, every push to qa triggers a deployment to your test account, and every push to main triggers a deployment to your production account. You can extend this pattern by adding additional workflow files for other environments, each with their own branch trigger, secrets, and profile name.

Verify workflow success

To verify that your workflows have run successfully, you can review the workflow run history in GitHub as well as the project build and deploy logs in HubSpot. When viewing workflow run history in GitHub, you can view the details of each action defined in the workflow to ensure it ran as expected.
Action log details in the GitHub action logs interface
To review the project’s build and deploy logs in HubSpot:
You can also open a project from the terminal by running hs project open from within the project directory. Learn more about project commands.
  • Click the Builds & Deploys tab.
Builds triggered by GitHub Actions are attributed with the commit message and SHA, distinguishing them from manual uploads.
HubSpot developer project build and deploy logs showing a build that was triggered by a GitHub Action.

Troubleshooting

If your GitHub Actions workflow isn’t working as expected, review the common issues and solutions below.

YAML syntax errors

Branch names and other string values in your workflow file must be quoted. For example, - main without quotes can cause a "no event trigger is defined" error. Use - "main" instead:
on:
  push:
    branches:
      - "main"

Action version mismatch

If a feature you expect (such as profile support) isn’t available, ensure you are on at least v1.1.0 of the action. Check the hubspot-project-actions repository for available versions and update the uses line in your workflow file accordingly.

Secrets not configured correctly

If your workflow fails with authentication errors, verify the following:
  • The secret names in your workflow file match exactly what you configured in your GitHub repository settings (e.g., HUBSPOT_ACCOUNT_ID, not HUBSPOT_ACCOUNT_Id).
  • The secret values are correct and have not expired.
  • You’re referencing secrets using the ${{ secrets.SECRET_NAME }} syntax.

Workflow not triggering

If pushes to your branch don’t trigger the workflow:
  • Confirm that the branch name in your workflow file matches the branch you’re pushing to. For example, if your default branch is master rather than main, update the workflow accordingly.
  • Check the Actions tab in your GitHub repository for error messages or disabled workflows.
  • Verify that the workflow file is located at .github/workflows/ and has a .yml or .yaml extension.
Last modified on June 5, 2026