Hitchhiker's Guide — Release Engineering
(0) 30-Second Mental Model
JIRA: fixVersion set RC1 cut [VOTE] thread Distribution
────────────────────── ────────────────── ────────────────────── ──────────────
Committers merge Tag in git PMC members cast: Mirrored to
patches with Sign artifacts +1 (binding) apache.org
fixVersion=3.5.0 Upload to +1 (non-binding) mirrors network
dist/dev/ 0 (abstain)
Generate: -1 (binding VETO!) 72-hour minimum
.tar.gz vote window
.tar.gz.asc Result:
.tar.gz.sha512 ≥ 3 binding +1 AND
LICENSE no binding -1 → PASS
NOTICE
(1) RC Checklist Anatomy
Every Apache source release must pass this checklist before the vote passes. PMC members vote +1 only after personally verifying these items.
| Check | Why it matters |
|---|---|
✅ GPG signature present (.asc) | Proves release was built and signed by a known committer |
✅ SHA-512 checksum present (.sha512) | Lets downloaders verify integrity after transfer |
✅ LICENSE file in archive | Required by ASL 2.0 §4 — must cover bundled dependencies |
✅ NOTICE file in archive | Required by ASL 2.0 §4 — attribution for upstream works |
| ✅ No binary artifacts in source release | Source releases must be reproducibly buildable from source |
✅ DISCLAIMER or DISCLAIMER-WIP if incubating | Incubator projects carry an extra file |
| ✅ All dependencies are Category A | Category X (GPL, LGPL) licenses cannot be bundled |
Verifying GPG locally:
gpg --verify apache-spark-3.5.0.tgz.asc apache-spark-3.5.0.tgz
# GOOD signature from "Release Manager <rm@apache.org>"
Verifying SHA-512:
sha512sum -c apache-spark-3.5.0.tgz.sha512
# apache-spark-3.5.0.tgz: OK
(2) GPG Trust Chain
Apache Root CA
└── Committer GPG key (published at https://people.apache.org/keys/)
└── Detached signature (.asc) for each release artifact
Key points:
- Committer keys are published at
https://people.apache.org/keys/committer/<username>.asc - The project
KEYSfile indist/aggregates all signing keys for that project - Votes that say "+1 but I didn't verify the signature" are non-binding for practical purposes
(3) japicmp — Reading API Compatibility Output
japicmp compares two JARs and reports compatibility issues:
@@@ MODIFIED CLASS: org.apache.spark.sql.Dataset
=== REMOVED METHOD: public Dataset filter(String)
Binary incompatible!
=== MODIFIED METHOD: public Dataset select(Column[])
Return type changed: Dataset -> RelationalGroupedDataset
Binary incompatible!
+++ NEW METHOD: public Dataset filter(Column)
Binary compatible.
Classification rules:
| Change | Binary-breaking? | Source-breaking? |
|---|---|---|
| Method removed | YES | YES |
| Method return type changed | YES | YES |
| Method parameter types changed | YES | YES |
| New method added to class | NO | NO |
| New method added to interface | NO (default) / YES (abstract) | YES |
| Field type changed | YES | YES |
| Field removed | YES | YES |
SemVer implication: Any binary-breaking change requires a MAJOR version bump.
(4) Vote Thread Grammar
Apache votes follow a strict format. The release manager sends a [VOTE]
email; community members reply.
Subject: [VOTE] Release Apache Spark 3.5.0 RC1
+1 (binding) Alice PMC Chair — verified GPG, built from source, ran TCK
+1 (binding) Bob PMC member — signature OK, license headers checked
+1 (binding) Carol Committer — smoke tested on cluster
+1 Dave contributor — built OK on ARM
0 (binding) Eve — abstaining, on vacation
-1 (binding) Frank — SHA-512 mismatch on the .tar.gz artifact
Quorum rules (Apache Release Policy §6.3):
- ≥ 3 binding +1 votes required
- No binding -1 votes (any binding -1 is a veto; release cannot proceed)
- Minimum 72-hour open window to allow all time zones to participate
- Non-binding votes count for morale but not quorum
After a -1 veto:
- Fix the issue (e.g., regenerate artifact if checksum mismatch)
- Cut RC2
- Start a new vote thread with
[VOTE] Release Apache Spark 3.5.0 RC2
(5) Lazy Consensus vs Full Vote
| Mechanism | Used for | Rule |
|---|---|---|
| Lazy consensus | Minor patches, docs, non-binding changes | Anyone can +1 silently; a -1 from any committer blocks |
| Full vote | Releases, new committers, PMC additions | Explicit +1s required; quorum applies |
| Majority vote | Policy changes | Simple majority of binding voters |
Most day-to-day Apache work runs on lazy consensus — if nobody objects in 72 hours, the change is approved.
(6) Interview Q&As
| Question | Strong answer |
|---|---|
| What makes an Apache release different from a CI deployment? | It's a legal artifact: signed, checksummed, voted on, permanently archived, and carries the Apache brand and license obligations |
| What is a binding veto in an Apache vote? | A -1 from a PMC member; it unconditionally blocks the release; the release manager must fix the issue and re-spin as a new RC |
| What files must be in every Apache source release? | LICENSE, NOTICE, and the source code; no pre-compiled binaries |
| When is a change binary-breaking? | When it prevents existing compiled code from linking or running: removed method, changed parameter types, changed return type, removed class |
| What is the difference between a Category A and Category X dependency? | Category A (MIT, BSD, ASL 2.0) can be bundled; Category X (GPL, LGPL) cannot be included in ASF distributions |
| How do you verify a release before voting? | Download artifact + .asc + .sha512; verify GPG signature with gpg --verify; verify checksum; build from source; run tests |