Skip to content

Continuous Integration

License Manager employs GitHub Actions for its continuous integration processes. Detailed descriptions of these actions are provided on this page.

Automated Quality Assurance

The test_on_push.yaml action runs the quality assurance checks (make qa: unit tests, linters, formatters, type checkers) for each sub-project (lm-agent, lm-api, lm-cli, lm-simulator, lm-simulator-api) independently. It is triggered on every push to main/release/** and on every pull request.

Automated Publication

License Manager's sub-projects are published to PyPI, the lm-agent, lm-api and lm-simulator-api container images are published to GHCR, lm-api's image is additionally published to Amazon ECR (Vantage's private registry), the standalone Helm chart is published to GHCR as an OCI artifact, and the agent snap is released to the Snap Store's edge/candidate channels. These are handled by the linked GitHub Actions detailed below.

Prepare for release

prepare_release.yaml is triggered manually via a workflow dispatch whenever new features or fixes need to be published. It takes a base version bump (major/minor/patch/stable) and an optional prerelease/stage bump (alpha/beta/rc/post/dev) as inputs.

Once activated, this action:

  • Uses uv to bump the version on all five sub-projects (lm-agent, lm-api, lm-cli, lm-simulator, lm-simulator-api) to the same new version, and fails if they end up out of sync.
  • Builds the changelog for the new version with Towncrier.
  • Creates a new branch named prepare-release/<version>.
  • Opens a draft pull request titled Release <version>.

This lets all the changes above be reviewed, with the full QA suite running against the pull request, before anything is published.

Create a new tag

tag_on_merged_pull_request.yaml triggers once the release PR (branch prepare-release/<version>) is merged into main or a release/** branch. It creates and pushes a new git tag named after the version.

Publish on Tag

publish_on_tag.yaml triggers when a version tag is pushed. It double-checks the tag matches each sub-project's version, then runs three independent jobs:

  • build-publish: builds and publishes lm-agent, lm-api, lm-cli, lm-simulator and lm-simulator-api to PyPI.
  • publish-to-ghcr: builds and pushes lm-agent, lm-api and lm-simulator-api container images to GHCR, tagged by docker/metadata-action with the semver version, {major}.{minor}, {major}, the git ref, and the commit SHA.
  • publish-to-ecr: additionally builds lm-api's image and pushes it to Amazon ECR (Vantage's private registry).
  • snapstore: builds the lm-agent snap and releases it to the Snap Store's edge/candidate channels.

Automated Publication of the Helm Chart

lm-api can also be deployed standalone via the Helm chart at helm/lm-api in this repository. It is a generic chart with no cloud-specific assumptions (no hardcoded node affinity, no cloud Ingress annotations); see the chart's own README.md for requirements and configuration.

The chart is versioned independently from the application (its own version in Chart.yaml), since chart changes (e.g. a resource limit tweak) happen at a very different cadence than application releases. It is published by publish_lm_api_helm_chart.yaml, which:

  • Triggers on its own tag, lm-api-chart-v<Chart.yaml version> (e.g. lm-api-chart-v0.2.0), or via manual workflow dispatch.
  • Fails if the tag doesn't match the chart's version in Chart.yaml.
  • Packages the chart and pushes it as an OCI artifact to oci://ghcr.io/omnivector-solutions/charts/lm-api.
  • Attaches the packaged .tgz to a GitHub Release for that tag.

To release a new chart version: bump version in helm/lm-api/Chart.yaml, merge to main, then tag and push lm-api-chart-v<version>.

Install directly from GHCR with:

helm install lm-api oci://ghcr.io/omnivector-solutions/charts/lm-api --version <chart-version>