Skip to content
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

Request less information from App Store Connect to detect latest build number #382

Merged
merged 10 commits into from
Dec 20, 2023
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
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
Version 0.48.2
-------------

This PR contains changes from [PR #382](https://github.com/codemagic-ci-cd/cli-tools/pull/382)

**Features**
- Speed improvements for `app-store-connect` actions `get-latest-testflight-build-number`, `get-latest-app-store-build-number` and `app-store-connect get-latest-build-number` in case the application has a lot of versions in App Store Connect.

**Development**
- Add new App Store Connect API Client methods:
- `codemagic.apple.app_store_connect.apps.Apps.list_app_store_versions_data` to fetch application's App Store versions as `list[dict]`,
- `codemagic.apple.app_store_connect.versioning.AppStoreVersions.read_build_data` to fetch build of App Store version as `dict`,
- `codemagic.apple.app_store_connect.versioning.PreReleaseVersions.list_data` to fetch pre-release versions as `list[dict]`,
- `codemagic.apple.app_store_connect.versioning.PreReleaseVersions.list_builds_data` to fetch builds of pre-release version as `list[dict]`.
- Move implementations of latest build number actions from `codemagic.tools.AppStoreConnect` to dedicated classes and plug them back in as mixins.

Version 0.48.1
-------------

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "codemagic-cli-tools"
version = "0.48.1"
version = "0.48.2"
description = "CLI tools used in Codemagic builds"
readme = "README.md"
authors = [
Expand Down
2 changes: 1 addition & 1 deletion src/codemagic/__version__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
__title__ = "codemagic-cli-tools"
__description__ = "CLI tools used in Codemagic builds"
__version__ = "0.48.1.dev"
__version__ = "0.48.2.dev"
__url__ = "https://github.com/codemagic-ci-cd/cli-tools"
__licence__ = "GNU General Public License v3.0"
36 changes: 25 additions & 11 deletions src/codemagic/apple/app_store_connect/apps/apps.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from dataclasses import dataclass
from typing import List
from typing import Optional
from typing import Sequence
from typing import Type
from typing import Union

Expand Down Expand Up @@ -92,23 +93,36 @@ def list_pre_release_versions(self, app: Union[LinkedResourceData, ResourceId])
url = f"{self.client.API_URL}/apps/{app}/preReleaseVersions"
return [PreReleaseVersion(version) for version in self.client.paginate(url, page_size=None)]

def list_app_store_versions(
def list_app_store_versions_data(
self,
app: Union[LinkedResourceData, ResourceId],
resource_filter: Optional[AppStoreVersions.Filter] = None,
resource_filter: AppStoreVersions.Filter = AppStoreVersions.Filter(),
limit: Optional[int] = None,
) -> List[AppStoreVersion]:
fields: Sequence[str] = tuple(),
page_size: Optional[int] = 100,
) -> List[dict]:
"""
https://developer.apple.com/documentation/appstoreconnectapi/list_all_app_store_versions_for_an_app
"""
url = None
if isinstance(app, App) and app.relationships is not None:
url = app.relationships.appStoreVersions.links.related
if url is None:
url = f"{self.client.API_URL}/apps/{app}/appStoreVersions"
params = resource_filter.as_query_params() if resource_filter else None
app_store_versions = self.client.paginate(url, params=params, limit=limit)
return [AppStoreVersion(app_store_version) for app_store_version in app_store_versions]
app_id = self._get_resource_id(app)
params = resource_filter.as_query_params()
if fields:
params["fields[appStoreVersions]"] = ",".join(fields)
url = f"{self.client.API_URL}/apps/{app_id}/appStoreVersions"
return self.client.paginate(url, params=params, limit=limit, page_size=page_size)

def list_app_store_versions(
self,
app: Union[LinkedResourceData, ResourceId],
resource_filter: AppStoreVersions.Filter = AppStoreVersions.Filter(),
limit: Optional[int] = None,
) -> List[AppStoreVersion]:
app_store_versions_data = self.list_app_store_versions_data(
app,
resource_filter=resource_filter,
limit=limit,
)
return [AppStoreVersion(app_store_version) for app_store_version in app_store_versions_data]

def list_beta_app_localizations(self, app: Union[App, ResourceId]) -> List[BetaAppLocalization]:
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,20 +95,25 @@ def read(self, app_store_version: Union[LinkedResourceData, ResourceId]) -> AppS
response = self.client.session.get(f"{self.client.API_URL}/appStoreVersions/{app_store_version_id}").json()
return AppStoreVersion(response["data"])

def read_build(self, app_store_version: Union[AppStoreVersion, ResourceId]) -> Optional[Build]:
def read_build_data(
self,
app_store_version: Union[AppStoreVersion, ResourceId],
fields: Sequence[str] = tuple(),
) -> Optional[dict]:
"""
https://developer.apple.com/documentation/appstoreconnectapi/read_the_build_information_of_an_app_store_version
"""
url = None
if isinstance(app_store_version, AppStoreVersion) and app_store_version.relationships is not None:
url = app_store_version.relationships.build.links.related
if url is None:
url = f"{self.client.API_URL}/appStoreVersions/{app_store_version}/build"
response = self.client.session.get(url).json()
app_store_version_id = self._get_resource_id(app_store_version)
url = f"{self.client.API_URL}/appStoreVersions/{app_store_version_id}/build"
params = {"fields[builds]": ",".join(fields)} if fields else {}
response = self.client.session.get(url, params=params).json()
return response["data"]

if response["data"] is None:
def read_build(self, app_store_version: Union[AppStoreVersion, ResourceId]) -> Optional[Build]:
build_data = self.read_build_data(app_store_version)
if build_data is None:
return None
return Build(response["data"])
return Build(build_data)

def read_app_store_version_submission(
self,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from dataclasses import dataclass
from typing import List
from typing import Optional
from typing import Sequence
from typing import Type
from typing import TypeVar
from typing import Union
Expand Down Expand Up @@ -38,25 +39,41 @@ def _get_include_field_name(cls, include_type: Type[IncludedResource]) -> str:
return "builds"
raise ValueError(f"Unknown include type {include_type}")

def list(self, resource_filter: Filter = Filter()) -> List[PreReleaseVersion]:
def list_data(
self,
resource_filter: Filter = Filter(),
limit: Optional[int] = None,
fields: Sequence[str] = tuple(),
page_size: Optional[int] = 100,
) -> List[dict]:
"""
https://developer.apple.com/documentation/appstoreconnectapi/list_prerelease_versions
"""
results = self.client.paginate_with_included(
f"{self.client.API_URL}/preReleaseVersions",
params=resource_filter.as_query_params(),
)
return [PreReleaseVersion(prerelease_version) for prerelease_version in results.data]
params = resource_filter.as_query_params()
if fields:
params["fields[preReleaseVersions]"] = ",".join(fields)
url = f"{self.client.API_URL}/preReleaseVersions"
return self.client.paginate(url, params=params, limit=limit, page_size=page_size)

def list_builds(self, pre_release_version: Union[LinkedResourceData, ResourceId]) -> List[Build]:
def list(self, resource_filter: Filter = Filter()) -> List[PreReleaseVersion]:
pre_release_versions_data = self.list_data(resource_filter=resource_filter)
return [PreReleaseVersion(prerelease_version) for prerelease_version in pre_release_versions_data]

def list_builds_data(
self,
pre_release_version: Union[LinkedResourceData, ResourceId],
limit: Optional[int] = None,
fields: Sequence[str] = tuple(),
page_size: Optional[int] = 100,
) -> List[dict]:
"""
https://developer.apple.com/documentation/appstoreconnectapi/list_all_builds_of_a_prerelease_version
"""
pre_release_version_id = self._get_resource_id(pre_release_version)
url = f"{self.client.API_URL}/preReleaseVersions/{pre_release_version_id}/builds"
params = {"fields[builds]": ",".join(fields)} if fields else {}
return self.client.paginate(url, params=params, limit=limit, page_size=page_size)

url = None
if isinstance(pre_release_version, PreReleaseVersion) and pre_release_version.relationships is not None:
url = pre_release_version.relationships.builds.links.related
if url is None:
url = f"{self.client.API_URL}/preReleaseVersions/{pre_release_version}/builds"

return [Build(build) for build in self.client.paginate(url, page_size=None)]
def list_builds(self, pre_release_version: Union[LinkedResourceData, ResourceId]) -> List[Build]:
builds_data = self.list_builds_data(pre_release_version, page_size=None)
return [Build(build) for build in builds_data]
3 changes: 3 additions & 0 deletions src/codemagic/tools/_app_store_connect/actions/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
from .latest_build_number_actions import GetLatestAppStoreBuildNumberAction
from .latest_build_number_actions import GetLatestBuildNumberAction
from .latest_build_number_actions import GetLatestTestflightBuildNumberAction
from .publish_action import PublishAction
Loading