pub struct Context {
pub config: Config,
pub artifacts: ArtifactRegistry,
pub options: ContextOptions,
pub stage_outputs: StageOutputs,
pub git_info: Option<GitInfo>,
pub token_type: ScmTokenType,
pub skip_memento: SkipMemento,
pub publish_report: Option<PublishReport>,
pub determinism: Option<DeterminismState>,
pub pending_outcome: Option<PublisherOutcome>,
/* private fields */
}Fields§
§config: Config§artifacts: ArtifactRegistry§options: ContextOptions§stage_outputs: StageOutputsStage→stage handoff outputs (changelog text, header/footer, etc.).
git_info: Option<GitInfo>§token_type: ScmTokenTypeThe resolved SCM token type (GitHub, GitLab, or Gitea).
skip_memento: SkipMementoAggregated skips from per-sub-config loops (signs, docker_signs,
publishers, …). Drained by the pipeline runner at end-of-pipeline so
the summary shows what was intentionally skipped — mirroring
GoReleaser’s pipe.SkipMemento pattern. The inner Arc<Mutex<…>>
lets parallel stage workers contribute without extra plumbing.
publish_report: Option<PublishReport>Trait-based publisher dispatch report, set by PublishStage::run
when the per-publisher dispatcher finishes. None until the
publish stage executes (or when publishing is skipped entirely
via snapshot mode / --skip=publish). Downstream stages
(SnapcraftPublishStage, AnnounceStage, future Submitter-group
stages) consult this to apply the submitter-gate / announce-gate
rules — see PublishReport::any_failed.
determinism: Option<DeterminismState>SOURCE_DATE_EPOCH seed + non-determinism allow-list state for the
run. None until a stage (typically BuildStage) seeds it from
resolve_reproducible_epoch(commit_timestamp); downstream stages
(stage-sbom, stage-archive, stage-sign) read sde to derive
deterministic timestamps. Lazy-init by design: tests and snapshot
runs without a clean commit can still proceed.
pending_outcome: Option<PublisherOutcome>Per-publisher outcome override published by Publisher::run when
the artifact reached a non-Succeeded terminal state but run
still returned Ok (e.g. chocolatey moderation skip,
winget/krew/homebrew PR-already-exists skip). Dispatch consumes
this slot via take_pending_outcome() immediately after run
returns Ok so the per-publisher row in the summary table reads
pending-moderation / pending-validation instead of
succeeded. The slot is single-shot: any unread value is
cleared at the start of every run call.
Implementations§
Source§impl Context
impl Context
pub fn new(config: Config, options: ContextOptions) -> Self
Sourcepub fn record_publisher_outcome(&mut self, outcome: PublisherOutcome)
pub fn record_publisher_outcome(&mut self, outcome: PublisherOutcome)
Publisher-facing override: when Publisher::run returns Ok
but the terminal outcome is something other than Succeeded
(chocolatey moderation skip, winget/krew/homebrew
PR-already-exists skip, …) call this before returning so
dispatch records the correct PublisherOutcome on the report.
Without this, dispatch defaults to Succeeded on any Ok and
the summary table silently misreports the skip as success.
Sourcepub fn take_pending_outcome(&mut self) -> Option<PublisherOutcome>
pub fn take_pending_outcome(&mut self) -> Option<PublisherOutcome>
Dispatch-side consumer: take the pending outcome override (if
any) recorded by the publisher’s run. Single-shot — the slot
is empty after this call.
Sourcepub fn publish_report(&self) -> Option<&PublishReport>
pub fn publish_report(&self) -> Option<&PublishReport>
Borrow the publisher dispatch report set by PublishStage::run,
or None if the publish stage hasn’t run yet (or was skipped).
Sourcepub fn set_publish_report(&mut self, r: PublishReport)
pub fn set_publish_report(&mut self, r: PublishReport)
Store the publisher dispatch report. Overwrites any prior report; the publish stage is the single writer.
Sourcepub fn remember_skip(&self, stage: &str, label: &str, reason: &str)
pub fn remember_skip(&self, stage: &str, label: &str, reason: &str)
Record an intentional skip from a per-sub-config loop
(signs, docker_signs, publishers, …). stage identifies the
owning stage, label identifies the sub-config (id / name / index),
reason is short user-facing text. Duplicate (stage, label, reason)
tuples are dropped on insert so a per-artifact inner loop cannot emit
N copies of the same skip message.
pub fn template_vars(&self) -> &TemplateVars
pub fn template_vars_mut(&mut self) -> &mut TemplateVars
pub fn render_template(&self, template: &str) -> Result<String>
Sourcepub fn render_template_opt(
&self,
template: Option<&str>,
) -> Result<Option<String>>
pub fn render_template_opt( &self, template: Option<&str>, ) -> Result<Option<String>>
Render a template if present, returning None for None input.
Sourcepub fn skip_with_log(
&self,
skip: &Option<StringOrBool>,
log: &StageLogger,
label: &str,
) -> Result<bool>
pub fn skip_with_log( &self, skip: &Option<StringOrBool>, log: &StageLogger, label: &str, ) -> Result<bool>
Evaluate a skip field, logging at INFO level when it resolves to true.
Returns Ok(false) when skip is None or evaluates falsy. On
truthy, writes "{label} skipped" via log.status and returns
Ok(true). A malformed skip: template propagates as Err so the
caller fails fast — silently treating a render error as “not skipped”
(the prior behavior) shipped configs that the user thought would
suppress a stage but actually ran it.
pub fn should_skip(&self, stage_name: &str) -> bool
Sourcepub fn skip_validate(&self) -> bool
pub fn skip_validate(&self) -> bool
Check whether “validate” is in the skip list.
pub fn is_dry_run(&self) -> bool
pub fn is_snapshot(&self) -> bool
pub fn is_strict(&self) -> bool
Sourcepub fn strict_guard(&self, log: &StageLogger, msg: &str) -> Result<()>
pub fn strict_guard(&self, log: &StageLogger, msg: &str) -> Result<()>
In strict mode, return an error. In normal mode, log a warning and continue. Use this for any situation where a configured feature silently skips.
Sourcepub fn skip_in_snapshot(&self, log: &StageLogger, stage: &str) -> bool
pub fn skip_in_snapshot(&self, log: &StageLogger, stage: &str) -> bool
Defense-in-depth helper for upload-style stages.
Returns true (after logging the skip) when the context is in snapshot
mode. Stages that perform external uploads (registries, package indexes,
object storage, snap store, …) call this at entry so they no-op even
when invoked directly without the orchestration layer’s auto-skip.
Centralising the check keeps every publish stage consistent and avoids
per-stage copy-paste.
Sourcepub fn render_template_strict(
&self,
template: &str,
label: &str,
log: &StageLogger,
) -> Result<String>
pub fn render_template_strict( &self, template: &str, label: &str, log: &StageLogger, ) -> Result<String>
Render a template, failing in strict mode on error, or falling back to the raw string.
pub fn is_nightly(&self) -> bool
Sourcepub fn set_release_url(&mut self, url: &str)
pub fn set_release_url(&mut self, url: &str)
Set the ReleaseURL template variable.
Should be called after a GitHub release is created, with the URL of
the created release (e.g. https://github.com/owner/repo/releases/tag/v1.0.0).
Sourcepub fn version(&self) -> String
pub fn version(&self) -> String
Return the current Version template variable, or an empty string if
not yet populated.
Sourcepub fn retry_policy(&self) -> RetryPolicy
pub fn retry_policy(&self) -> RetryPolicy
Resolve the user’s retry: block into a concrete [RetryPolicy],
applying defaults when retry: is unset. Equivalent to
ctx.config.retry.unwrap_or_default().to_policy() but centralizes
the lookup so a future refactor can hang validation / clamping off
a single seam.
Sourcepub fn logger(&self, stage: &'static str) -> StageLogger
pub fn logger(&self, stage: &'static str) -> StageLogger
Create a StageLogger for the given stage name, pre-attached to
the context’s env-pairs list so that subprocess stderr / stdout
flowing through StageLogger::check_output is automatically
redacted. The env list combines the template-engine env
(process + config + .env files) and the current std::env::vars
snapshot, so any secret value reachable to a hook or subprocess is
available for scrubbing.
Sourcepub fn populate_git_vars(&mut self)
pub fn populate_git_vars(&mut self)
Populate template variables from self.git_info.
Must be called after self.git_info is set. Sets the following vars:
Tag,Version,RawVersion— tag and version stringsMajor,Minor,Patch— semver componentsPrerelease— prerelease suffix (or empty)BuildMetadata— build metadata from semver tag (or empty)FullCommit,Commit— full commit SHA (Commitis alias forFullCommit)ShortCommit— abbreviated commit SHABranch— current git branchCommitDate— ISO 8601 author date of HEAD commitCommitTimestamp— unix timestamp of HEAD commitIsGitDirty— “true”/“false”IsGitClean— “true”/“false” (inverse ofIsGitDirty)GitTreeState— “clean”/“dirty”GitURL— git remote URLSummary— git describe summaryTagSubject— annotated tag subject or commit subjectTagContents— full annotated tag message or commit messageTagBody— tag message body or commit message bodyIsSnapshot— from context optionsIsNightly— from context optionsIsDraft— “false” (stages may override to “true”)IsSingleTarget— “true”/“false” based on single_target optionPreviousTag— previous matching tag, stripped in monorepo mode (or empty)PrefixedTag— full tag with monorepo prefix, or tag_prefix-prepended (Pro addition)PrefixedPreviousTag— full previous tag with prefix (Pro addition)PrefixedSummary— full summary with prefix (Pro addition)IsRelease— “true” if not snapshot and not nightly (Pro addition)IsMerging— “true” if running with –merge flag (Pro addition)
Stage-scoped variables (NOT set here; set per-artifact during stage execution):
Binary— binary name, set by build stage per binary and archive stage per archiveArtifactName— output artifact filename, set by archive stage after creating each archiveArtifactPath— absolute path to artifact, set by archive stage after creating each archiveArtifactExt— artifact file extension (e.g..tar.gz,.exe), set alongside ArtifactNameArtifactID— build configidfield, set by build stage per build configOs— target OS, set by archive/nfpm stages per targetArch— target architecture, set by archive/nfpm stages per targetTarget— full target triple (e.g.x86_64-unknown-linux-gnu), set alongside Os/ArchChecksums— combined checksum file contents, set by checksum stage
Sourcepub fn populate_time_vars(&mut self)
pub fn populate_time_vars(&mut self)
Populate time-related template variables.
Sets:
Date— UTC time as RFC 3339Timestamp— unix timestamp as stringNow— UTC time as RFC 3339Year— four-digit year (e.g. “2026”)Month— zero-padded month (e.g. “03”)Day— zero-padded day (e.g. “30”)Hour— zero-padded hour (e.g. “14”)Minute— zero-padded minute (e.g. “05”)
Time source resolution (first match wins):
SOURCE_DATE_EPOCHenv var — the standard reproducibility contract (set by the determinism harness on every child release subprocess, and the conventional way external CI / packagers signal a fixed epoch). This is load-bearing for byte-stability ofmetadata.json(which embedsDate) and any user template that consumesDate/Timestamp/Now. Without this branch, two from-clean runs of the same commit emit metadata.json files that differ in thedatefield, defeating release-asset idempotency.chrono::Utc::now()— wall-clock fallback. Matches GoReleaser’s legacy semantics for runs without SDE wired in. Note that the GoReleaser template docs explicitly call.Now“not deterministic” — under SDE-aware reproducible builds we deviate from that behavior intentionally.
Sourcepub fn populate_runtime_vars(&mut self)
pub fn populate_runtime_vars(&mut self)
Populate runtime environment variables.
Sets:
RuntimeGoos— host OS in Go-compatible naming (e.g. “linux”, “darwin”, “windows”)RuntimeGoarch— host architecture in Go-compatible naming (e.g. “amd64”, “arm64”)Runtime_Goos/Runtime_Goarch— GoReleaser-compatible nested aliases
Sourcepub fn populate_release_notes_var(&mut self)
pub fn populate_release_notes_var(&mut self)
Populate the ReleaseNotes template variable from stored changelogs.
Should be called after the changelog stage has run and populated
self.stage_outputs.changelogs. Uses the first crate (by config
order) whose changelog is present, or an empty string if no
changelogs exist. Config order is deterministic, unlike HashMap
iteration order.
Sourcepub fn refresh_artifacts_var(&mut self)
pub fn refresh_artifacts_var(&mut self)
Refresh the Artifacts structured template variable from the current
artifact registry. Should be called before rendering release body and
announce templates so they can iterate over all artifacts.
Each artifact is serialized as a map with keys: name, path, target,
kind, crate_name, and metadata.
Known metadata keys (populated by individual stages):
format— archive format (e.g."tar.gz","zip"), set by archive stageextra_file—"true"when artifact is an extra file, set by checksum stageextra_name_template— name template override for extra files, set by checksum stagedigest— docker image digest (e.g.sha256:abc123...), set by docker stageid— artifact ID from config, set by docker and build stagesbinary— binary name, set by build stage
Sourcepub fn populate_metadata_var(&mut self) -> Result<()>
pub fn populate_metadata_var(&mut self) -> Result<()>
Populate the Metadata structured template variable from config.metadata.
Exposes the project metadata block as a nested map with PascalCase keys
matching GoReleaser’s .Metadata.* namespace:
Description, Homepage, License, Maintainers, ModTimestamp,
FullDescription (resolved), CommitAuthor.{Name,Email}.
Missing fields default to empty strings / empty arrays.
full_description with from_url is NOT resolved here (avoids a
reqwest dep in core); the FromUrl case returns an error and the caller
should surface it. Inline and FromFile are resolved synchronously.