@@ -68,6 +68,15 @@ runtime_paths=(
6868 src
6969)
7070
71+ required_generated_paths=(
72+ src/generated/byova_common_pb2.py
73+ src/generated/byova_common_pb2_grpc.py
74+ src/generated/health_pb2.py
75+ src/generated/health_pb2_grpc.py
76+ src/generated/voicevirtualagent_pb2.py
77+ src/generated/voicevirtualagent_pb2_grpc.py
78+ )
79+
7180for path in " ${required_paths[@]} " ; do
7281 if ! git cat-file -e " ${resolved_ref} :${path} " 2> /dev/null; then
7382 echo " error: required runtime path is missing at ${ref} : ${path} " >&2
@@ -86,10 +95,73 @@ mkdir -p "$(dirname "$output")"
8695output_dir=" $( cd " $( dirname " $output " ) " && pwd -P) "
8796output_path=" ${output_dir} /$( basename " $output " ) "
8897temporary_archive=" $( mktemp " ${TMPDIR:-/ tmp} /byova-runtime-release.XXXXXX" ) "
89- trap ' rm -f "$temporary_archive"' EXIT
98+ staging_root=" $( mktemp -d " ${TMPDIR:-/ tmp} /byova-runtime-staging.XXXXXX" ) "
99+
100+ cleanup () {
101+ rm -f " $temporary_archive "
102+ rm -rf " $staging_root "
103+ }
104+ trap cleanup EXIT
90105
91106git archive --format=tar " $resolved_ref " -- " ${archive_paths[@]} " \
92- | gzip -n > " $temporary_archive "
107+ | tar -xf - -C " $staging_root "
108+
109+ protoc_python=" "
110+ protoc_candidates=()
111+ if [[ -n " ${PYTHON:- } " ]]; then
112+ protoc_candidates+=(" $PYTHON " )
113+ fi
114+ protoc_candidates+=(
115+ " $repo_root /.venv/bin/python"
116+ " $repo_root /venv/bin/python"
117+ python3
118+ python
119+ )
120+
121+ for candidate in " ${protoc_candidates[@]} " ; do
122+ if [[ " $candidate " == * /* ]]; then
123+ [[ -x " $candidate " ]] || continue
124+ elif ! command -v " $candidate " > /dev/null 2>&1 ; then
125+ continue
126+ fi
127+ if " $candidate " -c ' import grpc_tools.protoc' > /dev/null 2>&1 ; then
128+ protoc_python=" $candidate "
129+ break
130+ fi
131+ done
132+
133+ if [[ -z " $protoc_python " ]]; then
134+ echo " error: grpcio-tools is required to build runtime protobuf modules" >&2
135+ exit 1
136+ fi
137+
138+ proto_files=()
139+ while IFS= read -r proto_file; do
140+ proto_files+=(" $proto_file " )
141+ done < <( find " $staging_root /proto" -maxdepth 1 -type f -name ' *.proto' -print | sort)
142+
143+ if [[ " ${# proto_files[@]} " -eq 0 ]]; then
144+ echo " error: runtime release contains no protobuf definitions" >&2
145+ exit 1
146+ fi
147+
148+ " $protoc_python " -m grpc_tools.protoc \
149+ -I" $staging_root /proto" \
150+ --python_out=" $staging_root /src/generated" \
151+ --grpc_python_out=" $staging_root /src/generated" \
152+ " ${proto_files[@]} "
153+
154+ for path in " ${required_generated_paths[@]} " ; do
155+ if [[ ! -f " $staging_root /$path " ]]; then
156+ echo " error: generated runtime module is missing: $path " >&2
157+ exit 1
158+ fi
159+ done
160+
161+ (
162+ cd " $staging_root "
163+ COPYFILE_DISABLE=1 tar -cf - " ${archive_paths[@]} "
164+ ) | gzip -n > " $temporary_archive "
93165
94166archive_listing=" $( tar -tzf " $temporary_archive " ) "
95167for path in " ${required_paths[@]} " ; do
@@ -98,6 +170,12 @@ for path in "${required_paths[@]}"; do
98170 exit 1
99171 fi
100172done
173+ for path in " ${required_generated_paths[@]} " ; do
174+ if ! grep -Eq " ^${path} $" <<< " $archive_listing" ; then
175+ echo " error: runtime archive is missing generated module: $path " >&2
176+ exit 1
177+ fi
178+ done
101179
102180forbidden_pattern=' (^|/)(tools|tests|docs)(/|$)|(^|/)(requirements-dev.txt|package.json|package-lock.json|npm-shrinkwrap.json|yarn.lock|pnpm-lock.yaml)$|(^|/)\._'
103181if grep -Eq " $forbidden_pattern " <<< " $archive_listing" ; then
@@ -107,6 +185,7 @@ if grep -Eq "$forbidden_pattern" <<<"$archive_listing"; then
107185fi
108186
109187mv " $temporary_archive " " $output_path "
188+ cleanup
110189trap - EXIT
111190
112191if command -v sha256sum > /dev/null 2>&1 ; then
0 commit comments