Skip to content

Commit f44873a

Browse files
committed
Add pixi task to migrate devcontainer to prebuilt GHCR image
New `pixi run dev-use-prebuilt` task that automates switching from local builds to the prebuilt GHCR image: - Detects repo owner/name from git remote - Comments out build/features blocks in devcontainer.json - Uncomments and sets the correct image reference - Attempts to make the GHCR package public via gh CLI - Idempotent: no-op if already using a prebuilt image
1 parent 799c95b commit f44873a

File tree

2 files changed

+84
-0
lines changed

2 files changed

+84
-0
lines changed

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ ci-push = { depends-on = ["format", "ruff-lint", "update-lock", "ci", "push"] }
9999
clear-pixi = "rm -rf .pixi pixi.lock"
100100
setup-git-merge-driver = "git config merge.ourslock.driver true"
101101
update-from-template-repo = "./scripts/update_from_template.sh"
102+
dev-use-prebuilt = "./scripts/devcontainer_use_prebuilt.sh"
102103

103104
[tool.pylint]
104105
extension-pkg-whitelist = ["numpy"]
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#!/bin/bash
2+
set -euo pipefail
3+
4+
# Migrate devcontainer.json from local builds to a prebuilt GHCR image.
5+
# Also attempts to make the GHCR package public.
6+
7+
DEVCONTAINER_JSON=".devcontainer/devcontainer.json"
8+
9+
# --- Resolve GitHub owner/repo from git remote ---
10+
REMOTE_URL=$(git remote get-url origin 2>/dev/null) || {
11+
echo "ERROR: No git remote 'origin' found." >&2
12+
exit 1
13+
}
14+
15+
# Handle ssh (git@github.com:owner/repo.git) and https URLs
16+
REPO=$(echo "$REMOTE_URL" | sed -E 's#(git@github\.com:|https://github\.com/)##; s/\.git$//')
17+
18+
if [[ -z "$REPO" || "$REPO" != */* ]]; then
19+
echo "ERROR: Could not parse owner/repo from remote URL: $REMOTE_URL" >&2
20+
exit 1
21+
fi
22+
23+
IMAGE="ghcr.io/${REPO}/devcontainer:latest"
24+
echo "Repository: $REPO"
25+
echo "Image: $IMAGE"
26+
27+
# --- Check current state: look for an uncommented "image": line ---
28+
if grep -qP '^\s+"image"\s*:' "$DEVCONTAINER_JSON"; then
29+
echo "Already using a prebuilt image. Nothing to do."
30+
exit 0
31+
fi
32+
33+
# --- Replace the file using awk for reliable block manipulation ---
34+
awk -v image="$IMAGE" '
35+
# Comment out uncommented "build" block (4-space indent open/close)
36+
/^ "build": \{/ { in_build=1 }
37+
in_build {
38+
sub(/^ /, " // ")
39+
if (/^ \/\/ \}/) in_build=0
40+
print; next
41+
}
42+
43+
# Comment out uncommented "features" block (4-space indent open/close)
44+
/^ "features": \{/ { in_features=1 }
45+
in_features {
46+
sub(/^ /, " // ")
47+
if (/^ \/\/ \}/) in_features=0
48+
print; next
49+
}
50+
51+
# Uncomment the image line and set the correct reference
52+
/^ \/\/ "image":/ {
53+
printf " \"image\": \"%s\",\n", image
54+
next
55+
}
56+
57+
{ print }
58+
' "$DEVCONTAINER_JSON" > "${DEVCONTAINER_JSON}.tmp" && mv "${DEVCONTAINER_JSON}.tmp" "$DEVCONTAINER_JSON"
59+
60+
echo ""
61+
echo "Updated $DEVCONTAINER_JSON to use prebuilt image."
62+
63+
# --- Try to make the GHCR package public ---
64+
echo ""
65+
echo "Attempting to make GHCR package public..."
66+
67+
PACKAGE_NAME=$(echo "$REPO" | cut -d'/' -f2)
68+
ENCODED_PACKAGE="${PACKAGE_NAME}%2Fdevcontainer"
69+
70+
if gh api --method PATCH "/user/packages/container/${ENCODED_PACKAGE}" -f visibility=public >/dev/null 2>&1; then
71+
echo "GHCR package is now public."
72+
else
73+
echo "Could not set package visibility automatically."
74+
echo ""
75+
echo "To make the package public manually, either:"
76+
echo ""
77+
echo " 1. Visit: https://github.com/users/$(echo "$REPO" | cut -d'/' -f1)/packages/container/${ENCODED_PACKAGE}/settings"
78+
echo " -> Danger Zone -> Change visibility -> Public"
79+
echo ""
80+
echo " 2. Run:"
81+
echo " gh auth refresh -s write:packages"
82+
echo " gh api --method PATCH /user/packages/container/${ENCODED_PACKAGE} -f visibility=public"
83+
fi

0 commit comments

Comments
 (0)