From fd8038bfecb11d75acc7e34c3797ca216b76f3d7 Mon Sep 17 00:00:00 2001 From: JerrySentry Date: Tue, 26 Nov 2024 14:47:00 -0500 Subject: [PATCH 1/3] Bundle Analysis: expose bundle report info to GQL --- .../types/bundle_analysis/base.graphql | 11 ++++ graphql_api/types/bundle_analysis/base.py | 58 +++++++++++++++++++ services/bundle_analysis.py | 38 ++++++++++++ 3 files changed, 107 insertions(+) diff --git a/graphql_api/types/bundle_analysis/base.graphql b/graphql_api/types/bundle_analysis/base.graphql index 5aeb3898e5..7e2004b3f7 100644 --- a/graphql_api/types/bundle_analysis/base.graphql +++ b/graphql_api/types/bundle_analysis/base.graphql @@ -58,6 +58,16 @@ type BundleAsset { routes: [String!] } +type BundleInfo { + version: String! + plugin_name: String! + plugin_version: String! + built_at: String! + duration: Int! + bundler_name: String! + bundler_version: String! +} + type BundleReport { name: String! moduleCount: Int! @@ -82,6 +92,7 @@ type BundleReport { last: Int before: String ): AssetConnection + info: BundleInfo! } type BundleAnalysisMeasurements{ diff --git a/graphql_api/types/bundle_analysis/base.py b/graphql_api/types/bundle_analysis/base.py index 6bcee7f329..cc78daa771 100644 --- a/graphql_api/types/bundle_analysis/base.py +++ b/graphql_api/types/bundle_analysis/base.py @@ -17,6 +17,7 @@ BundleData, BundleLoadTime, BundleReport, + BundleReportInfo, BundleSize, ModuleReport, ) @@ -28,6 +29,7 @@ bundle_module_bindable = ObjectType("BundleModule") bundle_asset_bindable = ObjectType("BundleAsset") bundle_report_bindable = ObjectType("BundleReport") +bundle_info_bindable = ObjectType("BundleInfo") def _find_index_by_cursor(assets: List, cursor: str) -> int: @@ -372,3 +374,59 @@ def resolve_bundle_report_is_cached( bundle_report: BundleReport, info: GraphQLResolveInfo ) -> bool: return bundle_report.is_cached + + +@bundle_report_bindable.field("info") +def resolve_bundle_report_info( + bundle_report: BundleReport, info: GraphQLResolveInfo +) -> BundleReportInfo: + return BundleReportInfo(bundle_report.info) + + +@bundle_info_bindable.field("version") +def resolve_bundle_info_version( + bundle_info: BundleReportInfo, info: GraphQLResolveInfo +) -> str: + return bundle_info.version + + +@bundle_info_bindable.field("plugin_name") +def resolve_bundle_info_plugin_name( + bundle_info: BundleReportInfo, info: GraphQLResolveInfo +) -> str: + return bundle_info.plugin_name + + +@bundle_info_bindable.field("plugin_version") +def resolve_bundle_info_plugin_version( + bundle_info: BundleReportInfo, info: GraphQLResolveInfo +) -> str: + return bundle_info.plugin_version + + +@bundle_info_bindable.field("built_at") +def resolve_bundle_info_built_at( + bundle_info: BundleReportInfo, info: GraphQLResolveInfo +) -> str: + return bundle_info.built_at + + +@bundle_info_bindable.field("duration") +def resolve_bundle_info_duration( + bundle_info: BundleReportInfo, info: GraphQLResolveInfo +) -> int: + return bundle_info.duration + + +@bundle_info_bindable.field("bundler_name") +def resolve_bundle_info_bundler_name( + bundle_info: BundleReportInfo, info: GraphQLResolveInfo +) -> str: + return bundle_info.bundler_name + + +@bundle_info_bindable.field("bundler_version") +def resolve_bundle_info_bundler_version( + bundle_info: BundleReportInfo, info: GraphQLResolveInfo +) -> str: + return bundle_info.bundler_version diff --git a/services/bundle_analysis.py b/services/bundle_analysis.py index 921cdf8e61..77329b3dab 100644 --- a/services/bundle_analysis.py +++ b/services/bundle_analysis.py @@ -298,6 +298,44 @@ def module_count(self) -> int: def is_cached(self) -> bool: return self.report.is_cached() + @cached_property + def info(self) -> dict: + return self.report.info() + + +@dataclass +class BundleReportInfo(object): + def __init__(self, info: dict) -> None: + self.info = info + + @cached_property + def version(self) -> str: + return self.info.get("version", "unknown") + + @cached_property + def plugin_name(self) -> str: + return self.info.get("plugin_name", "unknown") + + @cached_property + def plugin_version(self) -> str: + return self.info.get("plugin_version", "unknown") + + @cached_property + def built_at(self) -> str: + return str(datetime.fromtimestamp(self.info.get("built_at", 0) / 1000)) + + @cached_property + def duration(self) -> int: + return self.info.get("duration", -1) + + @cached_property + def bundler_name(self) -> str: + return self.info.get("bundler_name", "unknown") + + @cached_property + def bundler_version(self) -> str: + return self.info.get("bundler_version", "unknown") + @dataclass class BundleAnalysisReport(object): From a5e67d40c5f205a7cb46bc0b9cdf6b21bfde88d2 Mon Sep 17 00:00:00 2001 From: JerrySentry Date: Tue, 26 Nov 2024 14:57:57 -0500 Subject: [PATCH 2/3] Add unit test --- graphql_api/tests/test_commit.py | 67 ++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/graphql_api/tests/test_commit.py b/graphql_api/tests/test_commit.py index e216e519fc..08b523ab2d 100644 --- a/graphql_api/tests/test_commit.py +++ b/graphql_api/tests/test_commit.py @@ -3323,3 +3323,70 @@ def test_bundle_analysis_asset_routes(self, get_storage_service): "/login", "/super/long/url/path", ] + + @patch("graphql_api.dataloader.bundle_analysis.get_appropriate_storage_service") + def test_bundle_analysis_report_info(self, get_storage_service): + storage = MemoryStorageService({}) + get_storage_service.return_value = storage + + head_commit_report = CommitReportFactory( + commit=self.commit, report_type=CommitReport.ReportType.BUNDLE_ANALYSIS + ) + + with open( + "./services/tests/samples/bundle_with_assets_and_modules.sqlite", "rb" + ) as f: + storage_path = StoragePaths.bundle_report.path( + repo_key=ArchiveService.get_archive_hash(self.repo), + report_key=head_commit_report.external_id, + ) + storage.write_file(get_bucket_name(), storage_path, f) + + query = """ + query FetchCommit($org: String!, $repo: String!, $commit: String!) { + owner(username: $org) { + repository(name: $repo) { + ... on Repository { + commit(id: $commit) { + bundleAnalysis { + bundleAnalysisReport { + __typename + ... on BundleAnalysisReport { + bundle(name: "b5") { + info { + version + plugin_name + plugin_version + built_at + duration + bundler_name + bundler_version + } + } + } + } + } + } + } + } + } + } + """ + + variables = { + "org": self.org.username, + "repo": self.repo.name, + "commit": self.commit.commitid, + } + data = self.gql_request(query, variables=variables) + commit = data["owner"]["repository"]["commit"] + + bundle_info = commit["bundleAnalysis"]["bundleAnalysisReport"]["bundle"]["info"] + + assert bundle_info["version"] == "1" + assert bundle_info["plugin_name"] == "codecov-vite-bundle-analysis-plugin" + assert bundle_info["plugin_version"] == "1.0.0" + assert bundle_info["built_at"] == "2023-12-01 17:17:28.604000" + assert bundle_info["duration"] == 331 + assert bundle_info["bundler_name"] == "rollup" + assert bundle_info["bundler_version"] == "3.29.4" From 2f99798a5201589e95d05df92bfbd9a1f09a0230 Mon Sep 17 00:00:00 2001 From: JerrySentry Date: Tue, 26 Nov 2024 15:41:34 -0500 Subject: [PATCH 3/3] use explicit resolvers --- graphql_api/types/__init__.py | 2 + graphql_api/types/bundle_analysis/__init__.py | 2 + .../types/bundle_analysis/base.graphql | 4 +- graphql_api/types/bundle_analysis/base.py | 58 +++++++++---------- 4 files changed, 35 insertions(+), 31 deletions(-) diff --git a/graphql_api/types/__init__.py b/graphql_api/types/__init__.py index 9c0619090e..38b4d3351b 100644 --- a/graphql_api/types/__init__.py +++ b/graphql_api/types/__init__.py @@ -17,6 +17,7 @@ bundle_data_bindable, bundle_module_bindable, bundle_report_bindable, + bundle_report_info_bindable, ) from .commit import ( commit, @@ -148,6 +149,7 @@ bundle_data_bindable, bundle_module_bindable, bundle_report_bindable, + bundle_report_info_bindable, commit_bindable, commit_bundle_analysis_bindable, commit_coverage_analytics_bindable, diff --git a/graphql_api/types/bundle_analysis/__init__.py b/graphql_api/types/bundle_analysis/__init__.py index 4b7ae42be4..40cf8873ad 100644 --- a/graphql_api/types/bundle_analysis/__init__.py +++ b/graphql_api/types/bundle_analysis/__init__.py @@ -5,6 +5,7 @@ bundle_data_bindable, bundle_module_bindable, bundle_report_bindable, + bundle_report_info_bindable, ) from .comparison import ( bundle_analysis_comparison_bindable, @@ -26,6 +27,7 @@ "bundle_data_bindable", "bundle_module_bindable", "bundle_report_bindable", + "bundle_report_info_bindable", "bundle_analysis_comparison_bindable", "bundle_analysis_comparison_result_bindable", "bundle_comparison_bindable", diff --git a/graphql_api/types/bundle_analysis/base.graphql b/graphql_api/types/bundle_analysis/base.graphql index 7e2004b3f7..31cdedd780 100644 --- a/graphql_api/types/bundle_analysis/base.graphql +++ b/graphql_api/types/bundle_analysis/base.graphql @@ -58,7 +58,7 @@ type BundleAsset { routes: [String!] } -type BundleInfo { +type BundleReportInfo { version: String! plugin_name: String! plugin_version: String! @@ -92,7 +92,7 @@ type BundleReport { last: Int before: String ): AssetConnection - info: BundleInfo! + info: BundleReportInfo! } type BundleAnalysisMeasurements{ diff --git a/graphql_api/types/bundle_analysis/base.py b/graphql_api/types/bundle_analysis/base.py index cc78daa771..6617fb39aa 100644 --- a/graphql_api/types/bundle_analysis/base.py +++ b/graphql_api/types/bundle_analysis/base.py @@ -29,7 +29,7 @@ bundle_module_bindable = ObjectType("BundleModule") bundle_asset_bindable = ObjectType("BundleAsset") bundle_report_bindable = ObjectType("BundleReport") -bundle_info_bindable = ObjectType("BundleInfo") +bundle_report_info_bindable = ObjectType("BundleReportInfo") def _find_index_by_cursor(assets: List, cursor: str) -> int: @@ -383,50 +383,50 @@ def resolve_bundle_report_info( return BundleReportInfo(bundle_report.info) -@bundle_info_bindable.field("version") -def resolve_bundle_info_version( - bundle_info: BundleReportInfo, info: GraphQLResolveInfo +@bundle_report_info_bindable.field("version") +def resolve_bundle_report_info_version( + bundle_report_info: BundleReportInfo, info: GraphQLResolveInfo ) -> str: - return bundle_info.version + return bundle_report_info.version -@bundle_info_bindable.field("plugin_name") -def resolve_bundle_info_plugin_name( - bundle_info: BundleReportInfo, info: GraphQLResolveInfo +@bundle_report_info_bindable.field("plugin_name") +def resolve_bundle_report_info_plugin_name( + bundle_report_info: BundleReportInfo, info: GraphQLResolveInfo ) -> str: - return bundle_info.plugin_name + return bundle_report_info.plugin_name -@bundle_info_bindable.field("plugin_version") -def resolve_bundle_info_plugin_version( - bundle_info: BundleReportInfo, info: GraphQLResolveInfo +@bundle_report_info_bindable.field("plugin_version") +def resolve_bundle_report_info_plugin_version( + bundle_report_info: BundleReportInfo, info: GraphQLResolveInfo ) -> str: - return bundle_info.plugin_version + return bundle_report_info.plugin_version -@bundle_info_bindable.field("built_at") -def resolve_bundle_info_built_at( - bundle_info: BundleReportInfo, info: GraphQLResolveInfo +@bundle_report_info_bindable.field("built_at") +def resolve_bundle_report_info_built_at( + bundle_report_info: BundleReportInfo, info: GraphQLResolveInfo ) -> str: - return bundle_info.built_at + return bundle_report_info.built_at -@bundle_info_bindable.field("duration") -def resolve_bundle_info_duration( - bundle_info: BundleReportInfo, info: GraphQLResolveInfo +@bundle_report_info_bindable.field("duration") +def resolve_bundle_report_info_duration( + bundle_report_info: BundleReportInfo, info: GraphQLResolveInfo ) -> int: - return bundle_info.duration + return bundle_report_info.duration -@bundle_info_bindable.field("bundler_name") -def resolve_bundle_info_bundler_name( - bundle_info: BundleReportInfo, info: GraphQLResolveInfo +@bundle_report_info_bindable.field("bundler_name") +def resolve_bundle_report_info_bundler_name( + bundle_report_info: BundleReportInfo, info: GraphQLResolveInfo ) -> str: - return bundle_info.bundler_name + return bundle_report_info.bundler_name -@bundle_info_bindable.field("bundler_version") -def resolve_bundle_info_bundler_version( - bundle_info: BundleReportInfo, info: GraphQLResolveInfo +@bundle_report_info_bindable.field("bundler_version") +def resolve_bundle_report_info_bundler_version( + bundle_report_info: BundleReportInfo, info: GraphQLResolveInfo ) -> str: - return bundle_info.bundler_version + return bundle_report_info.bundler_version