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:
LocalGitProviderGitLabProviderAzureDevOpsProvider
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:
GITLAB_CI=trueselectsGitLabProvider.TF_BUILD=trueselectsAzureDevOpsProvider.Otherwise
LocalGitProvideris 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 |
|---|---|---|
|
|
Project namespace. |
|
|
Project name. |
|
|
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 |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
|---|---|---|
|
|
Azure DevOps project name. |
|
|
Repository name. |
|
|
Technical pipeline run id. |
|
|
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_shacommit_short_shacommit_titlecommit_messagecommit_authorcommit_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 |
|
|
Pipeline id |
Generated or |
|
|
Pipeline alias |
Pipeline id |
Pipeline id |
|
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.