Skip to main content

Pydantic models wrapping GitLab CI/CD YAML with 1:1 mapping

Project description

Gitlab CICD Python Wrapper

Pydantic models wrapping every GitLab CI/CD YAML keyword with 1:1 mapping to GitLab CI/CD YAML reference.

Features

  • Programmatic pipeline generation using Python-native objects
  • Validation framework for existing pipelines
  • Comment-preserving round-trip serialization (load -> validate -> write = identical YAML)
  • GitLab CI/CD Component parsing with input validation
  • Both sync and async APIs
  • CLI validator and pre-commit hook

Installation

pip install gitlab-cicd-python-wrapper

Or with Poetry:

poetry add gitlab-cicd-python-wrapper

Compatibility Matrix

GitLab Version Pipeline Coverage Component Coverage Notes
17.x Full Full All keywords as of 17.9
16.x Full Partial Components GA in 17.0
15.x Partial N/A Deprecated keywords still accepted

Quick Start

Generate a Pipeline

from gitlab_cicd_python_wrapper import Pipeline, Job, Image, Artifacts

pipeline = Pipeline(
    stages=["build", "test", "deploy"],
    jobs={
        "build": Job(
            stage="build",
            image=Image(name="python:3.11"),
            script=["pip install -r requirements.txt", "python setup.py build"],
            artifacts=Artifacts(paths=["dist/"]),
        ),
        "test": Job(
            stage="test",
            script=["pytest"],
            needs=["build"],
        ),
    },
)

print(pipeline.to_yaml())

Validate an Existing Pipeline

from gitlab_cicd_python_wrapper import Pipeline

# Load and validate
pipeline = Pipeline.from_yaml(".gitlab-ci.yml")
print(f"Stages: {pipeline.stages}")
print(f"Jobs: {list(pipeline.jobs.keys())}")

# Validate without loading
errors = Pipeline.validate_file(".gitlab-ci.yml")
if errors:
    for err in errors:
        print(f"Error: {err}")

Round-Trip Editing (Comments Preserved)

from gitlab_cicd_python_wrapper import Pipeline

# Load -> modify -> save preserves comments and formatting
pipeline = Pipeline.from_yaml(".gitlab-ci.yml")
pipeline.to_yaml("validated-output.yml")
# Output is byte-identical to input for unmodified pipelines

CLI Validator

# Validate pipeline files
gitlab-cicd-validate .gitlab-ci.yml

