Skip to main content

CEP 31 - Build provenance metadata

Title Build provenance metadata
Status Accepted
Author(s) Jaime Rodríguez-Guerra <jaime.rogue@gmail.com>
Created Mar 10, 2025
Updated Mar 4, 2026
Discussion https://github.com/conda/ceps/pull/113
Implementation https://github.com/conda/conda-build/pull/4303, https://github.com/conda-forge/conda-smithy/pull/1577
Requires CEP 34

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC2119 when, and only when, they appear in all capitals, as shown here.

Abstract

This CEP aims to standardize how the conda ecosystem leverages free-form recipe metadata to annotate build provenance of its published artifacts.

Motivation

Provenance metadata is useful to assess how and when a conda artifact was built.

Since late 2023, thanks to conda-smithy 3.28.0 and later, conda-forge feedstocks have been adding CI provenance in the produced artifacts. The defaults channel also applies the same conventions. This is used by apps like conda-metadata-app to show provenance information in the build details. See the table in this Python 3.13 example.

This was possible thanks to a new --extra-meta flag added in conda-build#4303 and released in 3.21.8. Rattler-build also offers the same functionality using the same CLI flag. --extra-meta allows passing arbitrary key-value pairs that will be added to the info/about.json, under the extra key (as defined in CEP 34). For example, if a user passes --extra-meta date=2025-03-11, about.json will contain:

{
// ...
"extra": {
"date": "2025-03-11"
},
// ...
}

Specification

Build provenance metadata is optional. If necessary, the following metadata keys MAY be used to record the corresponding information:

  • sha: String. If the recipe is under version control, it SHOULD be the full commit hash. Otherwise, it SHOULD be an empty string.
  • remote_url: String. If the recipe is under version control, it SHOULD be the CVS URL of the recipe repository being built. HTTP(S) is preferred.
  • flow_run_id: String. It SHOULD be an unambiguous identifier for the pipeline run that produced the artifact. See examples for some recommendations.

Examples

conda-forge/linux-64::python-3.13.2-hf636f53_101_cp313.conda has the following provenance metadata:

{
"sha": "50a4e2d4203f05082fcbb93e14541180de3aa8ac",
"remote_url": "https://github.com/conda-forge/python-feedstock",
"flow_run_id": "azure_20250217.3.1"
}

flow_run_id tends to adopt the following syntax: {ci-provider}_{run-id}. Depending on the CI platform, this may be obtained through different means. For example:

  • AppVeyor on Windows: appveyor_${APPVEYOR_BUILD_ID}.
  • Azure DevOps Pipelines: azure_$(Build.BuildNumber).$(System.JobAttempt). Note this is using Azure Pipelines' macros instead of environment variables.
  • Circle CI: circle_${CIRCLE_WORKFLOW_ID}.
  • Drone CI: drone_${DRONE_BUILD_NUMBER}.
  • GitHub Actions: github_${GITHUB_RUN_ID}.
  • Travis CI: travis_${TRAVIS_JOB_ID}.

Rejected ideas

Additional provenance metadata can be collected for source origins, which can be useful for efforts like dependency mapping across ecosystems. See PEP 725 for practical applications in the context of PyPI/conda interoperability. This type of provenance is out of scope for this CEP and may be discussed separately.

Acknowledgements

These efforts were spearheaded by Connor Martin and Daniel Bast at Anaconda, and Isuru Fernando at conda-forge.

All CEPs are explicitly CC0 1.0 Universal.