feat(skills): add update-compositions skill and registry query reference
This commit is contained in:
2 files changed
+272
No files matched your search
@@ -0,0 +1,99 @@
|
||||
# Container Registry Tag Queries
|
||||
|
||||
This reference details how to discover available image tags across common container registries without requiring external tooling.
|
||||
|
||||
## 1. Docker Hub (`hub.docker.com`)
|
||||
|
||||
Docker Hub provides an unauthenticated v2 API for public repositories.
|
||||
|
||||
### Official Images (Library)
|
||||
For top-level images like `postgres`, `redis`, `traefik`, `mariadb`:
|
||||
|
||||
```bash
|
||||
IMAGE="postgres"
|
||||
curl -s "https://registry.hub.docker.com/v2/repositories/library/${IMAGE}/tags?page_size=100" \
|
||||
| python3 -c '
|
||||
import sys, json
|
||||
data = json.load(sys.stdin)
|
||||
tags = [t["name"] for t in data.get("results", [])]
|
||||
print("\n".join(tags[:30]))
|
||||
'
|
||||
```
|
||||
|
||||
### Community / User Images
|
||||
For namespace images like `adguard/adguardhome`, `prom/prometheus`, `grafana/alloy`:
|
||||
|
||||
```bash
|
||||
ORG="adguard"
|
||||
IMAGE="adguardhome"
|
||||
curl -s "https://registry.hub.docker.com/v2/repositories/${ORG}/${IMAGE}/tags?page_size=100" \
|
||||
| python3 -c '
|
||||
import sys, json
|
||||
data = json.load(sys.stdin)
|
||||
tags = [t["name"] for t in data.get("results", [])]
|
||||
print("\n".join(tags[:30]))
|
||||
'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. GitHub Container Registry (`ghcr.io`)
|
||||
|
||||
GHCR implements OCI distribution spec. Public image tags can be queried with an anonymous bearer token.
|
||||
|
||||
```bash
|
||||
IMAGE="xtls/xray-core"
|
||||
TOKEN=$(curl -s "https://ghcr.io/token?scope=repository:${IMAGE}:pull" | python3 -c 'import sys, json; print(json.load(sys.stdin)["token"])')
|
||||
curl -s -H "Authorization: Bearer ${TOKEN}" "https://ghcr.io/v2/${IMAGE}/tags/list" \
|
||||
| python3 -c '
|
||||
import sys, json
|
||||
data = json.load(sys.stdin)
|
||||
tags = data.get("tags", [])
|
||||
print("\n".join(sorted(tags, reverse=True)[:30]))
|
||||
'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Quay.io (`quay.io`)
|
||||
|
||||
Quay provides a REST API:
|
||||
|
||||
```bash
|
||||
REPO="repository_name"
|
||||
curl -s "https://quay.io/api/v1/repository/${REPO}/tag/?limit=50&onlyActiveTags=true" \
|
||||
| python3 -c '
|
||||
import sys, json
|
||||
data = json.load(sys.stdin)
|
||||
tags = [t["name"] for t in data.get("tags", [])]
|
||||
print("\n".join(tags[:30]))
|
||||
'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. SemVer Matching & Sorting
|
||||
|
||||
When filtering tags to find the latest stable version matching the current container's flavor:
|
||||
|
||||
```python
|
||||
import re
|
||||
|
||||
def parse_semver(tag: str):
|
||||
# Match patterns like v1.2.3, 1.2.3-alpine, 16.4
|
||||
m = re.match(r"^v?(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:-(.+))?$", tag)
|
||||
if not m:
|
||||
return None
|
||||
major = int(m.group(1))
|
||||
minor = int(m.group(2) or 0)
|
||||
patch = int(m.group(3) or 0)
|
||||
flavor = m.group(4) or ""
|
||||
return (major, minor, patch, flavor)
|
||||
```
|
||||
|
||||
Rules for candidate selection:
|
||||
1. Preserve flavor: If currently running `16-alpine`, match only tags with suffix `-alpine`.
|
||||
2. Ignore pre-releases: Filter out tags containing `alpha`, `beta`, `rc`, `dev`, `test`, or git SHAs.
|
||||
3. Classify:
|
||||
- Same `major`, higher `minor` or `patch` -> **Minor / Patch**.
|
||||
- Higher `major` -> **Major** (requires Step 5 approval).
|
||||
Reference in new issue
Block a user