Skip to content

Commit 316feef

Browse files
authored
feat: breaking changes detection against the backend server (HEXA-1238) (#260)
* v1 * v2 * v3 untested * v3 working * TODO * Fix for deprecated features * Minor * Minor * Fix * Cache * Cache * 2/4 tests * fix * Test 3/4 * Test 4/4 * clean * Fix * Dependency * Dependency * Lint * With command * TODO * Fix * Fix test * Revert "Fix test" This reverts commit d1ee33b. * Revert "Fix" This reverts commit bea9eff. * secho * Rely on settings and not file * Fix 1/2 test * Fix 2/2 test * small fix * update schema
1 parent 825f209 commit 316feef

6 files changed

Lines changed: 4280 additions & 1 deletion

File tree

MANIFEST.in

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
recursive-include openhexa/cli/skeleton *
1+
recursive-include openhexa/cli/skeleton *
2+
recursive-include openhexa/cli/graphql *

openhexa/cli/api.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import os
99
import tempfile
1010
import typing
11+
from datetime import datetime
1112
from importlib.metadata import version
1213
from pathlib import Path
1314
from zipfile import ZipFile
@@ -16,6 +17,8 @@
1617
import docker
1718
import requests
1819
from docker.models.containers import Container
20+
from graphql import build_client_schema, build_schema, get_introspection_query
21+
from graphql.utilities import find_breaking_changes
1922
from jinja2 import Template
2023

2124
from openhexa.cli.settings import settings
@@ -104,7 +107,41 @@ def get_library_versions() -> tuple[str, str]:
104107
return installed_version, installed_version
105108

106109

110+
def detect_graphql_breaking_changes(token):
111+
"""Detect breaking changes between the schema referenced in the SDK and the server using graphql-core."""
112+
stored_schema_obj = build_schema((Path(__file__).parent / "graphql" / "schema.generated.graphql").open().read())
113+
server_schema_obj = build_client_schema(
114+
_query_graphql(get_introspection_query(input_value_deprecation=True), token=token)
115+
)
116+
117+
breaking_changes = find_breaking_changes(stored_schema_obj, server_schema_obj)
118+
if breaking_changes:
119+
current_version, latest_version = get_library_versions()
120+
click.secho(
121+
f"⚠️ Breaking changes detected between the SDK (version {current_version}) and the server:",
122+
fg="red",
123+
)
124+
for change in breaking_changes:
125+
click.secho(f"- {change.description}", fg="yellow")
126+
click.secho(
127+
"This could lead to unexpected results.\n"
128+
f"Please update the SDK to the latest version {latest_version} "
129+
f"(using `pip install openhexa-sdk=={latest_version}`) or use a version of the SDK compatible with the server.",
130+
fg="red",
131+
)
132+
133+
107134
def graphql(query: str, variables=None, token=None):
135+
"""Check that there is no breaking change and perform a GraphQL request."""
136+
ONE_HOUR = 60 * 60
137+
now_timestamp = int(datetime.now().timestamp())
138+
if not settings.last_breaking_change_check or now_timestamp - settings.last_breaking_change_check > ONE_HOUR:
139+
detect_graphql_breaking_changes(token)
140+
settings.last_breaking_change_check = now_timestamp
141+
return _query_graphql(query, variables, token)
142+
143+
144+
def _query_graphql(query: str, variables=None, token=None):
108145
"""Perform a GraphQL request."""
109146
url = settings.api_url + "/graphql/"
110147
if token is None:
@@ -121,6 +158,7 @@ def graphql(query: str, variables=None, token=None):
121158
click.echo(f"Variables: {variables}")
122159

123160
session = create_requests_session()
161+
124162
response = session.post(
125163
url,
126164
headers={

0 commit comments

Comments
 (0)