Skip to main content

A CLI tool for automating CI tasks across Charmed Operator repositories

Project description

charmed-analytics-ci

A CLI tool to automate CI-driven integration of updated rock images into consumer Charmed Operator repositories.

This tool is part of Canonical's Charmed Kubeflow stack and enables automated pull request creation after a rock image is built and published. It eliminates manual effort, reduces human error, and supports scalable, reproducible CI/CD pipelines.


✨ Features

  • ✅ Automatically clones target charm repositories
  • 🔁 Updates image references in YAML or JSON configuration files
  • ⚙️ Optionally modifies service-spec fields like user and command
  • 🔧 Validates metadata schemas for correctness before modification
  • 🤖 Opens pull requests with deterministic branches and templated descriptions
  • 🔐 Supports GitHub authentication via token or environment variable
  • 🔗 Optionally links back to triggering PR
  • 📦 Installable via PyPI and usable from CI pipelines
  • 🧪 Supports dry-run mode for previewing changes

🚀 Installation

Install from PyPI:

pip install charmed-analytics-ci

Or install for development:

git clone https://github.com/canonical/charmed-analytics-ci.git
cd charmed-analytics-ci
poetry install

🧪 CLI Usage

After installing, the CLI provides a single command:

chaci integrate-rock METADATA_FILE BASE_BRANCH ROCK_IMAGE [OPTIONS]

Example:

export GH_TOKEN="ghp_abc123..."  # or pass explicitly with --github-token

chaci integrate-rock rock-ci-metadata.yaml main ghcr.io/canonical/my-rock:1.0.0 --dry-run

Arguments:

Argument Description
METADATA_FILE Path to rock-ci-metadata.yaml describing integration targets
BASE_BRANCH Target branch for PRs (e.g. main or develop)
ROCK_IMAGE Full rock image string (e.g. ghcr.io/org/my-rock:1.0.0)

Options:

Option Description
--github-token Optional. GitHub token. Falls back to $GH_TOKEN environment variable if not provided.
--github-username Optional. GitHub username. Defaults to "__token__" if not provided.
--clone-dir PATH Optional. Directory where target repos will be cloned (default: /tmp).
--dry-run Optional. If set, changes are simulated but not committed or pushed. Logs changes to console.
--triggering-pr URL Optional. Link to the PR which triggered this run. Included in the PR body if present.

📄 rock-ci-metadata.yaml Format

integrations:
  - consumer-repository: canonical/my-charm
    replace-image:
      - file: "metadata.yaml"
        path: "resources.my-rock.upstream-source"
      - file: "src/images.json"
        path: "config.batcher"
    service-spec:
      - file: "service-spec.json"
        user:
          path: "containers[0].user"
          value: "1001"
        command:
          path: "containers[0].command[1]"
          value: "/start"
  • All file paths are relative to the repo root
  • Paths can use dot and bracket notation for navigating YAML/JSON

🧪 Testing

Unit tests

tox -e unit

🔁 Integration tests

⚠️ These tests interact with a real GitHub repository and require a fine-grained GitHub token with appropriate permissions.

Required GitHub token permissions

The token must be a fine-grained personal access token (PAT) with:

  • Repository access: Select the repository you're testing against
  • Permissions:
    • Contents: Read and write
    • Pull requests: Read and write

These are needed to:

  • Clone the repo
  • Push branches
  • Open and manage pull requests

Setup and run:

export CHACI_TEST_TOKEN=<your_token>
export CHACI_TEST_REPO="org/repo-name"
export CHACI_TEST_BASE_BRANCH="target-branch"

tox -e integration

The integration tests will:

  • Clone the specified repository
  • Create a temporary branch and pull request
  • Validate the PR contents
  • Clean up the branch and PR after execution

🧰 Development & Contributing

This project uses:

To run all checks locally:

tox -e lint,unit,integration

📁 Project Structure

File Purpose
rock_integrator.py Core logic for modifying files with images
git_client.py Git and GitHub abstraction for PR workflow
rock_metadata_handler.py Orchestration for multi-repo integration
rock_ci_metadata_models.py Pydantic model for metadata schema validation
main.py CLI entrypoint via click
templates/pr_body.md.j2 Jinja2 template for pull request bodies

🔒 License

This project is licensed under the Apache 2.0 License.


✍️ Authors

Built by the Canonical Charmed Kubeflow team.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

charmed_analytics_ci-1.2.0.tar.gz (18.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

charmed_analytics_ci-1.2.0-py3-none-any.whl (20.5 kB view details)

Uploaded Python 3

File details

Details for the file charmed_analytics_ci-1.2.0.tar.gz.

File metadata

  • Download URL: charmed_analytics_ci-1.2.0.tar.gz
  • Upload date:
  • Size: 18.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.8

File hashes

Hashes for charmed_analytics_ci-1.2.0.tar.gz
Algorithm Hash digest
SHA256 4ee41be71fd728291c6c2307c6c5f3bb51c7151d57fb3380e3100652e20389cc
MD5 7bd880913a8ad8b24e1c7ebbcc4bfb44
BLAKE2b-256 e80425d250c3db5478c5c4cf80feff0ea0731990bef6294a433eda1189e8571e

See more details on using hashes here.

File details

Details for the file charmed_analytics_ci-1.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for charmed_analytics_ci-1.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 98df69feeefe468c3b1277e1b355a49473161f98ac4505c7e93ca6075d6d002b
MD5 71583e3d924d29e86b9b2df6f2d01ad4
BLAKE2b-256 9f594144b9c423aa1cfaf8f0789abd8daa83a7fdcf7b0d4a2e9248e4c41d057d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page