- integrations
- Python
- Authoring packages: announce
Authoring packages: announce
Part 2 of 2 of Authoring packages.
announce — publish the listing to the index
Section titled “announce — publish the listing to the index”announce writes
the package’s tag listing into the ocx index on a forge (GitHub or GitLab)
and returns an
AnnounceReport — status
is "updated" or "unchanged", pull_request_url is set when the forge
path went through a PR, capability_checks records what the credential
was allowed to do. Exactly one tag source is required — tags=,
tags_file= (the file cascade_repair(announce_tags=...) writes) or
tags_from_registry=True — and ocx, not the SDK, enforces that: none or
two is a UsageError (64).
# illustrative: needs a forge credential and network access.from ocx_sdk import Ocx, OcxConfig
ocx = Ocx(config=OcxConfig(forge_token="glpat-..."))report = ocx.package.announce("me/my-tool", tags=["1.0.0", "latest"])print(report.status, report.pull_request_url)A registry write like push, so retry defaults to None. The credential
comes from OcxConfig.forge_token
(OCX_ANNOUNCE_TOKEN) or the ambient identity ladder described in
Hermetic CI. --yank,
--unyank, --fork and --out are not typed: reach them through
invoke.
claim — register a package with the index
Section titled “claim — register a package with the index”claim registers a
package name and its owners in the index, returning a
ClaimReport. repository is
the OCI repository the claim points at; owners= lists forge logins beyond
the caller.
A claim is not idempotent on the wire: claiming an already-claimed package
exits 65 with no report, which the SDK surfaces as a plain
DataError. The idempotent-CI
shape is to catch it and read detail off the
error envelope —
"package_already_claimed", a frozen slug, never the message text:
# illustrative: needs a forge credential and network access.from ocx_sdk import DataError, Ocx, error_envelope
try: Ocx().package.claim("me/my-tool", repository="oci://ghcr.io/me/my-tool")except DataError as exc: envelope = error_envelope(exc) if envelope is None or envelope.detail != "package_already_claimed": raiseocx’s command reference tables the rest of claim’s slugs
(malformed_repository, owner_unknown, bot_identity, …), each pinned to
its exit code.
cascade_check / cascade_repair — audit the rolling tags
Section titled “cascade_check / cascade_repair — audit the rolling tags”push(cascade=True) advances the rolling tags (1, 1.0, latest) above
the version it publishes; a push without it leaves them behind.
cascade_check
audits one or more repositories and
cascade_repair
rewrites what is stale. Both are report-then-fail: ocx exits 65 with
the report whenever it found something, and the SDK hands that report back
as a result rather than raising — the finding is the answer. clean is the
one-word verdict; exit_code keeps what ocx said.
from ocx_sdk import CascadeCheckReport
report = CascadeCheckReport.from_json( '{"reports": [{"identifier": "ghcr.io/me/my-tool", "logical": null, "aliases": {}, ' '"rows": [{"tag": "latest", "platform": {}, "status": "stale", "observed": null, "expected": null, ' '"source": "1.0.1", "observed_source": "1.0.0"}], ' '"index_findings": [], "ignored_tags": [], "unrepairable": []}]}', exit_code=65,)assert not report.cleanassert [(row.tag, row.status) for row in report.reports[0].rows] == [("latest", "stale")]cascade_repair(dry_run=True, announce_tags=path) plans without writing and
leaves the tags it would touch in path — the file announce(tags_file=path)
consumes. Only a 65 without a report (an error envelope instead) raises.
Consuming what you just published
Section titled “Consuming what you just published”The loop closes through the ordinary consumer surface —
package.install or
a project’s add — pointed at
the identifier push returned. See
Vendoring a dist.json for shipping a bootstrap manifest
snapshot inside a package, which is a separate concern from publishing the
package itself.