Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 38 additions & 2 deletions docs/adr/0708-operator-distribution-hubs.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
> How Kollect becomes discoverable on Artifact Hub and OperatorHub without replacing Helm OCI
> as the primary install path, and without in-repo FBC/`opm` catalog machinery.

**Theme:** 07 · Project & meta · **Status:** Exploring (Proposed — maintainer LGTM required)
**Theme:** 07 · Project & meta · **Status:** Current (accepted 2026-08-08 — see the 2026-08-18 notes below)

<!-- AgDR: architect role · 2026-08-06 · trigger: hub distribution parity plan (Attune pattern) -->

Expand Down Expand Up @@ -76,7 +76,8 @@ Contract:
no release, and each reports through `steps.<id>.outcome` (`continue-on-error` pins
`.conclusion` to `success`) with a `::warning::` annotation and a `$GITHUB_STEP_SUMMARY`
line.
7. **Skipped:** Krew, Docker Hub chart mirror, in-repo FBC/`opm`, CLOMonitor.
7. **Skipped:** Krew, Docker Hub chart mirror, in-repo FBC/`opm` (posture re-confirmed
2026-08-18 against the upstream recommendation — see *Alternatives considered*), CLOMonitor.

## Consequences

Expand All @@ -86,8 +87,43 @@ Contract:
scopes, connection tests, cluster variants) — large owned list; keep generate step mechanical.
- Docs must not ship live Artifact Hub / OperatorHub badge URLs that 404 before listing.
- Soft-fail hub jobs preserve tag-release success when PAT/forks are absent.
- **Shipped 2026-08-18.** The contract above is live, which is what moves this ADR to *Current*:
[#309](https://github.com/platformrelay/kollect/pull/309) merged (`e71faaffd`); Artifact Hub
repository `kollect` registered with the real `repositoryID` and **Verified Publisher active**;
both community-operators submissions open and green. The operator accepted option A on
2026-08-08, so the placeholder-`repositoryID` and pre-registration caveats above are history,
not open work.

## Alternatives considered

See table. FBC rejected as disproportionate for solo maintenance. Artifact-Hub-only rejected
because OpenShift catalog adopters are in scope for this track.

### FBC posture — re-confirmed 2026-08-18

The upstream community-operators hosted pipeline on our open submissions
([community-operators#9070](https://github.com/k8s-operatorhub/community-operators/pull/9070),
[community-operators-prod#10889](https://github.com/redhat-openshift-ecosystem/community-operators-prod/pull/10889))
emits `check_using_fbc` as a **Warning**: *"File Based Catalog (FBC) is a new way to manage
operator metadata. This operator does not use FBC and it is recommended for new operators to
start directly with FBC."* Both submissions are green — the check recommends, it does not block.

We read the recommendation and kept **registry+v1 hand-templated bundles**; option C stays
rejected on its recorded grounds, not on new ones. In-repo FBC/`opm` is the only option that
loses on *operability / lean tooling* (2 against A's 4 and B's 5) and lands at the same weighted
total as doing nothing (35). The cost that decided it is ongoing, not one-off: an `opm`-rendered
catalog is a second generated artifact to keep, pin, and re-render every release, on top of the
CSV that `hack/test/dist_olm_bundle_test.sh` already gates for drift — disproportionate for a
solo-maintained project whose release engineering is deliberately lean
([ADR-0705](0705-release-supply-chain.md)).

This is a posture, not a permanent refusal. **Revisit when any of these becomes true:**

- upstream deprecates registry+v1 — `check_using_fbc` turns from a Warning into an error, or
either catalog stops accepting non-FBC submissions;
- the bundle outgrows hand-templating — multiple channels, `skips`/`replaces` upgrade graphs, or
per-OCP-version catalog pinning, none of which the single `stable` channel needs today;
- maintenance stops being solo, so the operability weighting that decided the table no longer
dominates.

Adopting FBC reverses a recorded decision: it needs a superseding ADR, not an edit here.
2 changes: 1 addition & 1 deletion docs/adr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ Then drill into [0414 — Sink family CRDs](0414-sink-family-crds.md) when wirin
| [0705](0705-release-supply-chain.md) | Release engineering and supply chain | Current |
| [0706](0706-testing-merge-gate-architecture.md) | Testing and merge-gate architecture | Current |
| [0707](0707-lab-harness.md) | Lab harness (multi-node / existing-cluster evidence) | Current |
| [0708](0708-operator-distribution-hubs.md) | Operator distribution via Artifact Hub and OperatorHub | Exploring (Proposed) |
| [0708](0708-operator-distribution-hubs.md) | Operator distribution via Artifact Hub and OperatorHub | Current |

## 08 · Pipeline & CLI

Expand Down
2 changes: 1 addition & 1 deletion docs/getting-started/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ for a constrained development environment. The chart does not generate certifica
## Discoverability on package hubs

Helm OCI on GHCR remains the primary install path ([ADR-0705](../adr/0705-release-supply-chain.md)).
Additional distribution wiring is landing under [ADR-0708](../adr/0708-operator-distribution-hubs.md):
Additional distribution wiring ships under [ADR-0708](../adr/0708-operator-distribution-hubs.md):

- **Artifact Hub** — the chart repository is registered and listed as
[`kollect`](https://artifacthub.io/packages/search?repo=kollect); it indexes the same OCI chart
Expand Down
32 changes: 26 additions & 6 deletions hack/test/dist_adr_0708_indexed_test.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env bash
# DIST-ADR-01: ADR-0708 hub distribution must exist and be indexed under theme 07.
# DIST-OH-03: its status is resolved -- ADR header and index row must both read Current.
set -euo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
Expand All @@ -20,10 +21,20 @@ pass() {
grep -Eq '^# ADR-0708:.*[Oo]perator distribution' "${ADR}" ||
fail "ADR missing title/heading for ADR-0708"

grep -Eqi 'Status:[[:space:]]*\*?Exploring\*?|\*\*Status:\*\*.*Exploring' "${ADR}" ||
fail "ADR-0708 must document Status Exploring (Proposed)"
# The status lives on the header line, next to the theme. Match THAT line, not any
# occurrence of the word in the body -- a file-wide grep would pass on prose.
adr_status="$(grep -E '^\*\*Theme:\*\*.*\*\*Status:\*\*' "${ADR}" | head -1 |
sed -E 's/^.*\*\*Status:\*\*[[:space:]]*//; s/[[:space:]]*$//')"
[[ -n "${adr_status}" ]] || fail "ADR-0708 header line carries no **Status:**"

pass "ADR-0708 file and Exploring status present"
# ADR-0708 was accepted by the operator on 2026-08-08 and shipped on 2026-08-18; the
# repo's status vocabulary spells an accepted decision **Current**
# (docs/development/adr-rfc-process.md). Anything still saying Exploring/Proposed means
# the header was never resolved.
[[ "${adr_status}" == Current* ]] ||
fail "ADR-0708 header must document Status Current, found '${adr_status}'"

pass "ADR-0708 file and Current status present"

[[ -f "${INDEX}" ]] || fail "${INDEX} is missing"

Expand All @@ -39,9 +50,18 @@ theme07="$(
printf '%s\n' "${theme07}" | grep -Eq '\[0708\]\(0708-operator-distribution-hubs\.md\)' ||
fail "docs/adr/README.md theme 07 must index [0708](0708-operator-distribution-hubs.md)"

printf '%s\n' "${theme07}" | grep -E '\[0708\]\(0708-operator-distribution-hubs\.md\)' | grep -Eiq 'Exploring|Proposed' ||
fail "docs/adr/README.md 0708 row must list Exploring/Proposed status"
# The index row must agree with the ADR header, so the two can never drift apart.
index_status="$(printf '%s\n' "${theme07}" |
grep -E '\[0708\]\(0708-operator-distribution-hubs\.md\)' | head -1 |
awk -F'|' '{gsub(/^[[:space:]]+|[[:space:]]+$/, "", $4); print $4}')"
[[ -n "${index_status}" ]] || fail "docs/adr/README.md 0708 row carries no status cell"

# The header may carry a parenthetical ("Current (accepted ...)"); the table cell is bare,
# so compare only the leading word. This is the ONLY status assertion on the index row --
# pinning it to a literal as well would make this comparison unfalsifiable.
[[ "${index_status}" == "${adr_status%% *}" ]] ||
fail "docs/adr/README.md 0708 row status '${index_status}' disagrees with the ADR header '${adr_status}'"

pass "README indexes 0708 under theme 07 as Exploring/Proposed"
pass "README indexes 0708 under theme 07 as Current, in sync with the ADR header"

echo "All dist ADR-0708 index tests passed."
Loading