Providers

Overview

cikit isolates CI-provider-specific behavior behind a common provider interface.

This allows the same project commands and macros to run:

  • locally from a Git checkout

  • in GitLab CI

  • in Azure DevOps

Provider-specific details such as pipeline identifiers, project identity, branch information, commit metadata, and CI log grouping are resolved by the active provider.

The current provider implementations are:

  • LocalGitProvider

  • GitLabProvider

  • AzureDevOpsProvider

They are identified through the CIProvider enum:

from cikit.env import CIProvider

CIProvider.LOCALGIT
CIProvider.GITLAB
CIProvider.AZURE_DEVOPS

Provider Interface

All providers derive from BaseProvider and expose the same core interface.

Project Identity

Provider-specific project identity is represented by:

provider.provider_scope
provider.provider_project

The exact meaning depends on the provider.

Examples:

GitLab
    provider_scope   = project namespace
    provider_project = project name

Azure DevOps
    provider_scope   = Azure DevOps project
    provider_project = repository name

Local Git has no provider-specific project identity and therefore returns empty strings for both values.

Pipeline Identity

Providers expose:

provider.pipeline_id
provider.pipeline_alias

pipeline_id is the technical identifier of the current pipeline or run.

pipeline_alias is intended for a human-readable identifier when the provider supplies one. The base implementation falls back to pipeline_id.

Version Control Metadata

The common provider interface also exposes:

provider.branch_name
provider.commit_sha
provider.commit_short_sha
provider.commit_title
provider.commit_message
provider.commit_author
provider.commit_timestamp

Missing metadata is represented by an empty string. A branch that cannot be resolved falls back to DETACHED.

CI Log Sections

Providers may implement CI-specific collapsible log sections through:

provider.section_start(title, collapsed=False)
provider.section_end(title)
provider.log_prefix()

The base implementation returns empty section markers. This allows higher-level logging helpers to use the same interface even when the active provider has no special section syntax.

Provider Detection

The active provider is normally detected automatically by detect_provider().

Detection currently follows this order:

  1. GITLAB_CI=true selects GitLabProvider.

  2. TF_BUILD=true selects AzureDevOpsProvider.

  3. Otherwise LocalGitProvider is used.

Example:

from cikit.env import detect_provider

provider = detect_provider()

The check is case-insensitive for the value true.

CiEnvironment performs this detection automatically when no provider instance is passed explicitly to its constructor.

An explicit provider can be supplied when required, for example in tests or custom integrations:

env = CiEnvironment(
    get_env_vars(),
    provider=provider,
)

Environment Integration

The active provider object is available through:

env.provider

CiEnvironment exposes frequently used pipeline and Git metadata as convenience properties:

env.pipeline_id
env.pipeline_alias
env.branch_name
env.commit_sha
env.commit_short_sha
env.commit_title
env.commit_message
env.commit_author
env.commit_timestamp

These properties delegate to the active provider.

Provider-specific project identity remains part of the provider interface:

env.provider.provider_scope
env.provider.provider_project

This distinction keeps general CI metadata easy to access while leaving provider-specific project identity explicitly attached to the provider.

Provider Comparison

A provider instance can be compared directly with a CIProvider value:

from cikit.env import CIProvider

if env.provider == CIProvider.GITLAB:
    ...

Converting the provider to a string returns the uppercase provider name:

str(env.provider)

Typical results are:

LOCALGIT
GITLAB
AZURE_DEVOPS

LocalGitProvider

LocalGitProvider is the fallback outside supported CI environments.

It derives revision metadata from the current Git checkout and allows the same CI command code to run locally.

Repository Metadata

Git metadata is queried from the repository through the git command.

The provider resolves:

  • branch name

  • full commit SHA

  • short commit SHA

  • commit title

  • complete commit message

  • commit author

  • commit timestamp

The values are loaded lazily and cached after the first access.

If Git metadata cannot be obtained, the provider falls back to the neutral values defined by the provider interface instead of preventing local workflow execution.

Local Pipeline ID

A local execution still needs a pipeline id for run data and optional remote synchronization.

LocalGitProvider first checks:

CIKIT_PIPELINE_ID

If this variable already exists, its value is reused.

Otherwise a pipeline id is generated in the form:

auto-<timestamp>-<random-id>

The generated value is written back to CIKIT_PIPELINE_ID in the current process environment.

This makes the local pipeline id stable across multiple provider instances created during the same process.

Provider Project Identity

LocalGitProvider does not define a provider-specific scope or project:

provider_scope   = ""
provider_project = ""

This is relevant when provider-based cikit data addressing is requested. In that case, the data configuration can fall back to the logical PROJECT_NAME.

Log Output

Local Git does not emit CI-specific section markers.

Its log_prefix() returns two spaces, allowing section-aware logging helpers to indent local output without relying on provider-specific control sequences.

GitLabProvider

GitLabProvider reads pipeline and revision metadata directly from GitLab CI environment variables.

Detection

GitLab is selected when:

GITLAB_CI=true

Project Identity

