IMPORTANT: Developer documentation for the current development branch. This content is unreleased, may change without notice, and must not be treated as Buildish release documentation.

Candidate Release And Promotion

Publish retained candidates and promote one exact candidate manifest to a final release.

Candidate Release And Promotion

The candidate lifecycle publishes one or more immutable candidates and promotes one explicitly selected candidate to the final release. Voting or approval is external: Buildish records exact candidate evidence but does not decide whether a candidate passed.

This separation lets a manual decision, a GitHub Issue bot, a foundation-specific voting process, or another approval system gate final publication without changing candidate identity or promotion semantics.

Minimal configuration

 1component:
 2  id: example
 3  display_name: Example
 4versioning:
 5  scheme: semver
 6  final_tag_template: "v{version}"
 7source:
 8  selection: explicit-ref-or-default-branch
 9  default_branch: main
10  snapshot:
11    mode: platform-generated
12  checks:
13    platform: github
14    required:
15      - Required Checks
16lifecycle:
17  mode: candidate
18candidate:
19  label: rc
20  start_number: 1
21  visibility: public-prerelease
22  retention: retain-published
23artifacts:
24  produced: []
25  checksums: []
26publication:
27  authoritative:
28    kind: github-release
29    repository: example/example
30tags:
31  final_mode: exact-source-commit
32  moving: []
33policy_profiles: {}

The default candidate number is one. With this configuration, version 1.2.3 starts at v1.2.3-rc1.

Create candidates

Run .github/workflows/release-candidate.yml with the exact version and optional source ref or candidate-label override. The workflow:

  1. resolves the next unused candidate number and exact source commit;
  2. verifies configured source checks on that commit;
  3. creates the immutable candidate tag;
  4. stages the GitHub candidate and any configured artifacts;
  5. creates and attaches candidate-manifest.json;
  6. verifies the tag, release metadata, asset inventory, manifest bytes, size, and SHA-256;
  7. applies configured visibility.

public-prerelease produces a public GitHub prerelease. draft retains a non-public draft. A later run for the same version and label selects the next number after the highest existing matching tag; published candidates are retained.

For example, a rejected or superseded v1.2.3-rc1 can remain available while a new run publishes v1.2.3-rc2 from another exact commit.

Zero-based numbering

Projects that prefer RC0 can choose it explicitly:

1candidate:
2  label: rc
3  start_number: 0
4  visibility: draft
5  retention: retain-published

That configuration begins at v1.2.3-rc0. Numbering is project policy; it has no effect on the unsuffixed final version or final tag.

Independent verification

Run .github/workflows/release-verify-candidate.yml with:

  • the exact candidate tag;
  • the lowercase SHA-256 of candidate-manifest.json.

The read-only workflow downloads the durable manifest from the candidate GitHub Release and checks the supplied digest, candidate identity, source commit, release metadata, and asset identities. It also retains the verified manifest and result as a workflow artifact for inspection.

Exact promotion

After the external gate accepts a candidate, run .github/workflows/release-promote.yml with:

  • version, such as 1.2.3;
  • candidate_tag, such as v1.2.3-rc2;
  • candidate_manifest_digest, the exact lowercase SHA-256 selected by the gate.

Promotion never discovers “the latest RC”. It downloads and verifies the named candidate manifest, downloads each candidate asset named by that manifest, verifies the bytes, and creates PromotionState. The remaining jobs create the final tag, stage and verify the final release, publish it, and attach release-manifest-v1.json.

The final manifest records the promoted candidate and its manifest digest. Per-artifact promotion evidence distinguishes byte-identical assets, immutable registry identities, and hosting-platform snapshots generated from tags at the same exact source revision.

Optional vote package

Voting is not a precondition of candidate publication. A component that wants reusable voting materials can add a generic profile:

1vote_materials:
2  profile: generic
3  release_name: Example
4  verification_guide_url: https://example.org/releases/verify/
5  instructions: Verify the candidate manifest and all referenced artifacts.

Dispatch the candidate workflow with vote_profile: generic, or call create-vote-package over the exact candidate manifest. VotePackageV1 binds the rendered opening/result templates to that manifest’s digest. Vote duration, voter eligibility, quorum, veto rules, and outcome remain the responsibility of the external authority.

The optional ASF profile provides ASF-specific terminology and trust-root data without changing the generic candidate or promotion contracts.