@@ -6,8 +6,9 @@ HERE="$(cd "$(dirname "$0")" && pwd)"
66SCRIPT=" ${HERE} /../detect-py-version-changes.sh"
77TMP=" $( mktemp -d) "
88SRV_PID=" "
9+ STDERR_LOG=" $TMP /stderr.log"
910cleanup () { [ -n " $SRV_PID " ] && kill " $SRV_PID " 2> /dev/null || true ; rm -rf " $TMP " ; }
10- trap cleanup EXIT
11+ trap cleanup EXIT INT TERM
1112
1213# Preflight: tomllib requires py3.11+
1314python3 -c ' import sys; sys.exit(0 if sys.version_info >= (3,11) else 1)' \
@@ -39,21 +40,59 @@ httpd.serve_forever()
3940PY
4041 SRV_PID=$!
4142 for _ in $( seq 1 50) ; do [ -s " $PORTFILE " ] && break ; sleep 0.1; done
43+ if [ ! -s " $PORTFILE " ]; then
44+ echo " FAIL: fixture server failed to bind/write PORTFILE within 5s" >&2
45+ exit 1
46+ fi
4247 PORT=" $( cat " $PORTFILE " ) "
4348}
4449stop_server () { kill " $SRV_PID " 2> /dev/null || true ; wait " $SRV_PID " 2> /dev/null || true ; SRV_PID=" " ; }
4550
46- serve_published () { mkdir -p " $WWW /pypi/copilotkit" ; printf ' {"info":{"version":"%s"}}' " $1 " > " $WWW /pypi/copilotkit/json" ; }
51+ serve_published () {
52+ # Realistic PyPI-shaped response: info.version AND a releases dict (single
53+ # released version). Real PyPI always returns `releases`; the bare-info shape
54+ # was a test-only shortcut that the max-over-releases logic doesn't match.
55+ mkdir -p " $WWW /pypi/copilotkit"
56+ printf ' {"info":{"version":"%s"},"releases":{"%s":[]}}' " $1 " " $1 " > " $WWW /pypi/copilotkit/json"
57+ }
58+
59+ # Serve a fuller PyPI-shaped response: info.version + a releases dict whose keys
60+ # are the version strings. $1 = info.version, remaining args = release keys.
61+ serve_published_with_releases () {
62+ mkdir -p " $WWW /pypi/copilotkit"
63+ local info=" $1 " ; shift
64+ local rels=" " k
65+ for k in " $@ " ; do
66+ [ -z " $rels " ] && rels=" \" $k \" :[]" || rels=" $rels ,\" $k \" :[]"
67+ done
68+ printf ' {"info":{"version":"%s"},"releases":{%s}}' " $info " " $rels " > " $WWW /pypi/copilotkit/json"
69+ }
4770
4871run () {
4972 PYPROJECT_PATH=" $TMP /pkg/pyproject.toml" PYPI_BASE_URL=" http://127.0.0.1:${PORT} " \
50- " $SCRIPT " 2> /dev/null | tail -n1
73+ " $SCRIPT " 2> " $STDERR_LOG " | tail -n1
74+ }
75+ fail () {
76+ echo " FAIL: $1 " >&2
77+ if [ -s " $STDERR_LOG " ]; then
78+ echo " --- captured stderr ---" >&2
79+ cat " $STDERR_LOG " >&2
80+ echo " --- end stderr ---" >&2
81+ fi
82+ exit 1
5183}
52- fail () { echo " FAIL: $1 " >&2 ; exit 1; }
5384
5485# Case A: published == local (0.2.0) -> should_publish=false (no-op)
86+ # Also assert GITHUB_OUTPUT emission: the script must append should_publish=,
87+ # name=, and version= lines when GITHUB_OUTPUT is set.
5588rm -rf " $WWW " ; serve_published " 0.2.0" ; start_server
56- OUT=" $( run) " ; echo " A: $OUT " ; [ " $OUT " = " false copilotkit 0.2.0" ] || fail " no-op: got '$OUT '"
89+ GHO=" $TMP /gho.txt" ; : > " $GHO "
90+ OUT=" $( GITHUB_OUTPUT=" $GHO " PYPROJECT_PATH=" $TMP /pkg/pyproject.toml" PYPI_BASE_URL=" http://127.0.0.1:${PORT} " \
91+ " $SCRIPT " 2> " $STDERR_LOG " | tail -n1) "
92+ echo " A: $OUT " ; [ " $OUT " = " false copilotkit 0.2.0" ] || fail " no-op: got '$OUT '"
93+ grep -q ' ^should_publish=false$' " $GHO " || fail " GITHUB_OUTPUT missing should_publish=false (got: $( cat " $GHO " ) )"
94+ grep -q ' ^name=copilotkit$' " $GHO " || fail " GITHUB_OUTPUT missing name=copilotkit (got: $( cat " $GHO " ) )"
95+ grep -q ' ^version=0.2.0$' " $GHO " || fail " GITHUB_OUTPUT missing version=0.2.0 (got: $( cat " $GHO " ) )"
5796stop_server
5897
5998# Case B: published < local (0.1.91 < 0.2.0) -> should_publish=true (exactly one pkg)
@@ -66,4 +105,30 @@ rm -rf "$WWW"; mkdir -p "$WWW"; start_server
66105OUT=" $( run) " ; echo " C: $OUT " ; [ " $OUT " = " true copilotkit 0.2.0" ] || fail " new-pkg: got '$OUT '"
67106stop_server
68107
108+ # Case D: info.version is LOWER than the true max in releases. PyPI's info.version
109+ # is the LATEST-UPLOADED, not the highest — an out-of-order patch upload to an
110+ # old line can produce this state. The script must compute the max over the
111+ # numeric-parseable releases keys, not trust info.version.
112+ # releases = {0.1.0, 0.2.0}, info.version=0.1.0, local=0.2.0 -> 0.2.0==0.2.0 -> false.
113+ rm -rf " $WWW " ; serve_published_with_releases " 0.1.0" " 0.1.0" " 0.2.0" ; start_server
114+ OUT=" $( run) " ; echo " D: $OUT " ; [ " $OUT " = " false copilotkit 0.2.0" ] || fail " max-over-releases: got '$OUT '"
115+ stop_server
116+
117+ # Case E: releases contains a non-numeric prerelease key alongside numeric. The
118+ # script must ignore non-numeric published keys (not abort on them) and compare
119+ # against the numeric max. info.version is the prerelease (rc1); local is 0.2.1.
120+ # numeric max published = 0.2.0 < 0.2.1 -> should_publish=true.
121+ rm -rf " $WWW "
122+ mkdir -p " $TMP /pkg2"
123+ cat > " $TMP /pkg2/pyproject.toml" << 'TOML '
124+ [tool.poetry]
125+ name = "copilotkit"
126+ version = "0.2.1"
127+ TOML
128+ serve_published_with_releases " 0.2.1rc1" " 0.2.0" " 0.2.1rc1" ; start_server
129+ OUT=" $( PYPROJECT_PATH=" $TMP /pkg2/pyproject.toml" PYPI_BASE_URL=" http://127.0.0.1:${PORT} " \
130+ " $SCRIPT " 2> " $STDERR_LOG " | tail -n1) "
131+ echo " E: $OUT " ; [ " $OUT " = " true copilotkit 0.2.1" ] || fail " non-numeric-released-ignored: got '$OUT '"
132+ stop_server
133+
69134echo " ALL PASS"
0 commit comments