423 lines
14 KiB
Bash
423 lines
14 KiB
Bash
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
usage() {
|
|
cat <<'EOF'
|
|
Usage:
|
|
HYPERTWIST_REMOTE_WINDOWS_PASSWORD=... \
|
|
scripts/run-hypertwist-remote-exact-source-browser-package-refresh.sh
|
|
|
|
Options:
|
|
--worktree-root <path>
|
|
Optional Windows worktree root. Defaults to C:\HyperTwist_worktrees\phase10validate.
|
|
|
|
--report-stamp <YYYYMMDD>
|
|
Optional suffix used for the browser automation report and package archive.
|
|
Defaults to the current UTC date.
|
|
|
|
--fallback-worktree-root <path>
|
|
Optional fallback Windows worktree root to use if the primary refresh
|
|
fails. Useful when the maintained worktree is temporarily locked by
|
|
another Windows-side process.
|
|
|
|
--browser-filter <automation-filter>
|
|
Optional Unreal automation filter. Defaults to HyperTwist.Browser.
|
|
|
|
--browser-report-name <name>
|
|
Optional explicit browser automation report name. Defaults to
|
|
Browser-ExactSource-<report-stamp>.
|
|
|
|
--package-archive-dir <path>
|
|
Optional Windows archive directory for the higher-dimensional package run.
|
|
Defaults to <worktree-root>_packaged_phase6c_higherdim_refresh_<report-stamp>.
|
|
|
|
--sync-file <repo-relative-path>
|
|
Optional repo-relative file to sync into the remote Windows worktree before
|
|
validation. May be repeated.
|
|
|
|
--skip-build
|
|
Skip the remote Unreal editor build step.
|
|
|
|
--skip-browser-automation
|
|
Skip the HyperTwist.Browser automation refresh.
|
|
|
|
--skip-package
|
|
Skip the higher-dimensional package refresh.
|
|
|
|
--skip-browser-report-pull
|
|
Skip pulling the browser automation index.json back into docs/generated.
|
|
|
|
--skip-package-report-pull
|
|
Skip pulling the higher-dimensional package validation report back into
|
|
docs/generated.
|
|
|
|
--skip-summary-refresh
|
|
Skip re-rendering website/src/shared/generated/windows-package-validation-summary.json.
|
|
|
|
--skip-exact-source-support-sync
|
|
Skip syncing the bounded exact-source browser/package support files that
|
|
the fallback Windows validation root needs for truthful browser/package
|
|
refreshes.
|
|
|
|
--dry-run
|
|
Print the wrapper invocations without executing them.
|
|
|
|
Environment:
|
|
HYPERTWIST_REMOTE_WINDOWS_PASSWORD Required by the underlying remote wrappers.
|
|
HYPERTWIST_REMOTE_WINDOWS_WORKTREE_ROOT Optional default for --worktree-root.
|
|
HYPERTWIST_REMOTE_WINDOWS_FALLBACK_WORKTREE_ROOT
|
|
Optional default for --fallback-worktree-root.
|
|
HYPERTWIST_REMOTE_WINDOWS_SKIP_EXACT_SOURCE_SUPPORT_SYNC
|
|
Optional default for --skip-exact-source-support-sync.
|
|
EOF
|
|
}
|
|
|
|
ps_single_quote() {
|
|
printf "'%s'" "${1//\'/\'\'}"
|
|
}
|
|
|
|
run_or_print() {
|
|
if [[ "$dry_run" == "true" ]]; then
|
|
printf '%q ' "$@"
|
|
printf '\n'
|
|
return 0
|
|
fi
|
|
|
|
"$@"
|
|
}
|
|
|
|
worktree_root="${HYPERTWIST_REMOTE_WINDOWS_WORKTREE_ROOT:-C:\\HyperTwist_worktrees\\phase10validate}"
|
|
fallback_worktree_root="${HYPERTWIST_REMOTE_WINDOWS_FALLBACK_WORKTREE_ROOT:-}"
|
|
report_stamp="$(date -u '+%Y%m%d')"
|
|
browser_filter="HyperTwist.Browser"
|
|
browser_report_name=""
|
|
package_archive_dir=""
|
|
sync_files=()
|
|
skip_build="false"
|
|
skip_browser_automation="false"
|
|
skip_package="false"
|
|
skip_browser_report_pull="false"
|
|
skip_package_report_pull="false"
|
|
skip_summary_refresh="false"
|
|
skip_exact_source_support_sync="${HYPERTWIST_REMOTE_WINDOWS_SKIP_EXACT_SOURCE_SUPPORT_SYNC:-false}"
|
|
dry_run="false"
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--worktree-root)
|
|
worktree_root="${2:-}"
|
|
shift 2
|
|
;;
|
|
--report-stamp)
|
|
report_stamp="${2:-}"
|
|
shift 2
|
|
;;
|
|
--fallback-worktree-root)
|
|
fallback_worktree_root="${2:-}"
|
|
shift 2
|
|
;;
|
|
--browser-filter)
|
|
browser_filter="${2:-}"
|
|
shift 2
|
|
;;
|
|
--browser-report-name)
|
|
browser_report_name="${2:-}"
|
|
shift 2
|
|
;;
|
|
--package-archive-dir)
|
|
package_archive_dir="${2:-}"
|
|
shift 2
|
|
;;
|
|
--sync-file)
|
|
sync_files+=("${2:-}")
|
|
shift 2
|
|
;;
|
|
--skip-build)
|
|
skip_build="true"
|
|
shift
|
|
;;
|
|
--skip-browser-automation)
|
|
skip_browser_automation="true"
|
|
shift
|
|
;;
|
|
--skip-package)
|
|
skip_package="true"
|
|
shift
|
|
;;
|
|
--skip-browser-report-pull)
|
|
skip_browser_report_pull="true"
|
|
shift
|
|
;;
|
|
--skip-package-report-pull)
|
|
skip_package_report_pull="true"
|
|
shift
|
|
;;
|
|
--skip-summary-refresh)
|
|
skip_summary_refresh="true"
|
|
shift
|
|
;;
|
|
--skip-exact-source-support-sync)
|
|
skip_exact_source_support_sync="true"
|
|
shift
|
|
;;
|
|
--dry-run)
|
|
dry_run="true"
|
|
shift
|
|
;;
|
|
-h|--help)
|
|
usage
|
|
exit 0
|
|
;;
|
|
*)
|
|
usage >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if [[ -z "$browser_report_name" ]]; then
|
|
browser_report_name="Browser-ExactSource-${report_stamp}"
|
|
fi
|
|
|
|
if [[ -z "$package_archive_dir" ]]; then
|
|
package_archive_dir="${worktree_root}_packaged_phase6c_higherdim_refresh_${report_stamp}"
|
|
fi
|
|
|
|
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
repo_root="$(cd "${script_dir}/.." && pwd)"
|
|
remote_ps_wrapper="${script_dir}/run-hypertwist-remote-windows-powershell.sh"
|
|
remote_build_wrapper="${script_dir}/run-hypertwist-remote-unreal-build.sh"
|
|
remote_automation_wrapper="${script_dir}/run-hypertwist-remote-unreal-automation.sh"
|
|
remote_sync_wrapper="${script_dir}/run-hypertwist-remote-windows-file-sync.sh"
|
|
remote_pull_wrapper="${script_dir}/run-hypertwist-remote-windows-file-pull.sh"
|
|
summary_refresh_script="${script_dir}/render-hypertwist-web-package-validation-summary.mjs"
|
|
|
|
for required_wrapper in \
|
|
"$remote_ps_wrapper" \
|
|
"$remote_build_wrapper" \
|
|
"$remote_automation_wrapper" \
|
|
"$remote_sync_wrapper" \
|
|
"$remote_pull_wrapper"
|
|
do
|
|
if [[ ! -x "$required_wrapper" ]]; then
|
|
echo "Expected executable wrapper at $required_wrapper" >&2
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
if [[ ! -f "$summary_refresh_script" ]]; then
|
|
echo "Expected summary refresh script at $summary_refresh_script" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [[ -z "${HYPERTWIST_REMOTE_WINDOWS_PASSWORD:-}" ]]; then
|
|
echo "Set HYPERTWIST_REMOTE_WINDOWS_PASSWORD before running this refresh." >&2
|
|
exit 1
|
|
fi
|
|
|
|
host_probe_command="Write-Output ('USER=' + [System.Security.Principal.WindowsIdentity]::GetCurrent().Name); Write-Output ('HOST=' + \$env:COMPUTERNAME)"
|
|
browser_report_local_path="docs/generated/browser_automation/${browser_report_name}/index.json"
|
|
package_report_local_path="docs/generated/higher_dimensional_training_maps/phase6c_dedicated_family_package_validation_report.json"
|
|
exact_source_support_files=(
|
|
"Content/Browser/index.html"
|
|
"Content/Browser/src/browser-runtime-bootstrap.js"
|
|
"Content/Browser/src/browser-spatial-runtime-fallback.js"
|
|
"Content/Browser/src/runtime/shell.ts"
|
|
"scripts/Invoke-HyperTwistHigherDimensionalPackage.ps1"
|
|
"scripts/Launch-HyperTwistHigherDimensionalPackage.ps1"
|
|
"docs/generated/higher_dimensional_training_maps/phase6c_dedicated_family_map_manifest.json"
|
|
"UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingRepositoryLibrary.cpp"
|
|
"UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingRepositoryLibraryInternal.h"
|
|
"UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingRepositoryLibraryCoachPolicies.cpp"
|
|
"UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingRepositoryLibraryCoachWorkflow.cpp"
|
|
"UnrealHyperTwist/Source/UnrealHyperTwist/Private/HyperTwistTraining/HyperTwistTrainingRepositoryLibraryCoachSummaries.cpp"
|
|
)
|
|
effective_sync_files=()
|
|
|
|
add_effective_sync_file() {
|
|
local candidate="$1"
|
|
local existing
|
|
for existing in "${effective_sync_files[@]}"; do
|
|
if [[ "$existing" == "$candidate" ]]; then
|
|
return 0
|
|
fi
|
|
done
|
|
effective_sync_files+=("$candidate")
|
|
}
|
|
|
|
if [[ "$skip_exact_source_support_sync" != "true" ]]; then
|
|
for sync_file in "${exact_source_support_files[@]}"; do
|
|
add_effective_sync_file "$sync_file"
|
|
done
|
|
fi
|
|
|
|
for sync_file in "${sync_files[@]}"; do
|
|
add_effective_sync_file "$sync_file"
|
|
done
|
|
|
|
run_refresh_for_root() {
|
|
local current_worktree_root="$1"
|
|
local current_validation_report_path="${current_worktree_root}\\docs\\generated\\higher_dimensional_training_maps\\phase6c_dedicated_family_package_validation_report.json"
|
|
local browser_report_remote_path="${current_worktree_root}\\UnrealHyperTwist\\Saved\\AutomationReports\\${browser_report_name}\\index.json"
|
|
local package_report_remote_path="$current_validation_report_path"
|
|
local current_package_script_path="${current_worktree_root}\\scripts\\Invoke-HyperTwistHigherDimensionalPackage.ps1"
|
|
local current_package_archive_dir="$package_archive_dir"
|
|
local current_game_target_receipt_path="${current_worktree_root}\\UnrealHyperTwist\\Binaries\\Win64\\UnrealHyperTwist.target"
|
|
local package_skip_build_clause=""
|
|
local pre_package_editor_build_ps_bool='$false'
|
|
local pre_package_editor_build_result='not-run'
|
|
local step_exit=0
|
|
|
|
if [[ "$current_worktree_root" != "$worktree_root" && "$package_archive_dir" == "${worktree_root}_packaged_phase6c_higherdim_refresh_${report_stamp}" ]]; then
|
|
current_package_archive_dir="${current_worktree_root}_packaged_phase6c_higherdim_refresh_${report_stamp}"
|
|
fi
|
|
|
|
echo "Re-proving remote Windows lane through ${current_worktree_root}."
|
|
if run_or_print "$remote_ps_wrapper" --command "$host_probe_command"; then
|
|
:
|
|
else
|
|
step_exit="$?"
|
|
return "$step_exit"
|
|
fi
|
|
|
|
if [[ ${#effective_sync_files[@]} -gt 0 ]]; then
|
|
echo "Syncing ${#effective_sync_files[@]} repo-relative exact-source support file(s) into ${current_worktree_root}."
|
|
local sync_command=("$remote_sync_wrapper")
|
|
local sync_file
|
|
for sync_file in "${effective_sync_files[@]}"; do
|
|
sync_command+=(--file "$sync_file")
|
|
done
|
|
sync_command+=(--remote-root "$current_worktree_root")
|
|
if run_or_print "${sync_command[@]}"; then
|
|
:
|
|
else
|
|
step_exit="$?"
|
|
return "$step_exit"
|
|
fi
|
|
fi
|
|
|
|
if [[ "$skip_build" != "true" ]]; then
|
|
echo "Running remote Unreal editor build."
|
|
if run_or_print "$remote_build_wrapper" --worktree-root "$current_worktree_root"; then
|
|
pre_package_editor_build_ps_bool='$true'
|
|
pre_package_editor_build_result='passed'
|
|
:
|
|
else
|
|
step_exit="$?"
|
|
return "$step_exit"
|
|
fi
|
|
fi
|
|
|
|
if [[ "$skip_browser_automation" != "true" ]]; then
|
|
echo "Running remote browser automation refresh (~10-20s once the editor lane is warm)."
|
|
if run_or_print \
|
|
env HYPERTWIST_REMOTE_WINDOWS_WORKTREE_ROOT="$current_worktree_root" \
|
|
"$remote_automation_wrapper" \
|
|
--filter "$browser_filter" \
|
|
--report-name "$browser_report_name"
|
|
then
|
|
:
|
|
else
|
|
step_exit="$?"
|
|
return "$step_exit"
|
|
fi
|
|
fi
|
|
|
|
if [[ "$skip_package" != "true" ]]; then
|
|
echo "Running remote higher-dimensional package refresh (~1-3m on the maintained lane)."
|
|
if [[ "$dry_run" == "true" ]]; then
|
|
echo "Dry run: package helper would auto-detect whether ${current_game_target_receipt_path} exists before deciding on -SkipBuild."
|
|
else
|
|
local package_skip_build_probe_output
|
|
if package_skip_build_probe_output="$(
|
|
"$remote_ps_wrapper" --command "\$GameTargetReceiptPath = $(ps_single_quote "$current_game_target_receipt_path"); Write-Output ('PACKAGE_SKIP_BUILD=' + (Test-Path -LiteralPath \$GameTargetReceiptPath).ToString().ToLowerInvariant())" \
|
|
| tr -d '\r'
|
|
)"; then
|
|
:
|
|
else
|
|
step_exit="$?"
|
|
return "$step_exit"
|
|
fi
|
|
if printf '%s\n' "$package_skip_build_probe_output" | grep -Fq 'PACKAGE_SKIP_BUILD=true'; then
|
|
package_skip_build_clause=" -SkipBuild"
|
|
echo "Package helper will reuse the existing Win64 game target receipt."
|
|
else
|
|
echo "Package helper will rebuild the Win64 game target because the packaged-game receipt is absent."
|
|
fi
|
|
fi
|
|
local package_command
|
|
package_command="$(
|
|
cat <<EOF
|
|
\$ProjectRoot = $(ps_single_quote "$current_worktree_root")
|
|
\$ArchiveDirectory = $(ps_single_quote "$current_package_archive_dir")
|
|
\$PackageScriptPath = $(ps_single_quote "$current_package_script_path")
|
|
\$ValidationReportPath = $(ps_single_quote "$current_validation_report_path")
|
|
\$PrePackageEditorBuildPerformed = ${pre_package_editor_build_ps_bool}
|
|
\$PrePackageEditorBuildResult = $(ps_single_quote "$pre_package_editor_build_result")
|
|
if (-not (Test-Path -LiteralPath \$PackageScriptPath)) {
|
|
throw "Higher-dimensional package script was not found at '\$PackageScriptPath'."
|
|
}
|
|
& \$PackageScriptPath -ProjectRoot \$ProjectRoot -ArchiveDirectory \$ArchiveDirectory -ValidationReportPath \$ValidationReportPath -PrePackageEditorBuildPerformed:\$PrePackageEditorBuildPerformed -PrePackageEditorBuildResult \$PrePackageEditorBuildResult${package_skip_build_clause}
|
|
exit \$LASTEXITCODE
|
|
EOF
|
|
)"
|
|
if run_or_print "$remote_ps_wrapper" --command "$package_command"; then
|
|
:
|
|
else
|
|
step_exit="$?"
|
|
return "$step_exit"
|
|
fi
|
|
fi
|
|
|
|
if [[ "$skip_browser_automation" != "true" && "$skip_browser_report_pull" != "true" ]]; then
|
|
echo "Pulling remote browser automation index.json back into docs/generated."
|
|
if run_or_print \
|
|
"$remote_pull_wrapper" \
|
|
--map "${browser_report_remote_path}::${browser_report_local_path}"
|
|
then
|
|
:
|
|
else
|
|
step_exit="$?"
|
|
return "$step_exit"
|
|
fi
|
|
fi
|
|
|
|
if [[ "$skip_package" != "true" && "$skip_package_report_pull" != "true" ]]; then
|
|
echo "Pulling remote higher-dimensional package report back into docs/generated."
|
|
if run_or_print \
|
|
"$remote_pull_wrapper" \
|
|
--map "${package_report_remote_path}::${package_report_local_path}"
|
|
then
|
|
:
|
|
else
|
|
step_exit="$?"
|
|
return "$step_exit"
|
|
fi
|
|
fi
|
|
|
|
if [[ "$skip_package" != "true" && "$skip_package_report_pull" != "true" && "$skip_summary_refresh" != "true" ]]; then
|
|
echo "Refreshing the checked-in website package-validation summary."
|
|
if run_or_print node "$summary_refresh_script"; then
|
|
:
|
|
else
|
|
step_exit="$?"
|
|
return "$step_exit"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
active_worktree_root="$worktree_root"
|
|
if run_refresh_for_root "$worktree_root"; then
|
|
:
|
|
else
|
|
primary_exit="$?"
|
|
if [[ -n "$fallback_worktree_root" ]]; then
|
|
echo "Primary remote refresh failed on ${worktree_root}. Falling back to ${fallback_worktree_root}." >&2
|
|
run_refresh_for_root "$fallback_worktree_root"
|
|
active_worktree_root="$fallback_worktree_root"
|
|
else
|
|
exit "$primary_exit"
|
|
fi
|
|
fi
|
|
|
|
echo "Remote exact-source browser/package refresh complete through ${active_worktree_root}."
|