Named tag support#8
Open
SmartyAdam wants to merge 2 commits into
Open
Conversation
RyanLCox1
approved these changes
Jun 25, 2026
|
Like it! |
cody-smarty
approved these changes
Jun 25, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Tagged Versions
Tags are named, manually-managed pointers to specific package versions. They let
a consumer depend on a stable name (for example
releaseorstable) instead ofa concrete version string, so that downstream pipelines do not have to know — or
be updated with — the exact version they should pull. Unlike
latest, a tag onlymoves when you explicitly move it, which makes it suitable for promoting a vetted
build to production on your own schedule.
Concepts
Each data package has a root manifest at
/{package}/manifest.jsonand oneversioned manifest per version at
/{package}/{version}/manifest.json. Theroot manifest is a copy of the most recently uploaded version's manifest and is
what
latestresolves to.Tags live only in the root manifest, in a
tagsarray. Each entry maps a tagname to a version:
{ "name": "cat-sound-data", "version": "2026.02.A", "archive": { "filename": "archive", "size": 2506300011, "md5": "34GMLE2LaQI1QHKoHJFRbQ==", "contents": [ { "path": "meows.txt", "size": 16087014133, "md5": "4ksM3tWryJom2O8XrU1l5A==" }, { "path": "purrs.txt", "size": 39014497, "md5": "E4LTd7kXWcP6kdAvTy9sHg==" } ], "compression": "zstd" }, "tags": [ { "name": "experimental", "version": "2026.01.B" }, { "name": "stable", "version": "2026.01.A" } ] }The versioned manifests are unchanged — they never carry a
tagsarray. Thetagsfield is omitted entirely from a manifest's JSON when there are no tags, sopackages that never use tags produce byte-for-byte the same manifests as before.
Manifests written to the local download directory also have their tags stripped,
since the tag list is a remote, root-level concern.
Reserved names and validation
latestis reserved and cannot be used as a tag name. The download keywordlatestalways takes precedence, so a tag of that name would be unreachable.name may not appear in both the add and delete lists.
Resolving a tag on download
A download dependency may put a tag name where it would normally put a version:
{ "dependencies": [ { "package_name": "cat-sound-data", "package_version": "stable", "remote_address": "gcs://cats-data-dev", "local_directory": "." } ] }Resolution is version-first:
package_versionas a literal version and looks for amanifest at
/{package}/{version}/manifest.json.the string up in the
tagsarray.This means a real version always shadows a tag of the same name, and an ordinary
pinned-version download behaves exactly as it did before tags existed — there is
no extra work on the common path. If the string matches neither a version nor a
tag, the download fails (and, importantly, fails before removing any
already-installed local files).
When a tag resolves to the version that is already installed locally, satisfy
runs its normal integrity check and skips the download, just as it does for a
matching pinned version. This is what makes a pipeline pinned to a tag cheap to
re-run: it does not re-download a multi-gigabyte archive every time simply
because the tag name differs from the installed version string.
Tagging during upload
An upload request may list tag names to apply to the version being uploaded:
{ "package_name": "cat-sound-data", "package_version": "2026.02.B", "compression_algorithm": "zstd", "compression_level": 9, "remote_address": "gcs://cats-data-dev", "tags": ["ultra-experimental", "experimental"], "source_path": "" }The versioned manifest is written as usual. For the root manifest, satisfy:
version just uploaded — adding the name if it is new, updating it if it
already existed.
So uploading
2026.02.Bwith"tags": ["experimental"]movesexperimentalto2026.02.Bwhile leaving an unrelatedstabletag exactly where it was. Anupload with no
tagsfield leaves all existing tags untouched. The resulting taglist is sorted by name for stable, reviewable diffs.
Modifying tags without uploading
The
tagssubcommand changes tags on an already-uploaded package withoutre-uploading any data. It reads a JSON request from a file (
-json <path>) orfrom standard input (the default,
-json _STDIN_):Request format:
{ "package_name": "cat-sound-data", "remote_address": "gcs://cats-data-dev", "add": [ { "name": "stable", "version": "2026.02.A" }, { "name": "marks-favorite", "version": "2026.01.B" } ], "delete": [ { "name": "active-build-test" }, { "name": "adam-test" } ] }Behavior:
version if it does.
nameis consulted; anyversionis ignored. Deleting a tag that does not exist is a no-op, not an error.
addactually exists on remote storage (again via a
HEADprobe of the version'smanifest). If any target version is missing, the whole request fails and
nothing is written — there is no partial update. This prevents creating a
tag that points at a version which cannot be downloaded.
On success, the updated root manifest is uploaded back to
/{package}/manifest.jsonwith its tag list sorted by name.Flags
-json_STDIN__STDIN_to read stdin.-max-retry5Exit code
0indicates success; exit code1indicates a failure (see stderr).Summary of behavior
tagstags: [...]tagsadd (new name)tagsadd (existing name)tagsdelete (existing name)tagsdelete (missing name)tagsarray.