Skip to content

Commit 0ab4a84

Browse files
author
1
committed
debug
1 parent 3c9475e commit 0ab4a84

1 file changed

Lines changed: 87 additions & 0 deletions

File tree

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
name: debug-dockerhub-description
2+
3+
on:
4+
workflow_dispatch:
5+
6+
jobs:
7+
debug:
8+
runs-on: ubuntu-latest
9+
steps:
10+
- uses: actions/checkout@v4
11+
12+
- name: Show README size and first lines
13+
run: |
14+
echo "== ./containers/xonsh/README.md =="
15+
wc -c ./containers/xonsh/README.md
16+
echo "----- first 20 lines -----"
17+
head -n 20 ./containers/xonsh/README.md
18+
echo "----- end -----"
19+
20+
- name: Probe Docker Hub description API
21+
env:
22+
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
23+
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
24+
run: |
25+
set -eu
26+
27+
# Build auth body with jq so the secret is never embedded into a shell-interpolated string.
28+
jq -nc --arg u "$DOCKERHUB_USERNAME" --arg s "$DOCKERHUB_TOKEN" \
29+
'{identifier:$u, secret:$s}' > /tmp/auth_body.json
30+
31+
echo "== POST /v2/auth/token =="
32+
auth_code=$(curl -sS -o /tmp/auth.json -w "%{http_code}" \
33+
-X POST https://hub.docker.com/v2/auth/token \
34+
-H 'Content-Type: application/json' \
35+
--data-binary @/tmp/auth_body.json)
36+
shred -u /tmp/auth_body.json 2>/dev/null || rm -f /tmp/auth_body.json
37+
38+
echo "HTTP status: $auth_code"
39+
echo "Response keys: $(jq -r 'keys | join(", ")' /tmp/auth.json 2>/dev/null || echo '<not JSON>')"
40+
# NB: We deliberately do NOT print the response body — it contains the token.
41+
42+
token=$(jq -r '.access_token // .token // empty' /tmp/auth.json)
43+
rm -f /tmp/auth.json
44+
if [ -z "$token" ]; then
45+
echo "::error::Failed to obtain token (status $auth_code)"
46+
exit 1
47+
fi
48+
# Mask the token in logs in case anything below echoes it accidentally.
49+
echo "::add-mask::$token"
50+
echo "Token acquired (length: ${#token})"
51+
52+
echo "== PATCH /v2/repositories/xonsh/xonsh =="
53+
jq -Rs '{full_description: .}' ./containers/xonsh/README.md > /tmp/body.json
54+
echo "Body size: $(wc -c < /tmp/body.json) bytes"
55+
56+
patch_code=$(curl -sS -o /tmp/patch.out -D /tmp/patch.headers -w "%{http_code}" \
57+
-X PATCH https://hub.docker.com/v2/repositories/xonsh/xonsh \
58+
-H "Authorization: Bearer ${token}" \
59+
-H 'Content-Type: application/json' \
60+
--data-binary @/tmp/body.json)
61+
# Token used; clear it from this shell. (It is short-lived anyway.)
62+
unset token
63+
rm -f /tmp/body.json
64+
65+
echo "HTTP status: $patch_code"
66+
echo "----- response headers -----"
67+
# Drop any Set-Cookie just in case it includes a session.
68+
grep -vi '^set-cookie:' /tmp/patch.headers || true
69+
echo "----- response body (first 4000 chars) -----"
70+
head -c 4000 /tmp/patch.out
71+
echo
72+
echo "----- end -----"
73+
rm -f /tmp/patch.out /tmp/patch.headers
74+
75+
case "$patch_code" in
76+
2*)
77+
echo "::notice::PATCH succeeded — description sync would work"
78+
;;
79+
*)
80+
if grep -qiE 'cloudflare|cf-ray|attention required|sorry, you have been blocked' /tmp/patch.out /tmp/patch.headers 2>/dev/null; then
81+
echo "::error::403 came from Cloudflare WAF — README content triggered the block"
82+
else
83+
echo "::error::PATCH failed with $patch_code — likely PAT scope or org admin role"
84+
fi
85+
exit 1
86+
;;
87+
esac

0 commit comments

Comments
 (0)