cikit
cikit is a lightweight Python toolkit for implementing local development and CI workflows with reusable Python building blocks instead of large shell scripts or provider-specific pipeline logic.
It combines a project-specific command framework with CI environment abstraction, reusable macros, run data, artifact management, reports, timeline charts, and Sphinx integration.
Highlights
- Project-specific CI commands discovered from a root-level
ci_commandspackage - Unified execution locally and in CI
- Provider support for local Git, GitLab, and Azure DevOps
- Structured environment handling with variable expansion and secret masking
- Ruff, Pylint, pytest, coverage, CMake, CTest, PlatformIO, and Sphinx helpers
- Run-bound metrics and persistent artifact metadata
- Build reports with timings, warnings/errors, memory metrics, artifacts, bundles, and logs
- Local and optional remote cikit data storage for historical metrics
- Configurable SVG timeline charts with line, filled-line, bar, and stacked-bar presets
- Sphinx extensions for inline metrics, interactive charts, collapsible logs, and compact SHA-256 hashes
Installation
cikit requires Python 3.12 or newer.
pip install cikit
For a project using uv, cikit is typically added as a development dependency:
uv add --dev cikit
CI Command Framework
cikit deliberately keeps the concrete workflow in the consuming project. A project provides a
root-level package named ci_commands; the cikit console command discovers its modules and calls
their register() functions automatically.
project/
├── ci_commands/
│ ├── __init__.py
│ ├── init.py
│ ├── lint.py
│ ├── test.py
│ ├── build.py
│ ├── sphinx.py
│ └── all_.py
├── docs/
├── src/
├── tests/
├── pyproject.toml
└── public/
├── artifacts/
├── badges/
├── cikit_data/
└── rst/
A minimal command module can orchestrate reusable cikit macros:
import argparse
from cikit import CiSection
from cikit.ci import run_ci_script
from cikit.macros import ruff
def run(env, status, args):
with CiSection("Running Ruff", status=status):
ruff.ruff(env, args.paths)
with CiSection("Generating Ruff report", status=status):
ruff.write_rst(env)
def command(args):
return run_ci_script("ruff", lambda env, status: run(env, status, args), args=args)
def register(subparsers):
parser = subparsers.add_parser("ruff", help="Run Ruff checks.")
parser.add_argument("paths", nargs="+")
parser.set_defaults(func=command)
The resulting command is executed through the shared runner:
cikit ruff src tests
The logical run name can be overridden globally. It is used for cikit data and artifact metadata:
cikit --name quality ruff src tests
The command set itself is project-specific. The ci_commands package in this repository is both the
workflow used by cikit and a practical reference implementation.
Environment and Providers
cikit.env resolves configuration once and exposes it consistently to commands and macros.
Environment variables may reference previously resolved values using ${VAR} syntax and can be
converted to types such as Path.
from cikit.env import CiEnvironment, get_env_vars
env = CiEnvironment(get_env_vars())
print(env["PROJECT_ROOT"])
print(env.pipeline_id)
print(env.branch_name)
print(env.commit_sha)
Supported providers are:
LOCALGITGITLABAZURE_DEVOPS
Outside a supported CI system, local Git metadata is used as the fallback. Provider metadata includes pipeline, branch, commit, and provider project information without requiring provider-specific logic inside reusable macros.
For cikit data, CIKIT_DATA_ADDRESSING can use either the logical PROJECT_NAME or a provider-based
scope/project key.
Reusable Macros
The cikit.macros package contains the reusable workflow implementation. Command modules should
mainly parse arguments, open CI sections, and compose these macros.
| Module | Purpose |
|---|---|
ruff |
Ruff execution, reports, badges, timelines, and GitLab Code Quality output |
pylint |
Pylint execution, reports, badges, timelines, and rule-specific reports |
pytest |
pytest execution, JUnit XML, and optional parallel coverage collection |
coverage |
Python/gcovr coverage, Cobertura XML, HTML reports, badges, and timelines |
cmake |
CMake configure/build, CTest, build metrics, memory parsing, logs, and reports |
platformio |
PlatformIO builds, compiler metadata, build metrics, memory parsing, logs, and reports |
reports |
Shared test and build report generation |
sphinx |
Documentation preparation, build, and artifact integration |
bundle |
ZIP, TAR, and TAR.GZ bundle creation and registration |
All run-bound macros operate on a CiRunEnvironment, so generated metrics and artifacts belong to a
well-defined logical run.
Build Metrics and Reports
CMake and PlatformIO builds can collect data such as:
- configure, build, and total build time
- compiled file counts
- compiler warning and error counts
- memory usage where the toolchain exposes it
- command logs
The generic build report adds the information available for the active run, including timeline charts, memory tables, downloadable build artifacts and bundles with size and SHA-256 metadata, and collapsible logs.
Typical usage:
from pathlib import Path
from cikit.macros import cmake
build_dir = cmake.get_build_dir(env)
cmake.cmake_configure(
env,
source_dir=Path("."),
build_dir=build_dir,
generator="Ninja",
clean=True,
)
cmake.cmake_build(env, build_dir)
cmake.write_rst(env)
PlatformIO follows the same run-data and report model:
from cikit.macros import platformio
platformio.build(env, clean=True)
platformio.write_rst(env)
Artifacts and Bundles
Artifacts are owned by CiRunEnvironment. Generated files are copied into cikit-managed storage and
registered together with their logical run, artifact type, file size, and hash metadata.
from pathlib import Path
from cikit.artifacts import ArtifactType
artifact = env.copy_artifact(Path("build/firmware.bin"), ArtifactType.BUILD)
print(artifact.path)
print(artifact.size)
print(artifact.hash)
For file artifacts, cikit records the size and calculates a SHA-256 hash automatically unless a hash
is supplied explicitly to copy_artifact(). Folder artifacts use None for size and hash by
default.
Runtime artifact paths are absolute, while the persistent registry stores portable paths relative to the configured artifact root. Artifacts can later be queried by run and type, which allows separate pipeline steps to exchange generated reports and build outputs without depending on physical output paths.
Bundles can package one file or a complete directory:
from pathlib import Path
from cikit.macros import bundle
bundle.create(env, "firmware-package.zip", Path("build/release"))
Supported bundle formats are .zip, .tar, and .tar.gz. Bundle artifacts can be included directly
in generated build reports.
cikit Data
cikit.data stores structured data per logical run and provides historical queries for reports,
badges, and timeline charts.
It supports three operating modes:
- local JSON cache only
- remote cikit Data API only
- local cache with remote synchronization
Run-bound access is normally provided by CiRunEnvironment:
env.data_set("build_time", 4.2)
env.data_update({"warnings": 0, "errors": 0})
data = env.data
Timeline data can be queried from the remote backend using reference keys such as timestamps, pipeline IDs, commit hashes, or relative indices.
The repository also contains the small PHP/MySQL reference backend used by the cikit Data API, including schema initialization scripts.
Timeline Charts
cikit.timeline renders cikit data as SVG charts using Pygal. TimelineChart validates timeline data
and can render directly or register the result as an artifact.
from cikit.timeline import TimelineChart, TimelinePreset
chart = TimelineChart(data, "Build duration", TimelinePreset.LINE_REPORT)
chart.create(env, "build-duration")
Available presets cover general, compact, and report-oriented line and bar charts, a filled report line chart, and stacked bars. Chart options, style, and individual series options can be overridden after selecting a preset.
For development and documentation, all presets can be rendered with deterministic preview data:
python -m cikit.timeline
Sphinx Integration
The Sphinx macro consumes registered artifacts instead of relying on fixed public paths. During preparation it places generated content into the documentation source tree:
- RST artifacts →
docs/_generated - badge artifacts →
docs/_static/badges - other documentation artifacts →
docs/_static/artifacts
The completed HTML documentation is registered again as a folder artifact.
cikit provides a bundled Sphinx extension with reusable roles and directives:
| Extension | RST interface | Purpose |
|---|---|---|
cikit.sphinx_ext.metrics |
:cikit-metric: |
Render a value from the local cikit data cache |
cikit.sphinx_ext.chart |
.. cikit-chart:: |
Embed interactive SVG charts in HTML with a non-HTML fallback |
cikit.sphinx_ext.log |
.. cikit-log:: |
Embed collapsible command logs with a non-HTML fallback |
cikit.sphinx_ext.hash |
:cikit-hash: |
Render compact SHA-256 hashes with tooltip and clipboard support |
The recommended configuration enables all cikit extensions through the package extension:
extensions = [
"cikit.sphinx_ext",
]
Individual extensions can still be enabled separately if required.
Example RST:
Build time: :cikit-metric:`build.build_time` seconds.
.. cikit-chart:: ../_static/artifacts/chart_build.svg
:alt: Build timeline
.. cikit-log:: ../_static/artifacts/build.log
:title: Build log
Package hash: :cikit-hash:`0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef`
Console Entry Points
The package currently installs three console entry points:
| Command | Purpose |
|---|---|
cikit |
Discover and run project-specific commands from ci_commands |
cikit-data |
Access local/remote cikit data operations directly |
cikit-env |
Inspect, export, document, and prepare the resolved cikit environment |
Use --help on each command for the available options. Concrete cikit subcommands depend on the
current project's ci_commands package.
Design Goals
- Keep project workflow logic in readable Python
- Share the same commands between local development and CI
- Separate provider metadata from reusable workflow implementation
- Keep generated data and artifacts associated with explicit logical runs
- Make pipeline steps composable through persistent artifact metadata
- Keep reports and documentation generated from the same underlying data
- Remain lightweight and testable with a small runtime dependency set
Documentation
The full documentation covers environment configuration, providers, project metadata, command architecture, local workflows, GitLab integration, cikit data, artifacts, build reports, and Sphinx integration:
https://cikit-a4de14.gitlab.io/
Repository:
https://gitlab.com/svesch/cikit
License
GPL-3.0-or-later
Metadata
Release files for cikit 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| cikit-0.1.0.tar.gz | 1.1 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cikit-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.2 MB
Release files / cikit-0.1.0.tar.gz
| Download URL | cikit-0.1.0.tar.gz |
|---|---|
| Size | 1.1 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
499e926787abcf73bef453dfdfb57b26c064865a418090ba1997d41a850446b7
|
|
BLAKE2b-256 checksum How to use checksums |
5edf806eb1333488c0478eafcd52fbb11b781d89329f13107c0741358126057c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.7.15
|
Release files / cikit-0.1.0-py3-none-any.whl
| Download URL | cikit-0.1.0-py3-none-any.whl |
|---|---|
| Size | 142.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d584164be5877a79926869630012eaa1f06096e5a51644b96843a747780553f6
|
|
BLAKE2b-256 checksum How to use checksums |
ac863407dad04a3394bffd5ca25aac1a4ce70ab071d0f374a83727c7aaa4fb0b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.7.15
|