GitLab provider identity is mapped as follows:

Provider property

GitLab variable

Meaning

provider_scope

CI_PROJECT_NAMESPACE

Project namespace.

provider_project

CI_PROJECT_NAME

Project name.

pipeline_id

CI_PIPELINE_ID

Pipeline identifier.

GitLab does not currently define a separate pipeline_alias implementation, so the common provider fallback returns pipeline_id.

Revision Metadata

GitLab revision metadata uses the corresponding CI variables:

Provider property

GitLab variable

branch_name

CI_COMMIT_REF_NAME

commit_sha

CI_COMMIT_SHA

commit_short_sha

CI_COMMIT_SHORT_SHA

commit_title

CI_COMMIT_TITLE

commit_message

CI_COMMIT_MESSAGE

commit_author

CI_COMMIT_AUTHOR

commit_timestamp

CI_COMMIT_TIMESTAMP

This avoids additional Git subprocesses during GitLab CI execution.

Log Sections

GitLab supports collapsible CI log sections.

GitLabProvider.section_start() and section_end() generate the GitLab section control sequences.

For example, higher-level cikit logging may conceptually emit:

section_start:<timestamp>:run_tests
...
section_end:<timestamp>:run_tests

The section identifier is derived from the human-readable title and normalized for use in GitLab section markers.

GitLab also supports requesting that a section starts collapsed.

AzureDevOpsProvider

AzureDevOpsProvider combines Azure DevOps pipeline metadata with Git metadata from the checked-out repository.

It derives from LocalGitProvider.

Detection

Azure DevOps is selected when:

TF_BUILD=true

Project and Pipeline Identity

Azure DevOps provider identity is mapped as follows:

Provider property

Azure DevOps variable

Meaning

provider_scope

SYSTEM_TEAMPROJECT

Azure DevOps project name.

provider_project

BUILD_REPOSITORY_NAME

Repository name.

pipeline_id

BUILD_BUILDID

Technical pipeline run id.

pipeline_alias

BUILD_BUILDNUMBER

Human-readable build number.

If BUILD_BUILDNUMBER is unavailable, pipeline_alias falls back to pipeline_id.

Branch Name

Azure DevOps branch resolution first uses:

BUILD_SOURCEBRANCH

The standard prefixes are removed:

refs/heads/main
-> main

refs/tags/v1.2.3
-> v1.2.3

If BUILD_SOURCEBRANCH does not provide a usable branch or tag name, BUILD_SOURCEBRANCHNAME is used.

If neither value is available, branch resolution falls back to the inherited local Git implementation.

Commit Metadata

Unlike GitLabProvider, Azure DevOps does not implement separate commit metadata properties.

The following values are inherited from LocalGitProvider and therefore resolved from the checked-out Git repository:

  • commit_sha

  • commit_short_sha

  • commit_title

  • commit_message

  • commit_author

  • commit_timestamp

This keeps Azure pipeline metadata and repository metadata separate.

Log Groups

Azure DevOps supports collapsible log groups through logging commands.

The provider emits:

##[group]Title
...
##[endgroup]

The common collapsed argument is accepted by the provider interface but Azure DevOps does not support choosing the initial collapsed state through the group marker.

Provider Comparison

The three providers differ mainly in where their metadata comes from:

Capability

Local Git

GitLab

Azure DevOps

Detection

Fallback

GITLAB_CI

TF_BUILD

Pipeline id

Generated or CIKIT_PIPELINE_ID

CI_PIPELINE_ID

BUILD_BUILDID

Pipeline alias

Pipeline id

Pipeline id

BUILD_BUILDNUMBER

Provider scope

Not available

Namespace

Azure project

Provider project

Not available

GitLab project

Repository

Commit metadata

Local Git

GitLab variables

Local Git

CI log sections

No provider markers

GitLab sections

Azure log groups

Cikit Data Addressing

Provider project metadata is independent of cikit data addressing. The remote cikit Data project key is built from PROJECT_NAME and the optional tool.cikit.data_scope value in pyproject.toml.

This keeps the project key identical during local execution, GitLab CI, Azure DevOps, and other providers. See Cikit Data for the complete model.

CI Sections and CiSection

Provider section support is consumed by higher-level logging helpers such as CiSection.

The caller works with a provider-independent section abstraction while the provider determines the actual output syntax.

Conceptually:

CiSection
   |
   +-- Local Git
   |      -> regular local output
   |
   +-- GitLab
   |      -> section_start / section_end
   |
   `-- Azure DevOps
          -> ##[group] / ##[endgroup]

This keeps CI command code independent from the active provider’s logging protocol.

Extending Provider Support

Additional CI systems can be integrated by implementing the BaseProvider interface.

A provider can supply only the metadata and behavior available from that CI system. Unimplemented properties automatically retain the neutral fallback behavior from BaseProvider.

Typical integration points are:

  • provider detection

  • pipeline identity

  • provider scope and project

  • branch and commit metadata

  • CI log section markers

Project commands and macros can then continue to use the provider-independent environment interface.

See Also