fix(e2e): escape Windows stale update import regex (#75315) thanks @steipete

Fix the Windows stale-import guard regex used by the Parallels npm update smoke path, with related maintainer-flow and regression-test cleanup preserved on a verified branch.
This commit is contained in:
clawsweeper[bot]
2026-05-02 19:10:44 -05:00
committed by GitHub
parent f30dc0aeb4
commit afe42fc977
11 changed files with 220 additions and 55 deletions

View File

@@ -17,6 +17,8 @@ export interface NpmUpdateScriptInput {
updateTarget: string;
}
const windowsStalePostSwapImportRegex = String.raw`node_modules\\openclaw\\dist\\[^\\]+-[A-Za-z0-9_-]+\.js`;
function posixModelProviderConfigCommands(
command: string,
modelId: string,
@@ -180,7 +182,7 @@ $updateExit = $LASTEXITCODE
$updateOutput
if ($updateExit -ne 0) {
$updateText = $updateOutput | Out-String
$stalePostSwapImport = $updateText -match 'ERR_MODULE_NOT_FOUND' -and $updateText -match 'node_modules\\openclaw\\dist\\[^\\]+-[A-Za-z0-9_-]+\\.js'
$stalePostSwapImport = $updateText -match 'ERR_MODULE_NOT_FOUND' -and $updateText -match ${psSingleQuote(windowsStalePostSwapImportRegex)}
if (-not $stalePostSwapImport) { throw "openclaw update failed with exit code $updateExit" }
Write-Host "openclaw update returned a stale post-swap module import; continuing to post-update health checks"
}

View File

@@ -159,6 +159,20 @@ validate_changelog_attribution_policy() {
node scripts/check-changelog-attributions.mjs CHANGELOG.md
}
changelog_thanks_required_for_contributor() {
local contrib="${1:-}"
local normalized
normalized=$(printf '%s' "$contrib" | tr '[:upper:]' '[:lower:]')
case "$normalized" in
""|"null"|"app/"*|"codex"|"openclaw"|"clawsweeper"|"openclaw-clawsweeper"|"clawsweeper[bot]"|"openclaw-clawsweeper[bot]"|"steipete")
return 1
;;
esac
return 0
}
validate_changelog_entry_for_pr() {
local pr="$1"
local contrib="$2"
@@ -314,7 +328,7 @@ END {
rm -f "$diff_file"
echo "changelog placement validated: PR-linked entries are appended at section tail"
if [ -n "$contrib" ] && [ "$contrib" != "null" ]; then
if changelog_thanks_required_for_contributor "$contrib"; then
local with_pr_and_thanks
with_pr_and_thanks=$(printf '%s\n' "$added_lines" | rg -in "$pr_pattern" | rg -i "thanks @$contrib" || true)
if [ -z "$with_pr_and_thanks" ]; then
@@ -325,7 +339,7 @@ END {
return 0
fi
echo "changelog validated: found PR #$pr (contributor handle unavailable, skipping thanks check)"
echo "changelog validated: found PR #$pr (no eligible human contributor handle, skipping thanks check)"
}
validate_changelog_merge_hygiene() {

View File

@@ -191,6 +191,32 @@ merge_author_email_candidates() {
"${reviewer}@users.noreply.github.com" | awk 'NF && !seen[$0]++'
}
pr_contributor_allows_human_trailers() {
local contrib="${1:-}"
local normalized
normalized=$(printf '%s' "$contrib" | tr '[:upper:]' '[:lower:]')
case "$normalized" in
""|"null"|"app/"*|"codex"|"openclaw"|"clawsweeper"|"openclaw-clawsweeper"|"clawsweeper[bot]"|"openclaw-clawsweeper[bot]"|"steipete")
return 1
;;
esac
return 0
}
resolve_contributor_coauthor_email() {
local contrib="${1:-}"
if ! pr_contributor_allows_human_trailers "$contrib"; then
return 1
fi
local contrib_id
contrib_id=$(gh api "users/$contrib" --jq .id) || return 1
printf '%s+%s@users.noreply.github.com\n' "$contrib_id" "$contrib"
}
common_repo_root() {
if command -v repo_root >/dev/null 2>&1; then
repo_root

View File

@@ -199,9 +199,11 @@ merge_run() {
local contrib_coauthor_email="${COAUTHOR_EMAIL:-}"
if [ -z "$contrib_coauthor_email" ] || [ "$contrib_coauthor_email" = "null" ]; then
local contrib_id
contrib_id=$(gh api "users/$contrib" --jq .id)
contrib_coauthor_email="${contrib_id}+${contrib}@users.noreply.github.com"
if contrib_coauthor_email=$(resolve_contributor_coauthor_email "$contrib"); then
:
else
contrib_coauthor_email=""
fi
fi
local reviewer_email_candidates=()
@@ -218,14 +220,16 @@ merge_run() {
local reviewer_email="${reviewer_email_candidates[0]}"
local reviewer_coauthor_email="${reviewer_id}+${reviewer}@users.noreply.github.com"
cat > .local/merge-body.txt <<EOF_BODY
Merged via squash.
Prepared head SHA: $PREP_HEAD_SHA
Co-authored-by: $contrib <$contrib_coauthor_email>
Co-authored-by: $reviewer <$reviewer_coauthor_email>
Reviewed-by: @$reviewer
EOF_BODY
{
echo "Merged via squash."
echo
echo "Prepared head SHA: $PREP_HEAD_SHA"
if [ -n "$contrib_coauthor_email" ]; then
echo "Co-authored-by: $contrib <$contrib_coauthor_email>"
fi
echo "Co-authored-by: $reviewer <$reviewer_coauthor_email>"
echo "Reviewed-by: @$reviewer"
} > .local/merge-body.txt
delete_remote_pr_head_branch_after_merge() {
local head_json
@@ -347,22 +351,29 @@ EOF_BODY
local commit_body
commit_body=$(gh api repos/:owner/:repo/commits/"$merge_sha" --jq .commit.message)
printf '%s\n' "$commit_body" | rg -q "^Co-authored-by: $contrib <" || { echo "Missing PR author co-author trailer"; exit 1; }
if [ -n "$contrib_coauthor_email" ]; then
printf '%s\n' "$commit_body" | rg -q "^Co-authored-by: $contrib <" || { echo "Missing PR author co-author trailer"; exit 1; }
else
echo "Skipping PR author co-author trailer check for bot/app author $contrib."
fi
printf '%s\n' "$commit_body" | rg -q "^Co-authored-by: $reviewer <" || { echo "Missing reviewer co-author trailer"; exit 1; }
local ok=0
local comment_output=""
local attempt
for attempt in 1 2 3; do
if comment_output=$(gh pr comment "$pr" -F - 2>&1 <<EOF_COMMENT
Merged via squash.
- Prepared head SHA: [$PREP_HEAD_SHA]($prep_sha_url)
- Merge commit: [$merge_sha]($merge_sha_url)
Thanks @$contrib!
EOF_COMMENT
); then
if comment_output=$(
{
echo "Merged via squash."
echo
echo "- Prepared head SHA: [$PREP_HEAD_SHA]($prep_sha_url)"
echo "- Merge commit: [$merge_sha]($merge_sha_url)"
if pr_contributor_allows_human_trailers "$contrib"; then
echo
echo "Thanks @$contrib!"
fi
} | gh pr comment "$pr" -F - 2>&1
); then
ok=1
break
fi

View File

@@ -163,9 +163,12 @@ prepare_push() {
if [ -z "$contrib" ]; then
contrib=$(gh pr view "$pr" --json author --jq .author.login)
fi
local contrib_id
contrib_id=$(gh api "users/$contrib" --jq .id)
local coauthor_email="${contrib_id}+${contrib}@users.noreply.github.com"
local coauthor_email=""
if coauthor_email=$(resolve_contributor_coauthor_email "$contrib"); then
:
else
coauthor_email=""
fi
cat >> .local/prep.md <<EOF_PREP
- Gates passed and push succeeded to branch $PR_HEAD.
@@ -237,9 +240,12 @@ prepare_sync_head() {
if [ -z "$contrib" ]; then
contrib=$(gh pr view "$pr" --json author --jq .author.login)
fi
local contrib_id
contrib_id=$(gh api "users/$contrib" --jq .id)
local coauthor_email="${contrib_id}+${contrib}@users.noreply.github.com"
local coauthor_email=""
if coauthor_email=$(resolve_contributor_coauthor_email "$contrib"); then
:
else
coauthor_email=""
fi
cat >> .local/prep.md <<EOF_PREP
- Prep head sync completed to branch $PR_HEAD.

View File

@@ -112,14 +112,20 @@ fi
# Default scan paths match CI. Override by passing `-- <paths...>`.
if (( PATHS_PASSED == 0 )); then
if (( CHANGED_ONLY )); then
mapfile -t SCAN_PATHS < <(
SCAN_PATHS=()
while IFS= read -r path; do
SCAN_PATHS+=( "$path" )
done < <(
{
git diff --name-only --diff-filter=ACMRTUXB "${OPENCLAW_OPENGREP_BASE_REF:-origin/main...HEAD}" 2>/dev/null || true
git diff --name-only --diff-filter=ACMRTUXB -- 2>/dev/null || true
git ls-files --others --exclude-standard
} | awk '/^(src|extensions|apps|packages|scripts)\// { print }' | sort -u
)
mapfile -t RULEPACK_CHANGED_PATHS < <(
RULEPACK_CHANGED_PATHS=()
while IFS= read -r path; do
RULEPACK_CHANGED_PATHS+=( "$path" )
done < <(
{
git diff --name-only --diff-filter=ACMRTUXB "${OPENCLAW_OPENGREP_BASE_REF:-origin/main...HEAD}" 2>/dev/null || true
git diff --name-only --diff-filter=ACMRTUXB -- 2>/dev/null || true
@@ -148,9 +154,11 @@ fi
echo "→ Running opengrep ($BUCKET) against $(IFS=' '; echo "${SCAN_PATHS[*]:-overridden}")" >&2
echo " Using exclusions from .semgrepignore" >&2
exec opengrep scan \
--no-strict \
--config "$CONFIG" \
--no-git-ignore \
"${EXTRA_ARGS[@]}" \
"${SCAN_PATHS[@]}"
OPENGREP_ARGS=( scan --no-strict --config "$CONFIG" --no-git-ignore )
if (( ${#EXTRA_ARGS[@]} > 0 )); then
OPENGREP_ARGS+=( "${EXTRA_ARGS[@]}" )
fi
if (( ${#SCAN_PATHS[@]} > 0 )); then
OPENGREP_ARGS+=( "${SCAN_PATHS[@]}" )
fi
exec opengrep "${OPENGREP_ARGS[@]}"