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.1.0.tar.gz (18.3 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.1.0-py3-none-any.whl (20.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: charmed_analytics_ci-1.1.0.tar.gz
  • Upload date:
  • Size: 18.3 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.1.0.tar.gz
Algorithm Hash digest
SHA256 cbf41a2fd6b863a4620d970a4aa7b8d4f8c22a3a315ddeefd362742510948cc8
MD5 bb9e3d6d504db9e01988baec6660a40e
BLAKE2b-256 038bd3d199c5d0e68b2c711dae58bf8335ba4f6161a41c4948ee3fd30d53fe99

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for charmed_analytics_ci-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8eca7f7feb3ae8da463282b8372568118e6a452d7c9efe1896b8f3ce7a2615a4
MD5 0388158a9c9163bcd4b98f5f152032e5
BLAKE2b-256 2900a7958d99e4a60a717d492845512322a4f1abf198501ed4b3398cd1d3f86a

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