Skip to content

Commit ca3295d

Browse files
committed
chore(docker): enforce OCI description label
1 parent 33fa6db commit ca3295d

5 files changed

Lines changed: 53 additions & 0 deletions

File tree

.github/workflows/docker-publish.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,16 @@ jobs:
6060
# when called via workflow_call, defaults to the commit that triggered the workflow
6161
ref: ${{ inputs.ref }}
6262

63+
# NOTE: We parse the description label from the Dockerfile so the
64+
# multi-arch manifest annotation stays in sync and GHCR shows a description.
65+
# If you change the label format or quoting, update the extraction logic.
66+
- name: Extract OCI description
67+
id: oci-description
68+
run: |
69+
set -euo pipefail
70+
description="$(python3 scripts/extract-oci-description.py packages/core/src/docker/Dockerfile)"
71+
echo "description=${description}" >> "$GITHUB_OUTPUT"
72+
6373
- name: Extract version
6474
id: version
6575
run: |
@@ -196,6 +206,8 @@ jobs:
196206
OPENCODE_CLOUD_VERSION=${{ steps.version.outputs.version }}
197207
tags: ${{ steps.meta.outputs.tags }}
198208
labels: ${{ steps.meta.outputs.labels }}
209+
annotations: |
210+
org.opencontainers.image.description=${{ steps.oci-description.outputs.description }}
199211
# Scoped cache prevents thrash between test and publish builds.
200212
# GHA cache v2 improves compatibility with the current cache API.
201213
cache-from: |

.github/workflows/dockerfile-updates.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ jobs:
7575
FOOTER
7676
echo "updates_body_path=${updates_body_path}" >> $GITHUB_OUTPUT
7777
78+
- name: Verify OCI description label
79+
run: python3 scripts/extract-oci-description.py packages/core/src/docker/Dockerfile
80+
7881
- name: Set up Docker Buildx
7982
if: steps.check.outputs.updates_available == 'true'
8083
uses: docker/setup-buildx-action@v3

.github/workflows/update-opencode-commit.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ jobs:
2727
run: |
2828
./scripts/update-opencode-commit.sh
2929
30+
- name: Verify OCI description label
31+
run: python3 scripts/extract-oci-description.py packages/core/src/docker/Dockerfile
32+
3033
- name: Commit and push if changed
3134
run: |
3235
if git diff --quiet; then

packages/core/src/docker/Dockerfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ FROM ubuntu:24.04 AS base
3636

3737
# OCI Labels for image metadata
3838
LABEL org.opencontainers.image.title="opencode-cloud"
39+
# NOTE: This exact label format is parsed by scripts/extract-oci-description.py
40+
# (called from .github/workflows/docker-publish.yml) to populate multi-arch
41+
# manifest annotations for GHCR. If you change this line (format, quoting, or
42+
# key), update the extraction logic too.
3943
LABEL org.opencontainers.image.description="AI-assisted development environment with opencode"
4044
LABEL org.opencontainers.image.url="https://github.com/pRizz/opencode-cloud"
4145
LABEL org.opencontainers.image.source="https://github.com/pRizz/opencode-cloud"

scripts/extract-oci-description.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/usr/bin/env python3
2+
import pathlib
3+
import re
4+
import sys
5+
6+
7+
def main() -> int:
8+
dockerfile_path = pathlib.Path(sys.argv[1]) if len(sys.argv) > 1 else pathlib.Path("Dockerfile")
9+
try:
10+
dockerfile = dockerfile_path.read_text()
11+
except OSError as exc:
12+
print(f"Failed to read Dockerfile at {dockerfile_path}: {exc}", file=sys.stderr)
13+
return 2
14+
15+
match = re.search(
16+
r'org\.opencontainers\.image\.description\s*=\s*"([^"]+)"',
17+
dockerfile,
18+
)
19+
if not match:
20+
print(
21+
"Missing org.opencontainers.image.description label in Dockerfile",
22+
file=sys.stderr,
23+
)
24+
return 3
25+
26+
print(match.group(1))
27+
return 0
28+
29+
30+
if __name__ == "__main__":
31+
raise SystemExit(main())

0 commit comments

Comments
 (0)