Skip to content

Introduce a "PR mode" for attestations #3265

Closed as not planned
Closed as not planned

Description

@migmartri

Context / problem

When an attestation runs as part of a pull request / merge request, Chainloop today treats it the same as a build on main/a release. That causes two side-effects we don't want for PR builds:

  1. Latest promotion — PR builds get promoted to the project's "latest" version. The current workaround is manually passing --mark-latest=false, but that flag was really meant to express "this is a PR build". We're overloading a low-level flag to express a higher-level concept.
  2. Findings processing — policy violations from a PR build get processed (and later re-processed) as if they were findings from a real merge/release build. We want PR-originated attestations to be tagged so downstream consumers can choose not to (re)process them.

The underlying insight: the real concept we want is "PR mode", and both behaviors above should flow from that single signal rather than being manually wired via --mark-latest.

Decision (simplified)

After discussion, we're simplifying the original proposal. Instead of adding a new field on the WorkflowRun ent schema or tagging the policy evaluation object, we'll set a top-level annotation on the attestation. This keeps the change minimal and decouples the PR signal from the policy evaluation pipeline.

Well-known annotation key: chainloop.dev/is-pull-request with value "true".

This leverages the existing annotations map on the Attestation proto (crafting_state.proto), which already flows through the rendering pipeline — no proto schema changes, no DB migration, no codegen churn.

Detection — auto-detect + explicit override

  • Auto-detect from the CI runner environment (already implemented in DetectPRContext / prmetadata.go):
    • GitHub Actions: GITHUB_EVENT_NAME=pull_request (or pull_request_target).
    • GitLab: CI_PIPELINE_SOURCE=merge_request_event / CI_MERGE_REQUEST_IID.
    • Dagger: delegates to the parent CI env vars.
  • Explicit --pr / --pr=false flag on chainloop attestation init overrides auto-detection (zero-config in CI, escapable for edge cases / self-hosted / generic runner).

Behavior when in PR mode (by default)

  • Skip latest promotion — default to mark-latest=false. An explicitly-passed --mark-latest=true still wins (respect explicit user intent). This replaces the manual --mark-latest=false workaround.
  • Set the chainloop.dev/is-pull-request=true annotation on the attestation so downstream consumers (e.g. findings processing) can detect PR-originated attestations and skip (re)processing.

Scope split

  • OSS (this issue): capture & propagate the PR signal as a top-level annotation on the attestation; wire --pr flag and mark-latest default behavior.
  • SaaS (downstream): findings processing/reprocessing reads the annotation and decides whether to process. Not in scope for this issue.

Relevant code pointers

  • PR detection (existing): pkg/attestation/crafter/prmetadata.go (DetectPRContext), pkg/attestation/crafter/collector_prmetadata.go.
  • Runner env vars: pkg/attestation/crafter/runners/githubaction.go, gitlabpipeline.go, daggerpipeline.go.
  • CLI flags: app/cli/cmd/attestation_init.go (--mark-latest).
  • Attestation proto (annotations map): pkg/attestation/crafter/api/attestation/v1/crafting_state.proto (Attestation.annotations, field 5).
  • Crafter init (where annotation would be set): pkg/attestation/crafter/crafter.go (initialCraftingState).
  • Action layer: app/cli/pkg/action/attestation_init.go.

🤖 Posted by Maximus bot (Claude Code) on behalf of @migmartri

Activity

  1. self-assigned this
    on Jul 6, 2026
  2. migmartri commented on Jul 15, 2026

    @migmartri
    MemberAuthor

    Reopening this because the "skip latest promotion" part of PR mode was causing unwanted side-effects. In #3289 we've decoupled PR mode from latest promotion — PR mode now only sets the chainloop.dev/is-pull-request annotation, and --mark-latest remains the explicit control for promotion.

    cc @jiparis @javirln — let's review the approach for how (and whether) PR mode should influence latest promotion before wiring it back in.

    🤖 Posted by Maximus bot (Claude Code) on behalf of @migmartri

  3. jiparis commented on Jul 15, 2026

    @jiparis
    Member

    cc @jiparis @javirln — let's review the approach for how (and whether) PR mode should influence latest promotion before wiring it back in.

    I think it shouldn't influence latest promotion at all. Here we want to avoid PR evaluations from being ingested by findings processing, right? I don't think latest matters here, but in general, you'd want to use --latest-version for PRs, so that they are attached to whichever the latest version is currently, without creating nor promoting any new version.

  4. github-actions commented on Sep 14, 2026

    @github-actions
    Contributor

    This issue is stale because it has been open for 60 days with no activity. It will be closed in 7 days if no further activity occurs.

  5. github-actions commented on Sep 21, 2026

    @github-actions
    Contributor

    This issue was closed because it has been inactive for 7 days since being marked as stale. Feel free to reopen if it is still relevant.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions