Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .claude/hooks/check-comment-line-breaks.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/bin/bash
# PostToolUse on Edit|Write|MultiEdit: reject hard-wrapped comments per CLAUDE.md.
# Blocks Claude (decision:block) when a single sentence is broken across multiple # lines so Claude rewrites before continuing.

REPO_ROOT=$(cd "$(dirname "$0")/../.." && pwd)

INPUT=$(cat)
FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // ""')

case "$FILE" in
"$REPO_ROOT"/*.py) ;;
*) exit 0 ;;
esac

case "$FILE" in
*/.venv/*|*/venv/*) exit 0 ;;
esac

OUTPUT=$(python3 "$REPO_ROOT/scripts/lint/check_comment_line_breaks.py" "$FILE" 2>&1)
STATUS=$?
if [ $STATUS -eq 0 ]; then
exit 0
fi

jq -n --arg reason "BLOCKED: Hard-wrapped comments per CLAUDE.md. Rewrite as one line per sentence (let the editor wrap visually):
$OUTPUT" '{decision: "block", reason: $reason}'
exit 2
5 changes: 5 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@
"type": "command",
"command": "/Users/rwest/Repositories/gitauto/.claude/hooks/check-logger-coverage.sh",
"timeout": 15
},
{
"type": "command",
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/check-comment-line-breaks.sh",
"timeout": 10
}
]
}
Expand Down
1 change: 1 addition & 0 deletions constants/mongoms.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Default MongoDB server versions that mongodb-memory-server downloads when no version is specified in package.json config.
# Must match upstream so GA tests against the same MongoDB the customer's CI does.
# https://github.com/typegoose/mongodb-memory-server/blob/master/packages/mongodb-memory-server-core/src/util/resolve-config.ts
MONGOMS_MAJOR_TO_MONGODB_VERSION: dict[int, str] = {
7: "6.0.9",
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "GitAuto"
version = "1.55.3"
version = "1.55.4"
requires-python = ">=3.14"
dependencies = [
"annotated-doc==0.0.4",
Expand Down
11 changes: 11 additions & 0 deletions scripts/git/pre_commit_hook.sh
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,17 @@ echo "--- cast usage check ---"
scripts/lint/check_cast_usage.sh
if [ $? -ne 0 ]; then exit 1; fi

# Comment line-break check (don't hard-wrap single sentences across # lines)
echo "--- comment line-break check ---"
if [ -n "$STAGED_PY_FILES" ]; then
# shellcheck disable=SC2086
python3 scripts/lint/check_comment_line_breaks.py $STAGED_PY_FILES
if [ $? -ne 0 ]; then
echo "FAILED: Rewrite hard-wrapped comments as one line per sentence."
exit 1
fi
fi

# Concurrent heavy checks (pylint, pyright, pytest)
echo "--- pylint + pyright + pytest (concurrent) ---"
scripts/lint/pre_commit_parallel_checks.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module.exports = {
mongodbMemoryServerOptions: {
binary: {
version: 'v8.0-latest',
skipMD5: true,
},
instance: {
dbName: 'jest',
},
autoStart: true,
},
mongoURLEnvName: 'JEST_MONGODB_URI',
};
12 changes: 8 additions & 4 deletions services/mongoms/get_distro_for_mongodb_server_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@

@handle_exceptions(default_return_value="amazon2023", raise_on_error=False)
def get_distro_for_mongodb_server_version(mongodb_server_version: str):
"""Return the correct Amazon Linux distro name for a MongoDB server version.
MongoDB 7.0+ has amazon2023 builds. 6.0.x and earlier only have amazon2."""
"""Return a distro name whose MongoDB binary runs on our AL2023 Lambda.
MongoDB 7.0+ has amazon2023 builds — use those.
MongoDB 6.0.x has no amazon2023 build, so fall back to rhel90 (RHEL 9 ships glibc 2.34 and OpenSSL 3, same ABI as AL2023).
Using `amazon2` for 6.x produces a binary linked against libcrypto.so.10 (OpenSSL 1.0.x) which AL2023 does not provide — Foxquilt PR #203 run (CloudWatch 2026-04-21 14:01:55) crashed with exactly this error.
"""
# Extract major.minor from version strings like "v7.0-latest", "7.0.11", "6.0.14"
cleaned = mongodb_server_version.lstrip("v")
major_str = cleaned.split(".")[0]
Expand All @@ -26,6 +29,7 @@ def get_distro_for_mongodb_server_version(mongodb_server_version: str):
return "amazon2023"

logger.info(
"get_distro_for_mongodb_server_version: MongoDB %s.x uses amazon2 distro", major
"get_distro_for_mongodb_server_version: MongoDB %s.x uses rhel90 distro (no amazon2023 build exists for 6.x; rhel90 shares glibc+OpenSSL ABI with AL2023)",
major,
)
return "amazon2"
return "rhel90"
47 changes: 46 additions & 1 deletion services/mongoms/get_mongodb_server_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,26 @@
from utils.files.read_local_file import read_local_file
from utils.logging.logging_config import logger

# `@shelf/jest-mongodb` reads its settings from one of these files at the repo root.
# Order matters: the first one present wins (same order as the upstream library).
JEST_MONGODB_CONFIG_FILENAMES = (
"jest-mongodb-config.js",
"jest-mongodb-config.cjs",
"jest-mongodb-config.ts",
)

# Matches e.g. `binary: { version: 'v8.0-latest', ... }` or the same with double quotes.
# Kept permissive for whitespace/newlines inside the `binary` object so it tolerates typical formatter output.
_BINARY_VERSION_RE = re.compile(
r"binary\s*:\s*\{[^{}]*?version\s*:\s*['\"]([^'\"]+)['\"]",
re.DOTALL,
)


@handle_exceptions(default_return_value=None, raise_on_error=False)
def get_mongodb_server_version(clone_dir: str):
"""Detect MongoDB version from package.json config or scripts. Returns e.g. 'v7.0-latest' or None."""
"""Detect MongoDB version from package.json config, scripts, or jest-mongodb-config.
Returns e.g. 'v7.0-latest' or None."""
pkg_content = read_local_file("package.json", clone_dir)
if not pkg_content:
logger.info(
Expand All @@ -24,8 +40,12 @@ def get_mongodb_server_version(clone_dir: str):
# config.mongodbMemoryServer.version first
config = pkg.get("config")
if isinstance(config, dict):
logger.info("get_mongodb_server_version: checking config.mongodbMemoryServer")
mongoms_config = config.get("mongodbMemoryServer")
if isinstance(mongoms_config, dict):
logger.info(
"get_mongodb_server_version: checking config.mongodbMemoryServer.version"
)
version = mongoms_config.get("version")
if isinstance(version, str):
logger.info(
Expand All @@ -40,6 +60,7 @@ def get_mongodb_server_version(clone_dir: str):
)
scripts = pkg.get("scripts")
if isinstance(scripts, dict):
logger.info("get_mongodb_server_version: scanning scripts for MONGOMS_VERSION")
for script in scripts.values():
match = re.search(r"MONGOMS_VERSION=(\S+)", str(script))
if match:
Expand All @@ -49,5 +70,29 @@ def get_mongodb_server_version(clone_dir: str):
)
return match.group(1)

# Fall back to @shelf/jest-mongodb config file at the repo root.
# Example: `mongodbMemoryServerOptions: { binary: { version: 'v8.0-latest' } }`
logger.info(
"get_mongodb_server_version: no MONGOMS_VERSION in scripts, checking jest-mongodb config"
)
for filename in JEST_MONGODB_CONFIG_FILENAMES:
config_content = read_local_file(filename, clone_dir)
if not config_content:
logger.info("get_mongodb_server_version: %s not found", filename)
continue
match = _BINARY_VERSION_RE.search(config_content)
if match:
logger.info(
"get_mongodb_server_version: found binary.version=%s in %s",
match.group(1),
filename,
)
return match.group(1)

logger.info(
"get_mongodb_server_version: %s present but no binary.version pattern matched",
filename,
)

logger.info("get_mongodb_server_version: no MongoDB version detected")
return None
114 changes: 108 additions & 6 deletions services/mongoms/test_get_archive_name.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
# pyright: reportUnusedVariable=false
from unittest.mock import patch

import pytest

from services.mongoms.get_archive_name import get_mongoms_archive_name


Expand Down Expand Up @@ -50,11 +52,13 @@ def test_mongoms_10x_with_explicit_7x_version(_mock_major, _mock_version):
"services.mongoms.get_archive_name.get_mongodb_server_version", return_value=None
)
@patch("services.mongoms.get_archive_name.get_dependency_major_version", return_value=9)
def test_mongoms_9x_no_explicit_version_uses_default(_mock_major, _mock_version):
"""mongoms 9.x with no explicit version falls back to default 6.0.9 with amazon2 distro."""
def test_mongoms_9x_no_explicit_version_uses_rhel90_distro(_mock_major, _mock_version):
"""mongoms 9.x with no explicit version stays on upstream's MongoDB 6.0.9 default — GA must test the same version the customer's CI does.
The broken archive was `amazon2-6.0.9` (libcrypto.so.10, not on AL2023). `rhel90-6.0.9` shares AL2023's glibc + OpenSSL 3 ABI and actually runs on Lambda.
"""
assert (
get_mongoms_archive_name("/tmp/clone")
== "mongodb-linux-x86_64-amazon2-6.0.9.tgz"
== "mongodb-linux-x86_64-rhel90-6.0.9.tgz"
)


Expand All @@ -76,11 +80,11 @@ def test_mongoms_10x_no_explicit_version_uses_default(_mock_major, _mock_version
"services.mongoms.get_archive_name.get_mongodb_server_version", return_value=None
)
@patch("services.mongoms.get_archive_name.get_dependency_major_version", return_value=7)
def test_mongoms_7x_no_explicit_version_uses_default(_mock_major, _mock_version):
"""mongoms 7.x with no explicit version falls back to default 6.0.9 with amazon2 distro."""
def test_mongoms_7x_no_explicit_version_uses_rhel90_distro(_mock_major, _mock_version):
"""mongoms 7.x with no explicit version: same rationale as the 9.x case — upstream default 6.0.9 with rhel90 distro so the binary actually runs on AL2023."""
assert (
get_mongoms_archive_name("/tmp/clone")
== "mongodb-linux-x86_64-amazon2-6.0.9.tgz"
== "mongodb-linux-x86_64-rhel90-6.0.9.tgz"
)


Expand Down Expand Up @@ -113,3 +117,101 @@ def test_mongoms_old_version_returns_none(_mock_major, _mock_version):
def test_no_mongoms_in_package_json(_mock_major):
"""mongodb-memory-server not in package.json."""
assert get_mongoms_archive_name("/tmp/clone") is None


# Snapshot of every Foxquilt repo at /Users/rwest/Repositories/Foxquilt on 2026-04-21.
# Columns: mongoms major (from direct dep or transitive via @shelf/jest-mongodb in yarn.lock), explicit MongoDB version detected by get_mongodb_server_version (package.json script MONGOMS_VERSION= OR jest-mongodb-config.js binary.version), and the archive name get_mongoms_archive_name must produce post-fix.
# `None` for mongoms_major means the repo doesn't use Mongo at all; the expected archive is `None` (no pre-cache needed).
# Every Mongo-using repo must resolve to a distro in AL2023_COMPATIBLE_DISTROS. `amazon2` would crash our Lambda with libcrypto.so.10 missing.
FOXQUILT_REPO_CASES = [
("foxcom-forms", None, None, None),
(
"foxcom-forms-backend",
7,
"v7.0-latest",
"mongodb-linux-x86_64-amazon2023-v7.0-latest.tgz",
),
(
"foxcom-payment-backend",
7,
"v7.0-latest",
"mongodb-linux-x86_64-amazon2023-v7.0-latest.tgz",
),
("foxcom-payment-frontend", None, None, None),
("foxden-admin-portal", None, None, None),
(
"foxden-admin-portal-backend",
9,
"v7.0-latest",
"mongodb-linux-x86_64-amazon2023-v7.0-latest.tgz",
),
(
"foxden-auth-service",
9,
"v7.0-latest",
"mongodb-linux-x86_64-amazon2023-v7.0-latest.tgz",
),
("foxden-billing", 10, None, "mongodb-linux-x86_64-amazon2023-7.0.11.tgz"),
(
"foxden-policy-document-backend",
9,
"v7.0-latest",
"mongodb-linux-x86_64-amazon2023-v7.0-latest.tgz",
),
(
"foxden-rating-quoting-backend",
9,
"v7.0-latest",
"mongodb-linux-x86_64-amazon2023-v7.0-latest.tgz",
),
# Default path — upstream mongoms 9.x default is 6.0.9 (no amazon2023 build); must fall back to rhel90 which shares AL2023's glibc/OpenSSL ABI.
("foxden-shared-lib", 9, None, "mongodb-linux-x86_64-rhel90-6.0.9.tgz"),
(
"foxden-tools",
9,
"v7.0-latest",
"mongodb-linux-x86_64-amazon2023-v7.0-latest.tgz",
),
(
"foxden-version-controller",
9,
"v8.0-latest",
"mongodb-linux-x86_64-amazon2023-v8.0-latest.tgz",
),
("foxden-version-controller-client", None, None, None),
]

# SONAMEs present on our AL2023 Lambda. Any distro whose binary dynamically links against these runs on Lambda. `amazon2` does not — it wants libcrypto.so.10 (OpenSSL 1.0.x) which AL2023 removed.
AL2023_COMPATIBLE_DISTROS = ("amazon2023", "rhel90")


def test_foxquilt_repo_cases_cover_all_14_repos():
# If Foxquilt adds/removes a repo, update FOXQUILT_REPO_CASES and this number.
assert len(FOXQUILT_REPO_CASES) == 14


@pytest.mark.parametrize(
"repo_name, mongoms_major, explicit_version, expected_archive",
FOXQUILT_REPO_CASES,
ids=[case[0] for case in FOXQUILT_REPO_CASES],
)
def test_every_foxquilt_repo_resolves_to_al2023_archive(
repo_name, mongoms_major, explicit_version, expected_archive
):
with patch(
"services.mongoms.get_archive_name.get_dependency_major_version",
return_value=mongoms_major,
), patch(
"services.mongoms.get_archive_name.get_mongodb_server_version",
return_value=explicit_version,
):
actual = get_mongoms_archive_name(f"/tmp/{repo_name}")
assert (
actual == expected_archive
), f"{repo_name} produced {actual!r}; expected {expected_archive!r}"
if expected_archive is None:
# Non-Mongo repo — nothing to pre-cache, nothing to check for ABI compat.
return
assert actual is not None and any(
d in actual for d in AL2023_COMPATIBLE_DISTROS
), f"{repo_name} produced {actual!r}; expected a distro from {AL2023_COMPATIBLE_DISTROS} so the binary can actually run on AL2023 Lambda"
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@ def test_mongodb_821_returns_amazon2023():
assert get_distro_for_mongodb_server_version("8.2.1") == "amazon2023"


def test_mongodb_609_returns_amazon2():
assert get_distro_for_mongodb_server_version("6.0.9") == "amazon2"
def test_mongodb_609_returns_rhel90():
# MongoDB 6.0.9 has no amazon2023 build. rhel90 shares the glibc 2.34 + OpenSSL 3 ABI with our AL2023 Lambda; amazon2 would pull in libcrypto.so.10 which AL2023 doesn't ship.
assert get_distro_for_mongodb_server_version("6.0.9") == "rhel90"


def test_mongodb_6014_returns_amazon2():
assert get_distro_for_mongodb_server_version("6.0.14") == "amazon2"
def test_mongodb_6014_returns_rhel90():
assert get_distro_for_mongodb_server_version("6.0.14") == "rhel90"


def test_unparseable_version_defaults_to_amazon2023():
Expand Down
Loading
Loading