-
Notifications
You must be signed in to change notification settings - Fork 1
feat: breaking changes detection against the backend server (HEXA-1238) #260
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 17 commits
584d182
0434af6
90ff1fe
8ff6584
22f09cc
dbf1317
3d69573
7558f10
0dff3f6
83b2eea
6a63766
7df3531
edc2554
d5728e3
5dcbeb1
4b88b9a
3a453ba
b0bb0a0
b23bf7e
9204700
ace843c
5c58c48
7d28522
bea9eff
d1ee33b
c228c36
b28cdbe
45c9878
1a72de8
b4d8bde
c2053bf
7b6cb7c
064360d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,2 @@ | ||
| recursive-include openhexa/cli/skeleton * | ||
| recursive-include openhexa/cli/skeleton * | ||
| recursive-include openhexa/cli/graphql * |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,7 @@ | |
| import logging | ||
| import os | ||
| import tempfile | ||
| import time | ||
| import typing | ||
| from importlib.metadata import version | ||
| from pathlib import Path | ||
|
|
@@ -18,6 +19,8 @@ | |
| from docker.models.containers import Container | ||
| from jinja2 import Template | ||
|
|
||
| from graphql import build_client_schema, build_schema, get_introspection_query | ||
| from graphql.utilities import find_breaking_changes | ||
| from openhexa.cli.settings import settings | ||
| from openhexa.sdk.pipelines import get_local_workspace_config | ||
| from openhexa.sdk.pipelines.runtime import get_pipeline | ||
|
|
@@ -104,7 +107,63 @@ def get_library_versions() -> tuple[str, str]: | |
| return installed_version, installed_version | ||
|
|
||
|
|
||
| def detect_graphql_breaking_changes(token): | ||
| """Detect breaking changes between the schema referenced in the SDK and the server using graphql-core.""" | ||
| stored_schema_obj = build_schema((Path(__file__).parent / "graphql" / "schema.generated.graphql").open().read()) | ||
| server_schema_obj = build_client_schema( | ||
| _query_graphql(get_introspection_query(input_value_deprecation=True), token=token) | ||
| ) | ||
|
|
||
| breaking_changes = find_breaking_changes(stored_schema_obj, server_schema_obj) | ||
| if breaking_changes: | ||
| current_version, latest_version = get_library_versions() | ||
| click.echo( | ||
| click.style( | ||
| f"⚠️ Breaking changes detected between the SDK (version {current_version}) and the server:", | ||
| fg="red", | ||
| ) | ||
| ) | ||
| for change in breaking_changes: | ||
| click.echo(click.style(f"- {change.description}", fg="yellow")) | ||
| click.echo(click.style("This could lead to unexpected results.", fg="red")) | ||
| click.echo( | ||
| click.style( | ||
| f"Please update the SDK to the latest version ({latest_version}) or use a version of the SDK compatible with the server.", | ||
| fg="red", | ||
| ) | ||
| ) | ||
|
|
||
|
|
||
| _COOLDOWN_PERIOD = 3600 # Cooldown period in seconds | ||
| _CACHE_FILE = Path.home() / f".openhexa_{version('openhexa.sdk')}" # Cache file in the user's home directory | ||
|
|
||
|
|
||
| def get_last_checked(): | ||
| """Retrieve the last checked timestamp from the cache file.""" | ||
| if _CACHE_FILE.exists(): | ||
| try: | ||
| return float(_CACHE_FILE.read_text().strip()) | ||
| except ValueError: | ||
| pass | ||
| return None | ||
|
|
||
|
|
||
| def update_last_checked(): | ||
| """Update the cache file with the current timestamp.""" | ||
| _CACHE_FILE.write_text(str(time.time())) | ||
|
|
||
|
|
||
| def graphql(query: str, variables=None, token=None): | ||
| """Check that there is no breaking change and perform a GraphQL request.""" | ||
| last_checked = get_last_checked() | ||
| current_time = time.time() | ||
| if not last_checked or (current_time - last_checked) >= _COOLDOWN_PERIOD: | ||
| detect_graphql_breaking_changes(token) | ||
| update_last_checked() | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not totally convinced myself on the caching on the disk. WDYT ?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mmm me neither. I'd prefer to store this in the config of the user (where we store the workspaces and the token)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok I agree, will do the change |
||
| return _query_graphql(query, variables, token) | ||
|
|
||
|
|
||
| def _query_graphql(query: str, variables=None, token=None): | ||
| """Perform a GraphQL request.""" | ||
| url = settings.api_url + "/graphql/" | ||
| if token is None: | ||
|
|
@@ -121,6 +180,7 @@ def graphql(query: str, variables=None, token=None): | |
| click.echo(f"Variables: {variables}") | ||
|
|
||
| session = create_requests_session() | ||
|
|
||
| response = session.post( | ||
| url, | ||
| headers={ | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you give an example of command to update the openhexa.sdk package to the user as well please ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea, thanks