Skip to content

GitHub Actions

This guide explains the GitHub Actions starter workflows generated by haute init. They run validation and deployment commands, but GitHub repository settings—not Haute—control branch protection, environment approval, and who may run production deployment. Databricks is the only end-to-end service-update adapter; generic container builds/pushes only, and Azure Container Apps, AWS ECS, and GCP Cloud Run build and push the image and leave the service update to you.

New to Git, pull requests, or CI/CD?

This page assumes you understand basic Git concepts like branches, commits, and pull requests. If these are unfamiliar, read Before You Start first - it explains everything in plain English.

Not sure if this is the right page?

If you access your project on github.com, this is the right page. If it's on gitlab.com (or a company GitLab server), go to GitLab CI/CD. If it's on dev.azure.com, go to Azure DevOps. If you're not sure, ask your IT team or tech lead: "Where is our code repository hosted?" They'll tell you GitHub, GitLab, or Azure DevOps.

What is CI/CD?

CI (Continuous Integration) means your code is automatically tested every time you propose a change. CD (Continuous Deployment) means the workflow can run a deployment step after those tests pass. A live endpoint is created or updated only when the selected target and hosting process support it. See full explanation.

Read this before enabling the starter workflows

The files are examples that call haute deploy, haute smoke, and haute impact in order. Haute does not create staging infrastructure, wait for a newly provisioned endpoint to become ready, require an approval, or guarantee an impact report. A failed deploy prevents dependent smoke and impact jobs. For platform-container targets, the deploy job succeeds once the image is pushed and prints its tag for your manual platform update; their generated workflow has no smoke or impact job, because nothing runs the new image until you update the service. Add a Databricks readiness wait or a container-hosting handoff before enabling downstream smoke and impact jobs.

What is GitHub Actions?

GitHub Actions is GitHub's built-in automation tool. It runs scripts (called workflows) in response to events in your repository - like opening a pull request or merging to the main branch. It's free for public repositories and has a generous free tier for private ones.

Who does what on this page?

This page has two parts. As a pricing analyst, you only need to do Step 2 (commit the workflow files) and Step 3 (test it). Step 1 (adding secrets) is usually done by your IT team or tech lead - they have the credentials and know the GitHub UI. If you're setting this up yourself, Step 1 walks you through it, but it's perfectly fine to hand it to IT and say: "Can you add these secrets to our GitHub repository? Here's the .env.example file listing what's needed."


What Haute generates

When you run haute init --ci github, Haute creates three workflow files in .github/workflows/:

File When it runs What it does
ci.yml On every pull request Lints, type-checks, runs tests, validates your pipeline
deploy-staging.yml On a push to main or manual dispatch Runs validation, then deploy/smoke/impact commands in dependency order
deploy-production.yml When you click "Run workflow" manually Runs haute deploy for production; configure GitHub protections if approval is required

This gives you a complete release pipeline:

Pull request → CI checks → Merge → target-dependent staging deploy → smoke/impact only if deploy succeeds → [your GitHub approval process] → manually triggered production deploy

How it works, step by step

1. You make a change and open a pull request

You edit your pipeline, update a model, or change a configuration. You push your changes to a branch and open a pull request (PR) on GitHub - which is a way of asking your teammate to review your changes before they go live.

2. CI runs automatically

The ci.yml workflow runs immediately:

  • Lint & format - checks your code style with ruff
  • Type check - runs mypy to catch type errors
  • Tests - runs pytest
  • Pipeline validation - runs haute lint and haute deploy --dry-run to check your pipeline parses correctly and test quotes pass

If any of these fail, the PR gets a red ❌ and you can see what went wrong.

3. You merge to main

Once CI passes and your teammate has reviewed the PR, you merge it - which applies your changes to the main version of the project. This triggers the deploy.yml workflow.

4. Staging deployment (automatic)

The deploy workflow:

  1. Validates again (same checks as CI)
  2. Deploys to staging - runs haute deploy --endpoint-suffix "-staging". Databricks submits an endpoint create/update request but does not wait for readiness; the generic container target does not host an endpoint; platform-container targets push the image and leave the service update to you, so their workflow ends there.
  3. Smoke tests staging - only after a successful deploy, runs haute smoke --endpoint-suffix "-staging" against an existing live endpoint
  4. Runs impact analysis - only after smoke succeeds, runs haute impact --endpoint-suffix "-staging" against existing staging and production endpoints

When the impact command runs, its report is uploaded as an artifact; it is not produced when an earlier stage fails.

5. You review the impact report

The impact report shows you exactly what changed:

Output: technical_price
  Staging mean:     548.57     Production mean:   536.12
  Mean change:       +2.3%    Rows changed:      84.2%
  Max increase:     +18.7%    Max decrease:       -4.2%

  ⚠ 147 quotes changed by more than ±25.0%
  ✓ Average change (+2.3%) within ±10.0% threshold

This is where you decide: does this change make sense? Is the impact expected?

6. You promote to production (manual)

If you're happy with the impact report, go to the Actions tab in GitHub, find the Deploy → Production workflow, and click Run workflow.

You can optionally paste the git SHA from the staging deploy to make sure you're deploying exactly what was tested - not something that was merged since.

The production workflow runs haute deploy and then tags the release. Its ability to update a live endpoint depends on the selected target; configure GitHub environments/branch protections separately if this action needs approval.


Setup

Step 1: Add your credentials as GitHub Secrets

This step is usually done by IT

If you're not comfortable navigating GitHub's settings, ask your IT team or tech lead to do this. Give them the .env.example file from your project - it lists exactly which secrets are needed.

