bots-garden/mini-mepublic Fork
⑂ fa8a56d
Commits
⬇ Clone ▾
git clone https://git.rickub.com/bots-garden/mini-me.git
git clone ssh://git@rickub.com/bots-garden/mini-me.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Download ZIP

🛟 Updated.

k33g committed 2026-09-21T23:47:48+02:00 Browse files
fa8a56d parent: cb250aa
modified .github/workflows/release.yml +50 -6
@@ -110,7 +110,8 @@ jobs:
110110 # account, which is also the image owner) and DOCKER_PAT (an access token
111111 # with read/write scope), exposed to the job as environment variables.
112112 docker-sandbox:
113- name: publish the Docker Sandbox template and kits ${{ github.ref_name }}
113+ # No expression in the name: Rickub shows it unexpanded.
114+ name: publish the Docker Sandbox template and kits
114115 runs-on: ubuntu-latest
115116 needs: release
116117 env:
@@ -122,13 +123,42 @@ jobs:
122123 - name: Checkout
123124 uses: actions/checkout@v4
124125
125- - name: Check the Docker Hub credentials are set
126+ - name: Check the Docker Hub credentials
127+ # Secrets pasted with a trailing newline or a stray CR are a classic;
128+ # both are stripped before use. The handle must be the Docker ID, not
129+ # the e-mail address: access tokens only pair with the username.
126130 run: |
127131 set -euo pipefail
128- if [ -z "${DOCKER_HANDLE}" ] || [ -z "${DOCKER_PAT}" ]; then
132+ handle="$(printf '%s' "${DOCKER_HANDLE}" | tr -d '\r\n' | sed 's/^ *//; s/ *$//')"
133+ pat="$(printf '%s' "${DOCKER_PAT}" | tr -d '\r\n' | sed 's/^ *//; s/ *$//')"
134+ if [ -z "${handle}" ] || [ -z "${pat}" ]; then
129135 echo "❌ DOCKER_HANDLE and DOCKER_PAT must be set as repository secrets"
130136 exit 1
131137 fi
138+ case "${handle}" in
139+ *@*|*:*) echo "❌ DOCKER_HANDLE must be the Docker ID (username), got something with @ or : in it"; exit 1 ;;
140+ esac
141+ echo "handle: ${handle} (${#handle} chars), token: ${#pat} chars"
142+ echo "DOCKER_HANDLE=${handle}" >> "$GITHUB_ENV"
143+ echo "::add-mask::${pat}"
144+ echo "DOCKER_PAT=${pat}" >> "$GITHUB_ENV"
145+
146+ - name: Diagnose the path to Docker Hub
147+ # An anonymous GET on the registry must answer 401 with a Bearer
148+ # challenge. A 400 "malformed HTTP Authorization header" there means
149+ # something between this runner and the Hub (a proxy) adds its own
150+ # Authorization header — the request below carries none. The token
151+ # endpoint check then says whether the credentials themselves are
152+ # accepted, without going through the Docker daemon.
153+ run: |
154+ set -uo pipefail
155+ echo "--- anonymous GET https://registry-1.docker.io/v2/ (expect 401 + www-authenticate: Bearer)"
156+ curl -sS -o /dev/null -D - https://registry-1.docker.io/v2/ | grep -i -E '^HTTP/|^www-authenticate|^docker-distribution' || true
157+ echo "--- token for ${DOCKER_HANDLE}/mm-sandbox with the access token (expect 200)"
158+ code="$(curl -sS -o /dev/null -w '%{http_code}' -u "${DOCKER_HANDLE}:${DOCKER_PAT}" \
159+ "https://auth.docker.io/token?service=registry.docker.io&scope=repository:${DOCKER_HANDLE}/mm-sandbox:pull,push")"
160+ echo "auth.docker.io answered ${code}"
161+ env | grep -i -E '^(https?_proxy|no_proxy|DOCKER_)' | sed 's/=.*/=…/' || true
132162
133163 - name: Set up QEMU
134164 # The final image stage runs `mm --version` for linux/arm64 on an
@@ -139,7 +169,21 @@ jobs:
139169 uses: docker/setup-buildx-action@v3
140170
141171 - name: Log in to Docker Hub
142- run: printf '%s' "${DOCKER_PAT}" | docker login --username "${DOCKER_HANDLE}" --password-stdin
172+ # Not `docker login`: its ping of the registry goes through the Docker
173+ # daemon and failed on Rickub with "malformed HTTP Authorization
174+ # header". Writing the credential store directly is the same result —
175+ # buildx forwards it to BuildKit for the push, and `sbx kit push`
176+ # reads it (credentials.NewStoreFromDocker) — without the ping.
177+ run: |
178+ set -euo pipefail
179+ mkdir -p "${HOME}/.docker"
180+ auth="$(printf '%s:%s' "${DOCKER_HANDLE}" "${DOCKER_PAT}" | base64 | tr -d '\n')"
181+ if [ -f "${HOME}/.docker/config.json" ]; then
182+ cp "${HOME}/.docker/config.json" "${RUNNER_TEMP}/docker-config.orig.json"
183+ fi
184+ printf '{"auths":{"https://index.docker.io/v1/":{"auth":"%s"}}}\n' "${auth}" > "${HOME}/.docker/config.json"
185+ chmod 0600 "${HOME}/.docker/config.json"
186+ echo "credential store written for ${DOCKER_HANDLE}"
143187
144188 - name: Build and push the template image
145189 run: PUSH=1 IMAGE_OWNER="${DOCKER_HANDLE}" bash ./docker-sbx/build.sh "${GITHUB_REF_NAME}"
@@ -158,6 +202,6 @@ jobs:
158202 - name: Publish the kits
159203 run: IMAGE_OWNER="${DOCKER_HANDLE}" SBX="${RUNNER_TEMP}/sbx/sbx" bash ./docker-sbx/push-kits.sh "${GITHUB_REF_NAME}"
160204
161- - name: Log out of Docker Hub
205+ - name: Remove the credential store
162206 if: always()
163- run: docker logout || true
207+ run: rm -f "${HOME}/.docker/config.json"
@@ -110,7 +110,8 @@ jobs:
110 # account, which is also the image owner) and DOCKER_PAT (an access token110 # account, which is also the image owner) and DOCKER_PAT (an access token
111 # with read/write scope), exposed to the job as environment variables.111 # with read/write scope), exposed to the job as environment variables.
112 docker-sandbox:112 docker-sandbox:
113- name: publish the Docker Sandbox template and kits ${{ github.ref_name }}113+ # No expression in the name: Rickub shows it unexpanded.
114+ name: publish the Docker Sandbox template and kits
114 runs-on: ubuntu-latest115 runs-on: ubuntu-latest
115 needs: release116 needs: release
116 env:117 env:
@@ -122,13 +123,42 @@ jobs:
122 - name: Checkout123 - name: Checkout
123 uses: actions/checkout@v4124 uses: actions/checkout@v4
124 125
125- - name: Check the Docker Hub credentials are set126+ - name: Check the Docker Hub credentials
127+ # Secrets pasted with a trailing newline or a stray CR are a classic;
128+ # both are stripped before use. The handle must be the Docker ID, not
129+ # the e-mail address: access tokens only pair with the username.
126 run: |130 run: |
127 set -euo pipefail131 set -euo pipefail
128- if [ -z "${DOCKER_HANDLE}" ] || [ -z "${DOCKER_PAT}" ]; then132+ handle="$(printf '%s' "${DOCKER_HANDLE}" | tr -d '\r\n' | sed 's/^ *//; s/ *$//')"
133+ pat="$(printf '%s' "${DOCKER_PAT}" | tr -d '\r\n' | sed 's/^ *//; s/ *$//')"
134+ if [ -z "${handle}" ] || [ -z "${pat}" ]; then
129 echo "❌ DOCKER_HANDLE and DOCKER_PAT must be set as repository secrets"135 echo "❌ DOCKER_HANDLE and DOCKER_PAT must be set as repository secrets"
130 exit 1136 exit 1
131 fi137 fi
138+ case "${handle}" in
139+ *@*|*:*) echo "❌ DOCKER_HANDLE must be the Docker ID (username), got something with @ or : in it"; exit 1 ;;
140+ esac
141+ echo "handle: ${handle} (${#handle} chars), token: ${#pat} chars"
142+ echo "DOCKER_HANDLE=${handle}" >> "$GITHUB_ENV"
143+ echo "::add-mask::${pat}"
144+ echo "DOCKER_PAT=${pat}" >> "$GITHUB_ENV"
145+
146+ - name: Diagnose the path to Docker Hub
147+ # An anonymous GET on the registry must answer 401 with a Bearer
148+ # challenge. A 400 "malformed HTTP Authorization header" there means
149+ # something between this runner and the Hub (a proxy) adds its own
150+ # Authorization header — the request below carries none. The token
151+ # endpoint check then says whether the credentials themselves are
152+ # accepted, without going through the Docker daemon.
153+ run: |
154+ set -uo pipefail
155+ echo "--- anonymous GET https://registry-1.docker.io/v2/ (expect 401 + www-authenticate: Bearer)"
156+ curl -sS -o /dev/null -D - https://registry-1.docker.io/v2/ | grep -i -E '^HTTP/|^www-authenticate|^docker-distribution' || true
157+ echo "--- token for ${DOCKER_HANDLE}/mm-sandbox with the access token (expect 200)"
158+ code="$(curl -sS -o /dev/null -w '%{http_code}' -u "${DOCKER_HANDLE}:${DOCKER_PAT}" \
159+ "https://auth.docker.io/token?service=registry.docker.io&scope=repository:${DOCKER_HANDLE}/mm-sandbox:pull,push")"
160+ echo "auth.docker.io answered ${code}"
161+ env | grep -i -E '^(https?_proxy|no_proxy|DOCKER_)' | sed 's/=.*/=…/' || true
132 162
133 - name: Set up QEMU163 - name: Set up QEMU
134 # The final image stage runs `mm --version` for linux/arm64 on an164 # The final image stage runs `mm --version` for linux/arm64 on an
@@ -139,7 +169,21 @@ jobs:
139 uses: docker/setup-buildx-action@v3169 uses: docker/setup-buildx-action@v3
140 170
141 - name: Log in to Docker Hub171 - name: Log in to Docker Hub
142- run: printf '%s' "${DOCKER_PAT}" | docker login --username "${DOCKER_HANDLE}" --password-stdin172+ # Not `docker login`: its ping of the registry goes through the Docker
173+ # daemon and failed on Rickub with "malformed HTTP Authorization
174+ # header". Writing the credential store directly is the same result —
175+ # buildx forwards it to BuildKit for the push, and `sbx kit push`
176+ # reads it (credentials.NewStoreFromDocker) — without the ping.
177+ run: |
178+ set -euo pipefail
179+ mkdir -p "${HOME}/.docker"
180+ auth="$(printf '%s:%s' "${DOCKER_HANDLE}" "${DOCKER_PAT}" | base64 | tr -d '\n')"
181+ if [ -f "${HOME}/.docker/config.json" ]; then
182+ cp "${HOME}/.docker/config.json" "${RUNNER_TEMP}/docker-config.orig.json"
183+ fi
184+ printf '{"auths":{"https://index.docker.io/v1/":{"auth":"%s"}}}\n' "${auth}" > "${HOME}/.docker/config.json"
185+ chmod 0600 "${HOME}/.docker/config.json"
186+ echo "credential store written for ${DOCKER_HANDLE}"
143 187
144 - name: Build and push the template image188 - name: Build and push the template image
145 run: PUSH=1 IMAGE_OWNER="${DOCKER_HANDLE}" bash ./docker-sbx/build.sh "${GITHUB_REF_NAME}"189 run: PUSH=1 IMAGE_OWNER="${DOCKER_HANDLE}" bash ./docker-sbx/build.sh "${GITHUB_REF_NAME}"
@@ -158,6 +202,6 @@ jobs:
158 - name: Publish the kits202 - name: Publish the kits
159 run: IMAGE_OWNER="${DOCKER_HANDLE}" SBX="${RUNNER_TEMP}/sbx/sbx" bash ./docker-sbx/push-kits.sh "${GITHUB_REF_NAME}"203 run: IMAGE_OWNER="${DOCKER_HANDLE}" SBX="${RUNNER_TEMP}/sbx/sbx" bash ./docker-sbx/push-kits.sh "${GITHUB_REF_NAME}"
160 204
161- - name: Log out of Docker Hub205+ - name: Remove the credential store
162 if: always()206 if: always()
163- run: docker logout || true207+ run: rm -f "${HOME}/.docker/config.json"