Skip to content

Commit feb80b2

Browse files
authored
Fix firebase-app-distribution release ordering rejected by the Firebase API (#501)
Fix Firebase App Distribution orderBy rejected as invalid argument Firebase's `releases.list` API now strictly validates `orderBy` and rejects the previously tolerated `createTimeDesc`, breaking `get-latest-build-version` and `releases list`. Send the documented `createTime desc` grammar instead. The API value is decoupled from the `--order-by` CLI token via a new tool-layer `ReleasesOrderByArgument`, so the CLI interface stays backwards compatible (`--order-by createTimeDesc` still works). Resolves #500.
1 parent f5bdb1a commit feb80b2

11 files changed

Lines changed: 80 additions & 13 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
Version 0.69.0
2+
-------------
3+
4+
**Bugfixes**
5+
- Fix `firebase-app-distribution` actions `get-latest-build-version` and `releases list`. The Firebase App Distribution API changed `orderBy` query parameter validation and rejects the previously tolerated `createTimeDesc`, requiring the documented space-separated grammar `createTime desc` instead.
6+
17
Version 0.68.0
28
-------------
39

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "codemagic-cli-tools"
3-
version = "0.68.0"
3+
version = "0.69.0"
44
description = "CLI tools used in Codemagic builds"
55
authors = [{ name = "Priit Lätt", email = "priit@nevercode.io" }]
66
requires-python = ">=3.8,<4"

src/codemagic/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
__title__ = "codemagic-cli-tools"
22
__description__ = "CLI tools used in Codemagic builds"
3-
__version__ = "0.68.0.dev"
3+
__version__ = "0.69.0.dev"
44
__url__ = "https://github.com/codemagic-ci-cd/cli-tools"
55
__licence__ = "GNU General Public License v3.0"

src/codemagic/google/resources/firebase/order_by.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,11 @@
22

33

44
class OrderBy(ResourceEnum):
5-
CREATE_TIME_DESC = "createTimeDesc"
5+
"""
6+
Values follow the Firebase App Distribution `releases.list` `orderBy` grammar, which uses a
7+
space-separated `desc` suffix, see
8+
https://firebase.google.com/docs/reference/app-distribution/rest/v1/projects.apps.releases/list
9+
"""
10+
11+
CREATE_TIME_DESC = "createTime desc"
612
CREATE_TIME_ASC = "createTime"

src/codemagic/tools/firebase_app_distribution/action_groups/releases_action_group.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
from codemagic import cli
55
from codemagic.cli import Colors
66
from codemagic.google.errors import GoogleError
7-
from codemagic.google.resources.firebase import OrderBy
87
from codemagic.google.resources.firebase import Release
98

9+
from ..argument_types import ReleasesOrderByArgument
1010
from ..arguments import ReleasesArgument
1111
from ..arguments import ResourcesArgument
1212
from ..errors import FirebaseAppDistributionError
@@ -26,15 +26,15 @@ def list_releases(
2626
self,
2727
app_id: str,
2828
limit: int = ResourcesArgument.LIMIT.get_default(),
29-
order_by: OrderBy = ResourcesArgument.ORDER_BY.get_default(),
29+
order_by: ReleasesOrderByArgument = ResourcesArgument.ORDER_BY.get_default(),
3030
should_print: bool = True,
3131
) -> List[Release]:
3232
"""
3333
List releases for the Firebase application
3434
"""
3535

3636
try:
37-
releases = self.client.releases.list(self.project_number, app_id, order_by, limit)
37+
releases = self.client.releases.list(self.project_number, app_id, order_by.order_by, limit)
3838
except GoogleError as e:
3939
raise FirebaseAppDistributionError(str(e))
4040

src/codemagic/tools/firebase_app_distribution/argument_types.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,17 @@
33
from typing import Dict
44

55
from codemagic import cli
6+
from codemagic.google.resources.firebase import OrderBy
7+
from codemagic.models.enums import ResourceEnum
8+
9+
10+
class ReleasesOrderByArgument(ResourceEnum):
11+
CREATE_TIME_DESC = "createTimeDesc"
12+
CREATE_TIME_ASC = "createTime"
13+
14+
@property
15+
def order_by(self) -> OrderBy:
16+
return OrderBy[self.name]
617

718

819
class CredentialsArgument(cli.EnvironmentArgumentValue[dict]):

src/codemagic/tools/firebase_app_distribution/arguments.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
from codemagic import cli
22
from codemagic.cli.colors import Colors
3-
from codemagic.google.resources.firebase import OrderBy
43

54
from .argument_types import CredentialsArgument
5+
from .argument_types import ReleasesOrderByArgument
66

77
select_project_group = cli.MutuallyExclusiveGroup(
88
name="select project",
@@ -50,12 +50,12 @@ class ResourcesArgument(cli.Argument):
5050
ORDER_BY = cli.ArgumentProperties(
5151
key="order_by",
5252
flags=("--order-by", "-o"),
53-
type=OrderBy,
53+
type=ReleasesOrderByArgument,
5454
description="Sort resources in the specified order",
5555
argparse_kwargs={
5656
"required": False,
57-
"default": OrderBy.CREATE_TIME_DESC,
58-
"choices": list(OrderBy),
57+
"default": ReleasesOrderByArgument.CREATE_TIME_DESC,
58+
"choices": list(ReleasesOrderByArgument),
5959
},
6060
)
6161

src/codemagic/tools/firebase_app_distribution/firebase_app_distribution_action.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55

66
from codemagic.google.firebase_client import FirebaseClient
77
from codemagic.google.resources import ResourcePrinter
8-
from codemagic.google.resources.firebase import OrderBy
98
from codemagic.google.resources.firebase import Release
109

10+
from .argument_types import ReleasesOrderByArgument
11+
1112

1213
class FirebaseAppDistributionAction(ABC):
1314
client: FirebaseClient
@@ -37,7 +38,7 @@ def list_releases(
3738
self,
3839
app_id: str,
3940
limit: int = 25,
40-
order_by: OrderBy = OrderBy.CREATE_TIME_DESC,
41+
order_by: ReleasesOrderByArgument = ReleasesOrderByArgument.CREATE_TIME_DESC,
4142
should_print: bool = True,
4243
) -> List[Release]:
4344
from .action_groups.releases_action_group import ReleasesActionGroup

tests/google/firebase_client/test_firebase_client.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,29 @@ def test_list_releases(firebase_client, release, mock_releases):
6969
assert releases[1].buildVersion == "71"
7070

7171

72+
@pytest.mark.parametrize(
73+
("order_by", "expected_order_by_param"),
74+
(
75+
(OrderBy.CREATE_TIME_DESC, "createTime desc"),
76+
(OrderBy.CREATE_TIME_ASC, "createTime"),
77+
),
78+
)
79+
def test_list_releases_order_by(firebase_client, mock_releases, order_by, expected_order_by_param):
80+
firebase_client.releases.list(
81+
"firebase-project-id",
82+
"firebase-app-id",
83+
order_by=order_by,
84+
page_size=2,
85+
)
86+
87+
mock_releases.return_value.list.assert_called_once_with(
88+
orderBy=expected_order_by_param,
89+
parent="projects/firebase-project-id/apps/firebase-app-id",
90+
pageSize=2,
91+
pageToken="",
92+
)
93+
94+
7295
def test_list_releases_limit(firebase_client, mock_releases):
7396
releases = firebase_client.releases.list(
7497
"firebase-project-number",

tests/tools/test_firebase_app_distribution.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from codemagic.google.services.firebase import ReleasesService
1818
from codemagic.tools.firebase_app_distribution import FirebaseAppDistribution
1919
from codemagic.tools.firebase_app_distribution.argument_types import CredentialsArgument
20+
from codemagic.tools.firebase_app_distribution.argument_types import ReleasesOrderByArgument
2021
from codemagic.tools.firebase_app_distribution.arguments import FirebaseArgument
2122
from codemagic.tools.firebase_app_distribution.errors import FirebaseAppDistributionError
2223

@@ -26,6 +27,25 @@
2627
json_output_argument = FirebaseArgument.JSON_OUTPUT
2728

2829

30+
@pytest.mark.parametrize(
31+
("argument", "expected_order_by", "expected_cli_token"),
32+
(
33+
(ReleasesOrderByArgument.CREATE_TIME_DESC, OrderBy.CREATE_TIME_DESC, "createTimeDesc"),
34+
(ReleasesOrderByArgument.CREATE_TIME_ASC, OrderBy.CREATE_TIME_ASC, "createTime"),
35+
),
36+
)
37+
def test_releases_order_by_argument(argument, expected_order_by, expected_cli_token):
38+
# CLI parameter value stays a single, backwards-compatible token and maps to the API-facing OrderBy.
39+
assert argument.value == expected_cli_token
40+
assert argument.order_by is expected_order_by
41+
42+
43+
def test_every_releases_order_by_argument_maps_to_order_by():
44+
# Guards against adding a CLI ordering choice without a matching API-facing OrderBy member.
45+
for argument in ReleasesOrderByArgument:
46+
assert isinstance(argument.order_by, OrderBy)
47+
48+
2949
@pytest.fixture
3050
def releases() -> List[Release]:
3151
mock_response_path = pathlib.Path(__file__).parent / "mocks" / "firebase_releases.json"

0 commit comments

Comments
 (0)