#!/usr/bin/env bash # Package Lambda zips for HCP plan/apply. Runs on the Terraform worker. set -euo pipefail ROOT="$(cd "$(dirname "$0")" && pwd)" BUILD="${ROOT}/build" SRC="$(cd "${ROOT}/../lambdas" && pwd)" # Copy only regular files that resolve inside SRC (no symlink escape). copy_src_file() { local rel="$1" local dest="$2" local src_path="${SRC}/${rel}" if [[ -L "${src_path}" ]]; then echo "error: refusing symlink source: ${src_path}" >&2 exit 1 fi if [[ ! -f "${src_path}" ]]; then echo "error: missing regular file: ${src_path}" >&2 exit 1 fi local resolved resolved="$(cd "$(dirname "${src_path}")" && pwd)/$(basename "${src_path}")" case "${resolved}" in "${SRC}"/*) ;; *) echo "error: path escapes src tree: ${resolved}" >&2 exit 1 ;; esac mkdir -p "$(dirname "${dest}")" cp -P "${src_path}" "${dest}" } copy_py_dir() { local rel_dir="$1" local dest_dir="$2" local f mkdir -p "${dest_dir}" for f in "${SRC}/${rel_dir}"/*.py; do [[ -f "${f}" ]] || continue copy_src_file "${rel_dir}/$(basename "${f}")" "${dest_dir}/$(basename "${f}")" done } copy_shared_all() { local dest_dir="$1" local f for f in "${SRC}/shared"/*.py; do [[ -f "${f}" ]] || continue copy_src_file "shared/$(basename "${f}")" "${dest_dir}/$(basename "${f}")" done } maybe_pip_install() { local dest_dir="$1" local req="${dest_dir}/requirements.txt" if [[ ! -f "${req}" ]]; then return 0 fi local deps deps="$(grep -Ev '^[[:space:]]*(#|$)' "${req}" || true)" if [[ -z "${deps}" ]]; then rm -f "${req}" return 0 fi # boto3-only pins are Dependabot anchors; runtime provides boto3. if ! printf '%s\n' "${deps}" | grep -Eqv '^[[:space:]]*boto3([= ]|$)'; then rm -f "${req}" return 0 fi python3 -m pip install \ --quiet \ --disable-pip-version-check \ -r "${req}" \ -t "${dest_dir}/" \ --platform manylinux2014_aarch64 \ --implementation cp \ --python-version 3.12 \ --only-binary=:all: \ --upgrade rm -rf "${dest_dir}/boto3" "${dest_dir}/botocore" \ "${dest_dir}/s3transfer" "${dest_dir}/jmespath" \ "${dest_dir}/"*.dist-info 2>/dev/null || true rm -f "${req}" } rm -rf "${BUILD}" mkdir -p \ "${BUILD}/po_email_processor" \ "${BUILD}/po_web_ui" \ "${BUILD}/po_site_extractor" \ "${BUILD}/wo_email_processor" \ "${BUILD}/wo_web_ui" \ "${BUILD}/wo_shoc_emitter" \ "${BUILD}/wo_shoc_hmac_rotator" \ "${BUILD}/procurement_api" copy_py_dir "po/email_processor" "${BUILD}/po_email_processor" copy_shared_all "${BUILD}/po_email_processor" if [[ -f "${SRC}/po/email_processor/requirements.txt" ]]; then copy_src_file "po/email_processor/requirements.txt" "${BUILD}/po_email_processor/requirements.txt" fi maybe_pip_install "${BUILD}/po_email_processor" copy_py_dir "po/web_ui" "${BUILD}/po_web_ui" copy_src_file "shared/web_ui_auth.py" "${BUILD}/po_web_ui/web_ui_auth.py" if [[ -f "${SRC}/po/web_ui/requirements.txt" ]]; then copy_src_file "po/web_ui/requirements.txt" "${BUILD}/po_web_ui/requirements.txt" fi maybe_pip_install "${BUILD}/po_web_ui" copy_py_dir "po/site_extractor" "${BUILD}/po_site_extractor" if [[ -f "${SRC}/po/site_extractor/requirements.txt" ]]; then copy_src_file "po/site_extractor/requirements.txt" "${BUILD}/po_site_extractor/requirements.txt" fi maybe_pip_install "${BUILD}/po_site_extractor" copy_py_dir "wo/email_processor" "${BUILD}/wo_email_processor" copy_shared_all "${BUILD}/wo_email_processor" if [[ -f "${SRC}/wo/email_processor/requirements.txt" ]]; then copy_src_file "wo/email_processor/requirements.txt" "${BUILD}/wo_email_processor/requirements.txt" fi maybe_pip_install "${BUILD}/wo_email_processor" copy_py_dir "wo/web_ui" "${BUILD}/wo_web_ui" copy_src_file "shared/web_ui_auth.py" "${BUILD}/wo_web_ui/web_ui_auth.py" if [[ -f "${SRC}/wo/web_ui/requirements.txt" ]]; then copy_src_file "wo/web_ui/requirements.txt" "${BUILD}/wo_web_ui/requirements.txt" fi maybe_pip_install "${BUILD}/wo_web_ui" copy_py_dir "wo/shoc_emitter" "${BUILD}/wo_shoc_emitter" copy_py_dir "wo/shoc_hmac_rotator" "${BUILD}/wo_shoc_hmac_rotator" copy_py_dir "api" "${BUILD}/procurement_api" for f in openapi.json docs.html redoc.standalone.js fonts.css; do copy_src_file "api/${f}" "${BUILD}/procurement_api/${f}" done copy_src_file "shared/web_ui_auth.py" "${BUILD}/procurement_api/web_ui_auth.py" if [[ -f "${SRC}/api/requirements.txt" ]]; then copy_src_file "api/requirements.txt" "${BUILD}/procurement_api/requirements.txt" fi maybe_pip_install "${BUILD}/procurement_api"