Skip to content
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
28 changes: 28 additions & 0 deletions BREAKING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Breaking Changes

This is a comprehensive list of the breaking changes introduced in the major version releases. Until version 1.0.0, breaking changes are introduced in minor version releases.

## Versions

- [Version 0.2.x](#version-02x)

## Version 0.2.x

### Job Logs

`jobs.logs()` now returns a list of `JobLog` models (with `number`, `payload` and `timestamp`) instead of the raw response text.

```diff
- print(client.jobs.logs(job_id))
+ for log in client.jobs.logs(job_id):
+ print(log.payload)
```

### Removed `git_repository_url` Parameter

The `git_repository_url` parameter has been removed from `apps.update()` as the API no longer supports it and ignored the value. Use `apps.repository.set()` to link an app to a Git repository instead.

```diff
- client.apps.update(app_id, git_repository_url="https://github.com/owner/name")
+ client.apps.repository.set(app_id, git_connection_id=git_connection_id, path="owner/name")
```
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@ build = client.apps.builds.create(app_id, platform="ios", git_ref="main")
job = client.jobs.wait(build.job_id)
print(job.status)

logs = client.jobs.logs(job.id)
for log in client.jobs.logs(job.id):
print(log.payload)

# Explain a failure
if job.status == "failed":
Expand Down
3 changes: 2 additions & 1 deletion examples/trigger_native_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ def main(app_id: str) -> None:

print(f"Build finished with status: {job.status}")
if job.status != "succeeded":
print(client.jobs.logs(build.job_id))
for log in client.jobs.logs(build.job_id):
print(log.payload)
return

for artifact in client.apps.builds.artifacts.list(app_id, build.id):
Expand Down
2 changes: 2 additions & 0 deletions src/capawesome_cloud/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
GitRepository,
Job,
JobFailureSummary,
JobLog,
LicenseKey,
Organization,
OrganizationInvitation,
Expand Down Expand Up @@ -75,6 +76,7 @@
"GitRepository",
"Job",
"JobFailureSummary",
"JobLog",
"LicenseKey",
"Organization",
"OrganizationInvitation",
Expand Down
8 changes: 8 additions & 0 deletions src/capawesome_cloud/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"AppGitRepository",
"Job",
"JobFailureSummary",
"JobLog",
"User",
"Organization",
"OrganizationMember",
Expand Down Expand Up @@ -227,6 +228,13 @@ class Job(CapawesomeModel):
created_at: Optional[datetime] = None


class JobLog(CapawesomeModel):
job_id: Optional[str] = None
number: Optional[int] = None
payload: Optional[str] = None
timestamp: Optional[datetime] = None


class JobFailureSummary(CapawesomeModel):
summary: Optional[str] = None

Expand Down
2 changes: 0 additions & 2 deletions src/capawesome_cloud/resources/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ def update(
app_channel_id: Union[str, None, NotGiven] = NOT_GIVEN,
app_environment_id: Union[str, None, NotGiven] = NOT_GIVEN,
app_channel_discovery_enabled: Union[bool, NotGiven] = NOT_GIVEN,
git_repository_url: Union[str, None, NotGiven] = NOT_GIVEN,
next_app_build_number: Union[int, NotGiven] = NOT_GIVEN,
) -> App:
"""Update an app."""
Expand All @@ -128,7 +127,6 @@ def update(
"appChannelId": app_channel_id,
"appEnvironmentId": app_environment_id,
"appChannelDiscoveryEnabled": app_channel_discovery_enabled,
"gitRepositoryUrl": git_repository_url,
"nextAppBuildNumber": next_app_build_number,
}
)
Expand Down
9 changes: 4 additions & 5 deletions src/capawesome_cloud/resources/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from typing import List, Optional, Sequence, Union

from ..exceptions import CapawesomeCloudError
from ..models import Job, JobFailureSummary
from ..models import Job, JobFailureSummary, JobLog
from ..pagination import DEFAULT_PAGE_SIZE, Paginator
from ._base import BaseResource, build_params

Expand Down Expand Up @@ -65,10 +65,9 @@ def get(self, job_id: str, *, relations: Optional[str] = None) -> Job:
params = build_params({"relations": relations})
return self._request_model("GET", f"{self._path}/{job_id}", Job, params=params)

def logs(self, job_id: str) -> str:
"""Return the job's logs as text."""
response = self._http.request("GET", f"{self._path}/{job_id}/logs")
return response.text
def logs(self, job_id: str) -> List[JobLog]:
"""List the log lines of a job."""
return self._list_page(f"{self._path}/{job_id}/logs", JobLog)

def get_failure_summary(self, job_id: str) -> JobFailureSummary:
"""Return a summary explaining why a failed job failed.
Expand Down
20 changes: 20 additions & 0 deletions tests/test_jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,23 @@ def test_get_failure_summary(client: CapawesomeCloud) -> None:
return_value=httpx.Response(200, json={"summary": "The signing certificate expired."})
)
assert client.jobs.get_failure_summary("job1").summary == "The signing certificate expired."


@respx.mock
def test_logs_are_parsed(client: CapawesomeCloud) -> None:
respx.get(f"{BASE_URL}/v1/jobs/job1/logs").mock(
return_value=httpx.Response(
200,
json=[
{
"jobId": "job1",
"number": 1,
"payload": "Cloning repository",
"timestamp": "2026-10-01T08:00:00Z",
}
],
)
)
logs = client.jobs.logs("job1")
assert logs[0].number == 1
assert logs[0].payload == "Cloning repository"
Loading