Your CI/CD workflows need credentials stored securely in GitHub.

  1. Go to your repository page on GitHub (e.g. github.com/yourcompany/motor-pricing)
  2. Click the ⚙️ Settings tab (near the top of the page, next to "Insights")
  3. In the left sidebar, click Secrets and variables → Actions
  4. Click the green New repository secret button
  5. For each credential below, enter the Name and Secret value, then click Add secret:

For Databricks:

Secret name Value
DATABRICKS_MLFLOW_HOST The workspace URL for MLflow and the model registry
DATABRICKS_MLFLOW_TOKEN A personal access token scoped for MLflow and the model registry
DATABRICKS_RATING_HOST Your workspace URL (e.g. https://adb-xxx.12.azuredatabricks.net)
DATABRICKS_RATING_TOKEN Your personal access token (starts with dapi) scoped for Model Serving

For Docker/Container targets:

Secret name Value
DOCKER_USERNAME Your registry username
DOCKER_PASSWORD Your registry password or access token

For AWS ECS:

Secret name Value
DOCKER_USERNAME AWS
DOCKER_PASSWORD ECR auth token
AWS_ACCESS_KEY_ID Your AWS access key
AWS_SECRET_ACCESS_KEY Your AWS secret key
AWS_DEFAULT_REGION e.g. eu-west-1

For Azure Container Apps:

Secret name Value
DOCKER_USERNAME Your ACR name or service principal app ID
DOCKER_PASSWORD Your ACR password or service principal secret
AZURE_SUBSCRIPTION_ID Your Azure subscription ID
AZURE_TENANT_ID Your Azure tenant ID
AZURE_CLIENT_ID Your service principal app ID
AZURE_CLIENT_SECRET Your service principal password

How to find these values

These are listed in the .env.example file that haute init generated in your project. Your target's setup page explains where each value comes from.

Step 2: Commit the workflow files

The workflow files were created by haute init in .github/workflows/. Make sure they're committed to your repository:

git add .github/
git commit -m "Add CI/CD workflows"
git push

What do these commands mean?

  • git add - tells Git to include these files in your next save
  • git commit -m "..." - saves a checkpoint with a description
  • git push - uploads the changes to the shared copy (GitHub)

See Git workflow for a full explanation.

Step 3: Test it

  1. Create a branch, make a small change, and open a pull request
  2. Watch the Actions tab - the CI workflow should start automatically
  3. If it passes, merge the PR
  4. Watch the deploy workflow run - it should deploy to staging and generate an impact report

The generated workflows in detail

You don't need to read or understand the YAML below

The workflow files were generated by haute init and work out of the box. The sections below are reference only - for troubleshooting or if your IT team wants to understand what’s happening.

ci.yml - Pull request checks
name: CI

on:
  pull_request:
    branches: [main]

jobs:
  lint:
    # Runs ruff check and ruff format --check
  typecheck:
    # Runs mypy
  test:
    # Runs pytest
  pipeline-validate:
    # Runs haute lint and haute deploy --dry-run

This runs on every pull request targeting main. All four jobs run in parallel for speed.

deploy.yml - Merge to main
name: Deploy

on:
  push:
    branches: [main]
    paths:
      - "*.py"
      - "haute.toml"
      - "data/**"
      - "models/**"
      - "tests/quotes/**"

jobs:
  validate:     # Same checks as CI
  deploy-staging:  # haute deploy --endpoint-suffix "-staging"
  smoke-test:      # haute smoke --endpoint-suffix "-staging"
  impact-analysis: # haute impact --endpoint-suffix "-staging"

This only triggers when relevant files change (Python files, config, data, models, test quotes). Jobs run in sequence - if staging fails, smoke test doesn’t run.

deploy-production.yml - Manual production deploy
name: Deploy → Production

on:
  workflow_dispatch:
    inputs:
      sha:
        description: Git SHA that was staged & impact-analysed
        required: false

jobs:
  deploy-production:
    # Verifies SHA matches (if provided)
    # Runs haute deploy (no suffix = production)
    # Tags the release in Git

This is triggered manually from the GitHub Actions UI. The optional SHA input lets you pin the exact commit that was tested.


Working solo?

If you're the only person on the team, the process is the same but simpler:

  1. min_approvers in haute.toml is not enforced by Haute; configure GitHub environment or branch rules for any required approvers
  2. The generated workflow attempts CI → staging → smoke test → impact analysis → manual production deploy; later jobs require a ready endpoint and do not run after a failed deploy
  3. An impact report is generated only when the impact command runs successfully

Troubleshooting

Workflow doesn't trigger

  • On PR: Make sure the PR targets the main branch (not another branch)
  • On merge: Make sure the deploy.yml paths filter matches your changed files. If you only changed a markdown file, it won't trigger (by design)
  • Check the Actions tab: Go to your repo → Actions → look for the workflow run

"Credentials not found" or "Authentication failed"

Your GitHub Secrets are missing or misnamed. Double-check:

  1. Go to Settings → Secrets and variables → Actions
  2. Verify the secret names match exactly (they're case-sensitive)
  3. Verify the values are correct (no trailing spaces or newlines)

Deploy workflow succeeds but endpoint isn't updated

Check the deploy step logs in the Actions run. For Azure Container Apps, AWS ECS and GCP Cloud Run this is expected: the log ends with Image pushed: and The <target> service was not updated, and you point the service at that image yourself (see your target's documentation).

Impact analysis shows unexpected results

The impact analysis compares staging vs production. On a first deploy, a missing production endpoint is recorded as a first-deployment report; a missing or unready staging endpoint is still a real failure. Make sure staging is ready before the impact job runs.

"Staged SHA does not match"

This error in the production workflow means someone merged another PR between your staging deploy and your production deploy. The production workflow is protecting you from deploying untested code. Run the staging deploy again (push to main or re-run the deploy workflow) and then try production again.