envoyproxy / envoyproxy/bazel-registry
Release pipeline: module lifecycle, immutability and versioning rules
- Dominant language
- Starlark
- Stars
- 0
- Forks
- 8
- Avg merge
- 3h 22m
- Merged PRs (30d)
- 52
Description
Consolidates the rules that fell out of the pre-`v0.0.1` cleanup (prunes, the `tcmalloc` latent patch break, the `envoy`/`envoy_api` SHA mismatch, the `api/MODULE.bazel` toolshed straggler). #7 §4 sketches immutability; #11 covers CI selection. This issue is the policy + enforcement for how module versions are created, changed and retired, so the pipeline is mechanical rather than a manual sequence.
## Rules
### 1. One published version per module per release
A release tag of this registry contains exactly one version directory per module. Exceptions may be added later (e.g. an active release-branch pin, see #11 *Future*), but must be explicit in `metadata.json` — not implicit via leftover directories.
### 2. Published versions are immutable
Once a version is included in a release tag, its directory (`MODULE.bazel`, `source.json`, `patches/**`, `overlay/**`, `presubmit.yml`) cannot be modified or deleted. The only permitted change is adding the version to `yanked_versions` in `metadata.json`.
Corollary: fixing a bug in a *published* version means cutting a new version, never editing in place.
### 3. Unpublished versions are mutable — edit in place
If a version has not yet been released, changes that are not upstream changes (patch fixes, `MODULE.bazel` dep bumps, overlay fixes) MUST be made in that version's directory, not by cutting a sibling. Cutting a new version for a registry-side fix creates churn and leaves the broken one to prune.
Example: the `tcmalloc/0.0.0-250926-12f2552.envoy` patch fix was correctly done in place.
### 4. Cutting a new version removes the old one
When a new version of a module is added (upstream bump or snapshot re-cut), the PR MUST delete every other unpublished version of that module and trim `metadata.json` `versions` accordingly. A module never has more than one unpublished version at a time.
`git mv` when the change is a straight re-cut (preserves history); `rm` + new dir otherwise.
### 5. Sibling modules are published together
Modules cut from one upstream repo/SHA (`envoy` + `envoy_api`; `envoy-examples` + `envoy-example-filter-cc` + `envoy-example-wasm-cc`) are:
- published in one commit
- given identical version strings
- given identical `source.json` `url` + `integrity` (differing only in `strip_prefix`)
- pinned to each other by exact version in their published `MODULE.bazel`
### 6. Version string grammar
Everything in this registry ends in `.envoy`.
| Kind | Form | Example |
|---|---|---|
| Upstream release, patched | `.envoy` | `2.1.1.envoy` |
| Upstream release, BCR-derived | `.bcr[.N].envoy` | `35.1.bcr.envoy` |
| Upstream commit snapshot | `--.envoy` | `0.0.0-260704-f2db56a.envoy` |
| Envoy-owned snapshot | `...envoy` | `1.40.0.20260904.13144fb.envoy` |
- No `-dev` in any published version. In-repo dev pins (`1.40.0-dev`) are stripped by the publisher; `-dev` sorts *below* the release under Bazel version ordering so must never be published.
- `module(version = ...)` in `MODULE.bazel` must equal the directory name.
- `metadata.json` `versions` is append-only insertion order (relied on by `registry_select.py`).
### 7. Downstream repos never pin snapshots of themselves
In publishing repos (envoy, examples, docs, mobile), in-repo `MODULE.bazel` pins siblings to the bare dev version and wires them with `local_path_override`. Only the publisher rewrites to a snapshot string. Consumers of the published module override via `bazel_dep`.
## Enforcement
### Registry lint (`.github/workflows/registry_lint.py`, runs on every PR)
- [ ] every version dir name matches `module(version=)` and ends `.envoy`
- [ ] no `-dev` in any version dir name
- [ ] `metadata.json` `versions` parses, is append-only vs `origin/main`, every entry has a dir, every dir has an entry
- [ ] sibling sets have identical version + `url` + `integrity`
- [ ] published `envoy`/`envoy-examples` snapshots pin siblings to exactly their own version
- [ ] every `bazel_dep(... "*.envoy")` in any `MODULE.bazel` resolves to a dir in this registry
- [ ] a module has at most one unpublished version
- [ ] for versions in any release tag: no diff under the version dir; only `yanked_versions` may change
### Publisher
- [ ] takes `(repo, sha)`; emits all sibling module dirs from one tarball download
- [ ] strips `-dev`, applies `.` from the commit
- [ ] rewrites sibling `bazel_dep`s, drops `local_path_override`s
- [ ] deletes prior unpublished versions of the same modules and trims `metadata.json`
- [ ] fails if any resulting `bazel_dep(... .envoy)` does not exist in the registry
### Downstream lint (`.bcr/`-style, in each publishing repo)
- [ ] no in-repo `MODULE.bazel` pins a sibling to anything other than `-dev`
- [ ] no `.envoy` snapshot string for self-or-siblings anywhere in `MODULE.bazel`
- [ ] `local_path_override` present for every sibling `bazel_dep`
## Open questions
- Release-branch exceptions to rule 1: sibling key in `metadata.json` vs derived from what Envoy release branches pin (#11).
- Whether "published" is defined by GitHub release tags (as #7 proposes) or by a `releases.json` in-repo — the former is authoritative but needs API access in lint; the latter is self-contained.
- Should `yanked_versions` entries be allowed to be *removed* (un-yank)? Proposal: no.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with .github/workflows/registry_lint.py and compare its checks against origin/main; then inspect the publisher entry point and the .bcr-style downstream lint in each publishing repository. Done means the stated lifecycle, versioning, sibling, registry, publisher, and downstream rules are enforced, with the release-definition open questions resolved.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- git, github
- Domain
- build-system, ci-cd, release, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100