Skip to content

Commit 617e1e8

Browse files
committed
Fix integration changelog registry coverage
1 parent cf3bcee commit 617e1e8

3 files changed

Lines changed: 119 additions & 11 deletions

File tree

hindsight-dev/hindsight_dev/generate_changelog.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class IntegrationMeta:
4242
"pydantic-ai": IntegrationMeta("hindsight-pydantic-ai", "Pydantic AI"),
4343
"crewai": IntegrationMeta("hindsight-crewai", "CrewAI"),
4444
"agent-framework": IntegrationMeta("hindsight-agent-framework", "Microsoft Agent Framework"),
45+
"agno": IntegrationMeta("hindsight-agno", "Agno"),
4546
"ag2": IntegrationMeta("hindsight-ag2"),
4647
"ai-sdk": IntegrationMeta("@vectorize-io/hindsight-ai-sdk", "AI SDK"),
4748
"chat": IntegrationMeta("@vectorize-io/hindsight-chat", "Chat SDK"),
@@ -76,6 +77,7 @@ class IntegrationMeta:
7677
"roo-code": IntegrationMeta("hindsight-roo-code", "Roo Code"),
7778
"omo": IntegrationMeta("hindsight-omo", "OMO"),
7879
"composio": IntegrationMeta("hindsight-composio", "Composio"),
80+
"continue": IntegrationMeta("hindsight-continue", "Continue"),
7981
}
8082

8183
VALID_INTEGRATIONS = list(INTEGRATIONS.keys())
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
"""Regression tests for integration changelog registry coverage."""
2+
3+
import subprocess
4+
import tomllib
5+
from pathlib import Path
6+
7+
from hindsight_dev.generate_changelog import INTEGRATIONS
8+
9+
REPO_ROOT = Path(__file__).resolve().parents[2]
10+
RELEASE_SCRIPT = REPO_ROOT / "scripts" / "release-integration.sh"
11+
NEW_PYTHON_INTEGRATIONS = {"agno", "continue"}
12+
13+
14+
def _release_script_integrations():
15+
result = subprocess.run(
16+
["bash", str(RELEASE_SCRIPT), "--list-integrations"],
17+
check=True,
18+
capture_output=True,
19+
cwd=REPO_ROOT,
20+
text=True,
21+
)
22+
return result.stdout.splitlines()
23+
24+
25+
def _validate_release_path(slug):
26+
subprocess.run(
27+
["bash", str(RELEASE_SCRIPT), "--validate-only", slug, "patch"],
28+
check=True,
29+
capture_output=True,
30+
cwd=REPO_ROOT,
31+
text=True,
32+
)
33+
34+
35+
def test_release_script_integrations_match_changelog_metadata():
36+
release_integrations = _release_script_integrations()
37+
38+
assert len(release_integrations) == len(set(release_integrations))
39+
assert set(release_integrations) == set(INTEGRATIONS)
40+
41+
42+
def test_python_integration_metadata_matches_package_manifests():
43+
pyproject_slugs = {path.parent.name for path in (REPO_ROOT / "hindsight-integrations").glob("*/pyproject.toml")}
44+
assert NEW_PYTHON_INTEGRATIONS <= pyproject_slugs
45+
46+
for slug, meta in INTEGRATIONS.items():
47+
pyproject = REPO_ROOT / "hindsight-integrations" / slug / "pyproject.toml"
48+
if not pyproject.exists():
49+
continue
50+
manifest = tomllib.loads(pyproject.read_text())
51+
52+
assert meta.package_name == manifest["project"]["name"]
53+
54+
55+
def test_new_integration_display_names_match_user_facing_brands():
56+
assert INTEGRATIONS["agno"].display_name == "Agno"
57+
assert INTEGRATIONS["continue"].display_name == "Continue"
58+
59+
60+
def test_new_integration_release_paths_validate_before_mutation():
61+
for slug in NEW_PYTHON_INTEGRATIONS:
62+
_validate_release_path(slug)

scripts/release-integration.sh

Lines changed: 55 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,17 @@ usage() {
2828
exit 1
2929
}
3030

31+
if [ "${1:-}" = "--list-integrations" ] && [ "$#" -eq 1 ]; then
32+
printf "%s\n" "${VALID_INTEGRATIONS[@]}"
33+
exit 0
34+
fi
35+
36+
VALIDATE_ONLY=false
37+
if [ "${1:-}" = "--validate-only" ]; then
38+
VALIDATE_ONLY=true
39+
shift
40+
fi
41+
3142
if [ -z "$1" ] || [ -z "$2" ]; then
3243
usage
3344
fi
@@ -77,6 +88,23 @@ bump_version() {
7788
esac
7889
}
7990