# Validate multiple files
gitlab-cicd-validate .gitlab-ci.yml .gitlab/ci/*.yml

# Validate component templates
gitlab-cicd-validate --component templates/build.yml

# JSON output
gitlab-cicd-validate --format json .gitlab-ci.yml

# Strict mode (fail on warnings)
gitlab-cicd-validate --strict .gitlab-ci.yml

Pre-commit Hook

Add to your .pre-commit-config.yaml:

repos:
  - repo: https://github.com/szymonrychu/gitlab-cicd-python-wrapper
    rev: v0.1.0
    hooks:
      - id: gitlab-cicd-validate
        args: ['--strict']
      - id: gitlab-cicd-validate-components

This validates .gitlab-ci.yml and any YAML files under .gitlab/ci/ automatically, plus component templates under templates/.

Component Parsing

Parse and validate GitLab CI/CD components with input validation:

from gitlab_cicd_python_wrapper import Component

# Load a component template
component = Component.from_yaml("templates/deploy.yml")

# Inspect the spec
for name, input_def in component.spec.inputs.items():
    print(f"{name}: type={input_def.type}, default={input_def.default}")

# Validate inputs (raises ValueError on failure)
resolved = component.validate_inputs({
    "stage": "deploy",
    "environment": "production",
    "timeout": 3600,
})

# Render with inputs interpolated (returns a Pipeline)
pipeline = component.render({
    "stage": "deploy",
    "environment": "production",
    "timeout": 3600,
})
print(pipeline.to_yaml())

Dynamic Child Pipelines

Generate pipelines dynamically for use with trigger:include:

from gitlab_cicd_python_wrapper import Pipeline, Job

services = ["api", "web", "worker"]

jobs = {}
for svc in services:
    jobs[f"build-{svc}"] = Job(
        stage="build",
        image="docker:latest",
        script=[f"docker build -t {svc} services/{svc}/"],
        tags=["docker"],
    )

child = Pipeline(stages=["build"], jobs=jobs)
child.to_yaml("generated-pipeline.yml")

# Parent pipeline triggers it:
# trigger:
#   include:
#     - artifact: generated-pipeline.yml
#       job: generate-pipeline

Async API

import asyncio
from gitlab_cicd_python_wrapper import AsyncPipeline, AsyncComponent

async def main():
    # Pipeline
    pipeline = await AsyncPipeline.from_yaml(".gitlab-ci.yml")
    print(f"Stages: {pipeline.stages}")
    print(f"Jobs: {list(pipeline.jobs.keys())}")
    await AsyncPipeline.to_yaml(pipeline, "validated-output.yml")

    # Component
    component = await AsyncComponent.from_yaml("templates/build.yml")
    resolved = component.validate_inputs({"image": "python:3.12"})

asyncio.run(main())

Docker

Run the validator as a container:

docker run --rm -v $(pwd):/data szymonrychu/gitlab-cicd-python-wrapper /data/.gitlab-ci.yml

PyPI Configuration

To publish this library to PyPI using GitHub Actions trusted publishing:

  1. Create an account at pypi.org
  2. Go to "Your projects" -> "Publishing" -> "Add a new pending publisher"
  3. Set: GitHub owner=szymonrychu, repo=gitlab-cicd-python-wrapper, workflow=pypi.yaml, environment=pypi
  4. Create a GitHub environment named pypi in your repo settings
  5. Push a semantic version tag (e.g., v0.1.0) to trigger the publish workflow

Development

# Install dependencies
mise install
poetry install

# Run tests
poetry run pytest

# Run linters
pre-commit run --all-files

# Run CLI
poetry run gitlab-cicd-validate .gitlab-ci.yml

License

MIT

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

gitlab_cicd_python_wrapper-0.0.34.tar.gz (12.2 kB view details)

Uploaded Source

Built Distribution

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

gitlab_cicd_python_wrapper-0.0.34-py3-none-any.whl (19.3 kB view details)

Uploaded Python 3

File details

Details for the file gitlab_cicd_python_wrapper-0.0.34.tar.gz.

File metadata

File hashes

Hashes for gitlab_cicd_python_wrapper-0.0.34.tar.gz
Algorithm Hash digest
SHA256 3b6d9b06d46821e9a9c3c847a6cc0ca57546f1cbe7595d56392671016d200e4c
MD5 643a0231a91c285fcf6df295c90962e3
BLAKE2b-256 3646f50db108b65a1ba86a8b49b268976a06476e81ac41313c9838ca7c3c2a41

See more details on using hashes here.

Provenance

The following attestation bundles were made for gitlab_cicd_python_wrapper-0.0.34.tar.gz:

Publisher: pypi.yaml on szymonrychu/gitlab-cicd-python-wrapper

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gitlab_cicd_python_wrapper-0.0.34-py3-none-any.whl.

File metadata

File hashes

Hashes for gitlab_cicd_python_wrapper-0.0.34-py3-none-any.whl
Algorithm Hash digest
SHA256 19b92821b47c8f757f7c60e19d5a27bb78ad965804730e622578cd01e50b87ef
MD5 0aa5c5f6a2ae1d6344a5b586bebb4113
BLAKE2b-256 23ad4bbd0a75a0de2d4e81daa17ace5fb8dd9e1d0eb15a01913444b05d1296e0

See more details on using hashes here.

Provenance

The following attestation bundles were made for gitlab_cicd_python_wrapper-0.0.34-py3-none-any.whl:

Publisher: pypi.yaml on szymonrychu/gitlab-cicd-python-wrapper

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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