91+
validate_manifest_version_field() {
92+
local manifest=$1
93+
local matches
94+
if [[ "$manifest" == */pyproject.toml ]]; then
95+
matches=$(grep -Ec '^version = "[^"]+"$' "$manifest" || true)
96+
elif [[ "$manifest" == */package.json ]] || [[ "$manifest" == */plugin.json ]] || [[ "$manifest" == */settings.json ]]; then
97+
matches=$(grep -Ec '"version": "[^"]+"' "$manifest" || true)
98+
else
99+
matches=0
100+
fi
101+
102+
if [ "$matches" -ne 1 ]; then
103+
print_error "Expected exactly one release version field in $manifest, found $matches"
104+
exit 1
105+
fi
106+
}
107+
80108
# Resolve version: either an explicit semver or a bump keyword
81109
if [[ "$VERSION_ARG" =~ ^(patch|minor|major)$ ]]; then
82110
CURRENT_VERSION=$(get_current_version)
@@ -95,6 +123,33 @@ fi
95123

96124
TAG="integrations/$INTEGRATION/v$VERSION"
97125

126+
INTEGRATION_DIR="hindsight-integrations/$INTEGRATION"
127+
128+
if [ ! -d "$INTEGRATION_DIR" ]; then
129+
print_error "Integration directory not found: $INTEGRATION_DIR"
130+
exit 1
131+
fi
132+
133+
if [ -f "$INTEGRATION_DIR/pyproject.toml" ]; then
134+
MANIFEST_PATH="$INTEGRATION_DIR/pyproject.toml"
135+
elif [ -f "$INTEGRATION_DIR/package.json" ]; then
136+
MANIFEST_PATH="$INTEGRATION_DIR/package.json"
137+
elif [ -f "$INTEGRATION_DIR/.claude-plugin/plugin.json" ]; then
138+
MANIFEST_PATH="$INTEGRATION_DIR/.claude-plugin/plugin.json"
139+
elif [ -f "$INTEGRATION_DIR/settings.json" ] && grep -q '"version"' "$INTEGRATION_DIR/settings.json"; then
140+
MANIFEST_PATH="$INTEGRATION_DIR/settings.json"
141+
else
142+
print_error "No pyproject.toml, package.json, plugin.json, or versioned settings.json found in $INTEGRATION_DIR"
143+
exit 1
144+
fi
145+
146+
validate_manifest_version_field "$MANIFEST_PATH"
147+
148+
if [ "$VALIDATE_ONLY" = true ]; then
149+
print_info "Validated $INTEGRATION release path via $MANIFEST_PATH"
150+
exit 0
151+
fi
152+
98153
print_info "Releasing $INTEGRATION v$VERSION (tag: $TAG)"
99154

100155
# Check if we're on main branch
@@ -135,14 +190,6 @@ if [ -z "$OPENAI_API_KEY" ]; then
135190
exit 1
136191
fi
137192

138-
# Determine integration type and update version
139-
INTEGRATION_DIR="hindsight-integrations/$INTEGRATION"
140-
141-
if [ ! -d "$INTEGRATION_DIR" ]; then
142-
print_error "Integration directory not found: $INTEGRATION_DIR"
143-
exit 1
144-
fi
145-
146193
if [ -f "$INTEGRATION_DIR/pyproject.toml" ]; then
147194
print_info "Updating version in $INTEGRATION_DIR/pyproject.toml"
148195
sed -i.bak "s/^version = \".*\"/version = \"$VERSION\"/" "$INTEGRATION_DIR/pyproject.toml"
@@ -159,9 +206,6 @@ elif [ -f "$INTEGRATION_DIR/settings.json" ] && grep -q '"version"' "$INTEGRATIO
159206
print_info "Updating version in $INTEGRATION_DIR/settings.json"
160207
sed -i.bak "s/\"version\": \".*\"/\"version\": \"$VERSION\"/" "$INTEGRATION_DIR/settings.json"
161208
rm "$INTEGRATION_DIR/settings.json.bak"
162-
else
163-
print_error "No pyproject.toml, package.json, plugin.json, or versioned settings.json found in $INTEGRATION_DIR"
164-
exit 1
165209
fi
166210

167211
# Generate changelog entry using LLM

0 commit comments

Comments
 (0)