digitalai-release-api-client 26.3.0b1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- com/__init__.py +0 -0
- com/xebialabs/__init__.py +0 -0
- com/xebialabs/xlrelease/__init__.py +0 -0
- com/xebialabs/xlrelease/api/__init__.py +0 -0
- com/xebialabs/xlrelease/api/v1/__init__.py +63 -0
- com/xebialabs/xlrelease/api/v1/activity_logs_api.py +27 -0
- com/xebialabs/xlrelease/api/v1/api_base_task.py +296 -0
- com/xebialabs/xlrelease/api/v1/application_api.py +108 -0
- com/xebialabs/xlrelease/api/v1/archive_api.py +56 -0
- com/xebialabs/xlrelease/api/v1/attachment_api.py +80 -0
- com/xebialabs/xlrelease/api/v1/category_api.py +107 -0
- com/xebialabs/xlrelease/api/v1/configuration_api.py +226 -0
- com/xebialabs/xlrelease/api/v1/delivery_api.py +289 -0
- com/xebialabs/xlrelease/api/v1/delivery_pattern_api.py +328 -0
- com/xebialabs/xlrelease/api/v1/dsl_api.py +63 -0
- com/xebialabs/xlrelease/api/v1/environment_api.py +166 -0
- com/xebialabs/xlrelease/api/v1/environment_label_api.py +117 -0
- com/xebialabs/xlrelease/api/v1/environment_reservation_api.py +208 -0
- com/xebialabs/xlrelease/api/v1/environment_stage_api.py +117 -0
- com/xebialabs/xlrelease/api/v1/folder_api.py +634 -0
- com/xebialabs/xlrelease/api/v1/folder_versioning_api.py +344 -0
- com/xebialabs/xlrelease/api/v1/permissions_api.py +25 -0
- com/xebialabs/xlrelease/api/v1/phase_api.py +185 -0
- com/xebialabs/xlrelease/api/v1/release_api.py +493 -0
- com/xebialabs/xlrelease/api/v1/report_api.py +83 -0
- com/xebialabs/xlrelease/api/v1/risk_api.py +187 -0
- com/xebialabs/xlrelease/api/v1/roles_api.py +138 -0
- com/xebialabs/xlrelease/api/v1/search_api.py +136 -0
- com/xebialabs/xlrelease/api/v1/settings_api.py +26 -0
- com/xebialabs/xlrelease/api/v1/task_api.py +482 -0
- com/xebialabs/xlrelease/api/v1/task_reporting_api.py +77 -0
- com/xebialabs/xlrelease/api/v1/team_api.py +194 -0
- com/xebialabs/xlrelease/api/v1/template_api.py +383 -0
- com/xebialabs/xlrelease/api/v1/triggers_api.py +173 -0
- com/xebialabs/xlrelease/api/v1/user_api.py +157 -0
- com/xebialabs/xlrelease/api/v1/variable_api.py +137 -0
- com/xebialabs/xlrelease/domain/__init__.py +150 -0
- com/xebialabs/xlrelease/domain/activity_log.py +16 -0
- com/xebialabs/xlrelease/domain/attachment.py +15 -0
- com/xebialabs/xlrelease/domain/base.py +43 -0
- com/xebialabs/xlrelease/domain/category.py +26 -0
- com/xebialabs/xlrelease/domain/configuration.py +24 -0
- com/xebialabs/xlrelease/domain/delivery.py +86 -0
- com/xebialabs/xlrelease/domain/environment.py +106 -0
- com/xebialabs/xlrelease/domain/folder.py +13 -0
- com/xebialabs/xlrelease/domain/forms.py +79 -0
- com/xebialabs/xlrelease/domain/gate.py +21 -0
- com/xebialabs/xlrelease/domain/phase.py +26 -0
- com/xebialabs/xlrelease/domain/release.py +67 -0
- com/xebialabs/xlrelease/domain/reporting.py +49 -0
- com/xebialabs/xlrelease/domain/risk.py +52 -0
- com/xebialabs/xlrelease/domain/role.py +21 -0
- com/xebialabs/xlrelease/domain/task.py +43 -0
- com/xebialabs/xlrelease/domain/team.py +22 -0
- com/xebialabs/xlrelease/domain/trigger.py +21 -0
- com/xebialabs/xlrelease/domain/user.py +18 -0
- com/xebialabs/xlrelease/domain/variable.py +20 -0
- com/xebialabs/xlrelease/domain/versioning.py +87 -0
- com/xebialabs/xlrelease/scripting/__init__.py +18 -0
- com/xebialabs/xlrelease/scripting/dictionary.py +85 -0
- com/xebialabs/xlrelease/scripting/external_property.py +37 -0
- com/xebialabs/xlrelease/scripting/logger.py +71 -0
- digitalai_release_api_client-26.3.0b1.dist-info/METADATA +137 -0
- digitalai_release_api_client-26.3.0b1.dist-info/RECORD +66 -0
- digitalai_release_api_client-26.3.0b1.dist-info/WHEEL +4 -0
- digitalai_release_api_client-26.3.0b1.dist-info/licenses/LICENSE +21 -0
com/__init__.py
ADDED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
from com.xebialabs.xlrelease.api.v1.activity_logs_api import ActivityLogsApi
|
|
2
|
+
from com.xebialabs.xlrelease.api.v1.application_api import ApplicationApi
|
|
3
|
+
from com.xebialabs.xlrelease.api.v1.archive_api import ArchiveApi
|
|
4
|
+
from com.xebialabs.xlrelease.api.v1.attachment_api import AttachmentApi
|
|
5
|
+
from com.xebialabs.xlrelease.api.v1.category_api import CategoryApi
|
|
6
|
+
from com.xebialabs.xlrelease.api.v1.configuration_api import ConfigurationApi
|
|
7
|
+
from com.xebialabs.xlrelease.api.v1.delivery_api import DeliveryApi
|
|
8
|
+
from com.xebialabs.xlrelease.api.v1.delivery_pattern_api import DeliveryPatternApi
|
|
9
|
+
from com.xebialabs.xlrelease.api.v1.dsl_api import DslApi
|
|
10
|
+
from com.xebialabs.xlrelease.api.v1.environment_api import EnvironmentApi
|
|
11
|
+
from com.xebialabs.xlrelease.api.v1.environment_label_api import EnvironmentLabelApi
|
|
12
|
+
from com.xebialabs.xlrelease.api.v1.environment_reservation_api import (
|
|
13
|
+
EnvironmentReservationApi,
|
|
14
|
+
)
|
|
15
|
+
from com.xebialabs.xlrelease.api.v1.environment_stage_api import EnvironmentStageApi
|
|
16
|
+
from com.xebialabs.xlrelease.api.v1.folder_api import FolderApi
|
|
17
|
+
from com.xebialabs.xlrelease.api.v1.folder_versioning_api import FolderVersioningApi
|
|
18
|
+
from com.xebialabs.xlrelease.api.v1.permissions_api import PermissionsApi
|
|
19
|
+
from com.xebialabs.xlrelease.api.v1.phase_api import PhaseApi
|
|
20
|
+
from com.xebialabs.xlrelease.api.v1.release_api import ReleaseApi
|
|
21
|
+
from com.xebialabs.xlrelease.api.v1.report_api import ReportApi
|
|
22
|
+
from com.xebialabs.xlrelease.api.v1.risk_api import RiskApi
|
|
23
|
+
from com.xebialabs.xlrelease.api.v1.roles_api import RolesApi
|
|
24
|
+
from com.xebialabs.xlrelease.api.v1.search_api import SearchApi
|
|
25
|
+
from com.xebialabs.xlrelease.api.v1.task_api import TaskApi
|
|
26
|
+
from com.xebialabs.xlrelease.api.v1.task_reporting_api import TaskReportingApi
|
|
27
|
+
from com.xebialabs.xlrelease.api.v1.team_api import TeamApi
|
|
28
|
+
from com.xebialabs.xlrelease.api.v1.template_api import TemplateApi
|
|
29
|
+
from com.xebialabs.xlrelease.api.v1.triggers_api import TriggersApi
|
|
30
|
+
from com.xebialabs.xlrelease.api.v1.user_api import UserApi
|
|
31
|
+
from com.xebialabs.xlrelease.api.v1.variable_api import VariableApi
|
|
32
|
+
|
|
33
|
+
__all__ = [
|
|
34
|
+
"ActivityLogsApi",
|
|
35
|
+
"ApplicationApi",
|
|
36
|
+
"ArchiveApi",
|
|
37
|
+
"AttachmentApi",
|
|
38
|
+
"CategoryApi",
|
|
39
|
+
"ConfigurationApi",
|
|
40
|
+
"DeliveryApi",
|
|
41
|
+
"DeliveryPatternApi",
|
|
42
|
+
"DslApi",
|
|
43
|
+
"EnvironmentApi",
|
|
44
|
+
"EnvironmentLabelApi",
|
|
45
|
+
"EnvironmentReservationApi",
|
|
46
|
+
"EnvironmentStageApi",
|
|
47
|
+
"FolderApi",
|
|
48
|
+
"FolderVersioningApi",
|
|
49
|
+
"PermissionsApi",
|
|
50
|
+
"PhaseApi",
|
|
51
|
+
"ReleaseApi",
|
|
52
|
+
"ReportApi",
|
|
53
|
+
"RiskApi",
|
|
54
|
+
"RolesApi",
|
|
55
|
+
"SearchApi",
|
|
56
|
+
"TaskApi",
|
|
57
|
+
"TaskReportingApi",
|
|
58
|
+
"TeamApi",
|
|
59
|
+
"TemplateApi",
|
|
60
|
+
"TriggersApi",
|
|
61
|
+
"UserApi",
|
|
62
|
+
"VariableApi",
|
|
63
|
+
]
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from digitalai.release.release_api_client import ReleaseAPIClient
|
|
4
|
+
|
|
5
|
+
from com.xebialabs.xlrelease.domain.activity_log import ActivityLogEntry
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ActivityLogsApi:
|
|
9
|
+
"""Operations on activity logs."""
|
|
10
|
+
|
|
11
|
+
def __init__(self, api: ReleaseAPIClient):
|
|
12
|
+
"""
|
|
13
|
+
Initializes the ActivityLogsApi.
|
|
14
|
+
|
|
15
|
+
:param api: an instance of ReleaseAPIClient used to make HTTP requests.
|
|
16
|
+
"""
|
|
17
|
+
self.api = api
|
|
18
|
+
|
|
19
|
+
def getActivityLogs(self, containerId: str) -> list[ActivityLogEntry]:
|
|
20
|
+
"""
|
|
21
|
+
Gets activity logs for a container (Release, Task, Delivery, or Trigger).
|
|
22
|
+
|
|
23
|
+
:param containerId: the container identifier.
|
|
24
|
+
:return: a list of activity log entries.
|
|
25
|
+
"""
|
|
26
|
+
response = self.api.get(f"/api/v1/activities/{containerId}")
|
|
27
|
+
return ActivityLogEntry.from_response_to_list(response)
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
from typing import Dict, Type, TypeVar
|
|
2
|
+
|
|
3
|
+
from digitalai.release.integration import BaseTask
|
|
4
|
+
from digitalai.release.release_api_client import ReleaseAPIClient
|
|
5
|
+
|
|
6
|
+
from com.xebialabs.xlrelease.domain.folder import Folder
|
|
7
|
+
from com.xebialabs.xlrelease.domain.phase import Phase
|
|
8
|
+
from com.xebialabs.xlrelease.domain.release import Release
|
|
9
|
+
from com.xebialabs.xlrelease.domain.task import Task
|
|
10
|
+
|
|
11
|
+
from com.xebialabs.xlrelease.api.v1.activity_logs_api import ActivityLogsApi
|
|
12
|
+
from com.xebialabs.xlrelease.api.v1.application_api import ApplicationApi
|
|
13
|
+
from com.xebialabs.xlrelease.api.v1.archive_api import ArchiveApi
|
|
14
|
+
from com.xebialabs.xlrelease.api.v1.attachment_api import AttachmentApi
|
|
15
|
+
from com.xebialabs.xlrelease.api.v1.category_api import CategoryApi
|
|
16
|
+
from com.xebialabs.xlrelease.api.v1.configuration_api import ConfigurationApi
|
|
17
|
+
from com.xebialabs.xlrelease.api.v1.delivery_api import DeliveryApi
|
|
18
|
+
from com.xebialabs.xlrelease.api.v1.delivery_pattern_api import DeliveryPatternApi
|
|
19
|
+
from com.xebialabs.xlrelease.api.v1.dsl_api import DslApi
|
|
20
|
+
from com.xebialabs.xlrelease.api.v1.environment_api import EnvironmentApi
|
|
21
|
+
from com.xebialabs.xlrelease.api.v1.environment_label_api import EnvironmentLabelApi
|
|
22
|
+
from com.xebialabs.xlrelease.api.v1.environment_reservation_api import (
|
|
23
|
+
EnvironmentReservationApi,
|
|
24
|
+
)
|
|
25
|
+
from com.xebialabs.xlrelease.api.v1.environment_stage_api import EnvironmentStageApi
|
|
26
|
+
from com.xebialabs.xlrelease.api.v1.folder_api import FolderApi
|
|
27
|
+
from com.xebialabs.xlrelease.api.v1.folder_versioning_api import FolderVersioningApi
|
|
28
|
+
from com.xebialabs.xlrelease.api.v1.permissions_api import PermissionsApi
|
|
29
|
+
from com.xebialabs.xlrelease.api.v1.phase_api import PhaseApi
|
|
30
|
+
from com.xebialabs.xlrelease.api.v1.release_api import ReleaseApi
|
|
31
|
+
from com.xebialabs.xlrelease.api.v1.report_api import ReportApi
|
|
32
|
+
from com.xebialabs.xlrelease.api.v1.risk_api import RiskApi
|
|
33
|
+
from com.xebialabs.xlrelease.api.v1.roles_api import RolesApi
|
|
34
|
+
from com.xebialabs.xlrelease.api.v1.search_api import SearchApi
|
|
35
|
+
from com.xebialabs.xlrelease.api.v1.settings_api import SettingsApi
|
|
36
|
+
from com.xebialabs.xlrelease.api.v1.task_api import TaskApi
|
|
37
|
+
from com.xebialabs.xlrelease.api.v1.task_reporting_api import TaskReportingApi
|
|
38
|
+
from com.xebialabs.xlrelease.api.v1.team_api import TeamApi
|
|
39
|
+
from com.xebialabs.xlrelease.api.v1.template_api import TemplateApi
|
|
40
|
+
from com.xebialabs.xlrelease.api.v1.triggers_api import TriggersApi
|
|
41
|
+
from com.xebialabs.xlrelease.api.v1.user_api import UserApi
|
|
42
|
+
from com.xebialabs.xlrelease.api.v1.variable_api import VariableApi
|
|
43
|
+
|
|
44
|
+
T = TypeVar("T")
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class ApiBaseTask(BaseTask):
|
|
48
|
+
"""
|
|
49
|
+
Base class for Release container tasks that need the v1 REST API.
|
|
50
|
+
|
|
51
|
+
Subclass this instead of :class:`BaseTask` to get a ready-to-use, lazily
|
|
52
|
+
created instance of every ``com.xebialabs.xlrelease.api.v1`` wrapper as a
|
|
53
|
+
property (``releaseApi``, ``phaseApi``, ``taskApi``, ...). All wrappers
|
|
54
|
+
share a single :class:`ReleaseAPIClient` built from the task's
|
|
55
|
+
"Run as user" context, so the client and each API object are created only
|
|
56
|
+
once and only when first accessed.
|
|
57
|
+
|
|
58
|
+
Example::
|
|
59
|
+
|
|
60
|
+
class MyTask(ApiBaseTask):
|
|
61
|
+
def execute(self) -> None:
|
|
62
|
+
release = self.releaseApi.getRelease(self.get_release_id())
|
|
63
|
+
self.add_comment(f"Working on {release.title}")
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
def __init__(self):
|
|
67
|
+
super().__init__()
|
|
68
|
+
self._api_client: ReleaseAPIClient = None
|
|
69
|
+
self._api_instances: Dict[Type, object] = {}
|
|
70
|
+
|
|
71
|
+
# -- client / instance management ---------------------------------------
|
|
72
|
+
|
|
73
|
+
@property
|
|
74
|
+
def apiClient(self) -> ReleaseAPIClient:
|
|
75
|
+
"""The shared :class:`ReleaseAPIClient`, created on first access."""
|
|
76
|
+
if self._api_client is None:
|
|
77
|
+
self._api_client = self.get_release_api_client()
|
|
78
|
+
return self._api_client
|
|
79
|
+
|
|
80
|
+
def _api(self, api_class: Type[T]) -> T:
|
|
81
|
+
"""Return a cached instance of ``api_class``, creating it on first use."""
|
|
82
|
+
instance = self._api_instances.get(api_class)
|
|
83
|
+
if instance is None:
|
|
84
|
+
instance = api_class(self.apiClient)
|
|
85
|
+
self._api_instances[api_class] = instance
|
|
86
|
+
return instance
|
|
87
|
+
|
|
88
|
+
def reset_api_clients(self) -> None:
|
|
89
|
+
"""Drop the cached client and API instances (e.g. to re-authenticate)."""
|
|
90
|
+
self._api_client = None
|
|
91
|
+
self._api_instances = {}
|
|
92
|
+
|
|
93
|
+
# -- API wrappers -------------------------------------------------------
|
|
94
|
+
|
|
95
|
+
@property
|
|
96
|
+
def activityLogsApi(self) -> ActivityLogsApi:
|
|
97
|
+
return self._api(ActivityLogsApi)
|
|
98
|
+
|
|
99
|
+
@property
|
|
100
|
+
def applicationApi(self) -> ApplicationApi:
|
|
101
|
+
return self._api(ApplicationApi)
|
|
102
|
+
|
|
103
|
+
@property
|
|
104
|
+
def archiveApi(self) -> ArchiveApi:
|
|
105
|
+
return self._api(ArchiveApi)
|
|
106
|
+
|
|
107
|
+
@property
|
|
108
|
+
def attachmentApi(self) -> AttachmentApi:
|
|
109
|
+
return self._api(AttachmentApi)
|
|
110
|
+
|
|
111
|
+
@property
|
|
112
|
+
def categoryApi(self) -> CategoryApi:
|
|
113
|
+
return self._api(CategoryApi)
|
|
114
|
+
|
|
115
|
+
@property
|
|
116
|
+
def configurationApi(self) -> ConfigurationApi:
|
|
117
|
+
return self._api(ConfigurationApi)
|
|
118
|
+
|
|
119
|
+
@property
|
|
120
|
+
def deliveryApi(self) -> DeliveryApi:
|
|
121
|
+
return self._api(DeliveryApi)
|
|
122
|
+
|
|
123
|
+
@property
|
|
124
|
+
def deliveryPatternApi(self) -> DeliveryPatternApi:
|
|
125
|
+
return self._api(DeliveryPatternApi)
|
|
126
|
+
|
|
127
|
+
@property
|
|
128
|
+
def dslApi(self) -> DslApi:
|
|
129
|
+
return self._api(DslApi)
|
|
130
|
+
|
|
131
|
+
@property
|
|
132
|
+
def environmentApi(self) -> EnvironmentApi:
|
|
133
|
+
return self._api(EnvironmentApi)
|
|
134
|
+
|
|
135
|
+
@property
|
|
136
|
+
def environmentLabelApi(self) -> EnvironmentLabelApi:
|
|
137
|
+
return self._api(EnvironmentLabelApi)
|
|
138
|
+
|
|
139
|
+
@property
|
|
140
|
+
def environmentReservationApi(self) -> EnvironmentReservationApi:
|
|
141
|
+
return self._api(EnvironmentReservationApi)
|
|
142
|
+
|
|
143
|
+
@property
|
|
144
|
+
def environmentStageApi(self) -> EnvironmentStageApi:
|
|
145
|
+
return self._api(EnvironmentStageApi)
|
|
146
|
+
|
|
147
|
+
@property
|
|
148
|
+
def folderApi(self) -> FolderApi:
|
|
149
|
+
return self._api(FolderApi)
|
|
150
|
+
|
|
151
|
+
@property
|
|
152
|
+
def folderVersioningApi(self) -> FolderVersioningApi:
|
|
153
|
+
return self._api(FolderVersioningApi)
|
|
154
|
+
|
|
155
|
+
@property
|
|
156
|
+
def permissionsApi(self) -> PermissionsApi:
|
|
157
|
+
return self._api(PermissionsApi)
|
|
158
|
+
|
|
159
|
+
@property
|
|
160
|
+
def phaseApi(self) -> PhaseApi:
|
|
161
|
+
return self._api(PhaseApi)
|
|
162
|
+
|
|
163
|
+
@property
|
|
164
|
+
def releaseApi(self) -> ReleaseApi:
|
|
165
|
+
return self._api(ReleaseApi)
|
|
166
|
+
|
|
167
|
+
@property
|
|
168
|
+
def reportApi(self) -> ReportApi:
|
|
169
|
+
return self._api(ReportApi)
|
|
170
|
+
|
|
171
|
+
@property
|
|
172
|
+
def riskApi(self) -> RiskApi:
|
|
173
|
+
return self._api(RiskApi)
|
|
174
|
+
|
|
175
|
+
@property
|
|
176
|
+
def rolesApi(self) -> RolesApi:
|
|
177
|
+
return self._api(RolesApi)
|
|
178
|
+
|
|
179
|
+
@property
|
|
180
|
+
def searchApi(self) -> SearchApi:
|
|
181
|
+
return self._api(SearchApi)
|
|
182
|
+
|
|
183
|
+
@property
|
|
184
|
+
def settingsApi(self) -> SettingsApi:
|
|
185
|
+
return self._api(SettingsApi)
|
|
186
|
+
|
|
187
|
+
@property
|
|
188
|
+
def taskApi(self) -> TaskApi:
|
|
189
|
+
return self._api(TaskApi)
|
|
190
|
+
|
|
191
|
+
@property
|
|
192
|
+
def taskReportingApi(self) -> TaskReportingApi:
|
|
193
|
+
return self._api(TaskReportingApi)
|
|
194
|
+
|
|
195
|
+
@property
|
|
196
|
+
def teamApi(self) -> TeamApi:
|
|
197
|
+
return self._api(TeamApi)
|
|
198
|
+
|
|
199
|
+
@property
|
|
200
|
+
def templateApi(self) -> TemplateApi:
|
|
201
|
+
return self._api(TemplateApi)
|
|
202
|
+
|
|
203
|
+
@property
|
|
204
|
+
def triggersApi(self) -> TriggersApi:
|
|
205
|
+
return self._api(TriggersApi)
|
|
206
|
+
|
|
207
|
+
@property
|
|
208
|
+
def userApi(self) -> UserApi:
|
|
209
|
+
return self._api(UserApi)
|
|
210
|
+
|
|
211
|
+
@property
|
|
212
|
+
def variableApi(self) -> VariableApi:
|
|
213
|
+
return self._api(VariableApi)
|
|
214
|
+
|
|
215
|
+
# -- current-context helpers --------------------------------------------
|
|
216
|
+
# Convenience methods that resolve the release object the task is running
|
|
217
|
+
# in, mirroring the helpers the Jython script API offers on the server
|
|
218
|
+
# (XLReleaseApi.py). Each derives the relevant id from the task's context
|
|
219
|
+
# and fetches the object through the matching API wrapper above.
|
|
220
|
+
|
|
221
|
+
def getCurrentTask(self) -> Task:
|
|
222
|
+
"""
|
|
223
|
+
Return the task that is running this code.
|
|
224
|
+
|
|
225
|
+
Fetches the task via ``taskApi`` using the task's own id.
|
|
226
|
+
"""
|
|
227
|
+
return self.taskApi.getTask(self.get_task_id())
|
|
228
|
+
|
|
229
|
+
def getCurrentPhase(self) -> Phase:
|
|
230
|
+
"""
|
|
231
|
+
Return the phase that contains this task.
|
|
232
|
+
|
|
233
|
+
The phase id is derived from the task id, then fetched via ``phaseApi``.
|
|
234
|
+
"""
|
|
235
|
+
return self.phaseApi.getPhase(self.get_phase_id())
|
|
236
|
+
|
|
237
|
+
def getCurrentRelease(self) -> Release:
|
|
238
|
+
"""
|
|
239
|
+
Return the release this task belongs to.
|
|
240
|
+
|
|
241
|
+
Fetches the release via ``releaseApi`` using the task's release id, so
|
|
242
|
+
the caller does not need to know or substitute the id itself.
|
|
243
|
+
"""
|
|
244
|
+
return self.releaseApi.getRelease(self.get_release_id())
|
|
245
|
+
|
|
246
|
+
def getCurrentFolder(self) -> Folder:
|
|
247
|
+
"""
|
|
248
|
+
Return the folder that contains the current release.
|
|
249
|
+
|
|
250
|
+
The folder id is derived from the release id, then fetched via
|
|
251
|
+
``folderApi``.
|
|
252
|
+
"""
|
|
253
|
+
return self.folderApi.getFolder(self.get_folder_id())
|
|
254
|
+
|
|
255
|
+
def getTasksByTitle(self, taskTitle: str, phaseTitle: str | None = None,
|
|
256
|
+
releaseId: str | None = None) -> list[Task]:
|
|
257
|
+
"""
|
|
258
|
+
Find tasks by title.
|
|
259
|
+
|
|
260
|
+
:param taskTitle: the task title to search for.
|
|
261
|
+
:param phaseTitle: optional phase title to scope the search; searches the
|
|
262
|
+
whole release when omitted.
|
|
263
|
+
:param releaseId: optional release to search; the current release when
|
|
264
|
+
omitted.
|
|
265
|
+
:return: the matching tasks.
|
|
266
|
+
"""
|
|
267
|
+
return self.taskApi.searchTasksByTitle(
|
|
268
|
+
taskTitle, releaseId or self.get_release_id(), phaseTitle)
|
|
269
|
+
|
|
270
|
+
def getPhasesByTitle(self, phaseTitle: str,
|
|
271
|
+
releaseId: str | None = None) -> list[Phase]:
|
|
272
|
+
"""
|
|
273
|
+
Find phases by title.
|
|
274
|
+
|
|
275
|
+
:param phaseTitle: the phase title to search for.
|
|
276
|
+
:param releaseId: optional release to search; the current release when
|
|
277
|
+
omitted.
|
|
278
|
+
:return: the matching phases.
|
|
279
|
+
"""
|
|
280
|
+
return self.phaseApi.searchPhasesByTitle(
|
|
281
|
+
phaseTitle, releaseId or self.get_release_id())
|
|
282
|
+
|
|
283
|
+
def getReleasesByTitle(self, releaseTitle: str) -> list[Release]:
|
|
284
|
+
"""
|
|
285
|
+
Find releases by title.
|
|
286
|
+
|
|
287
|
+
:param releaseTitle: the release title to search for.
|
|
288
|
+
:return: the matching releases.
|
|
289
|
+
"""
|
|
290
|
+
return self.releaseApi.searchReleasesByTitle(releaseTitle)
|
|
291
|
+
|
|
292
|
+
def getVersion(self) -> str | None:
|
|
293
|
+
"""
|
|
294
|
+
Return the version of this Digital.ai Release instance.
|
|
295
|
+
"""
|
|
296
|
+
return self.settingsApi.getInstanceInformation().get('version')
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from digitalai.release.release_api_client import ReleaseAPIClient
|
|
4
|
+
|
|
5
|
+
from com.xebialabs.xlrelease.domain.environment import (
|
|
6
|
+
Application,
|
|
7
|
+
ApplicationFilters,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ApplicationApi:
|
|
12
|
+
"""Operations on applications."""
|
|
13
|
+
|
|
14
|
+
def __init__(self, api: ReleaseAPIClient):
|
|
15
|
+
"""
|
|
16
|
+
Initializes the ApplicationApi.
|
|
17
|
+
|
|
18
|
+
:param api: an instance of ReleaseAPIClient used to make HTTP requests.
|
|
19
|
+
"""
|
|
20
|
+
self.api = api
|
|
21
|
+
|
|
22
|
+
def createApplication(self, applicationForm: Application) -> Application:
|
|
23
|
+
"""
|
|
24
|
+
Creates a new application.
|
|
25
|
+
|
|
26
|
+
:param applicationForm: an Application (form) describing the new application.
|
|
27
|
+
:return: the created application.
|
|
28
|
+
"""
|
|
29
|
+
response = self.api.post(
|
|
30
|
+
"/api/v1/applications",
|
|
31
|
+
json=applicationForm.model_dump(exclude_none=True)
|
|
32
|
+
)
|
|
33
|
+
return Application.from_response(response)
|
|
34
|
+
|
|
35
|
+
def getApplication(self, applicationId: str) -> Application:
|
|
36
|
+
"""
|
|
37
|
+
Gets an application by id.
|
|
38
|
+
|
|
39
|
+
:param applicationId: the application identifier.
|
|
40
|
+
:return: the application.
|
|
41
|
+
"""
|
|
42
|
+
response = self.api.get(f"/api/v1/applications/{applicationId}")
|
|
43
|
+
return Application.from_response(response)
|
|
44
|
+
|
|
45
|
+
def updateApplication(self, applicationId: str, applicationForm: Application) -> Application:
|
|
46
|
+
"""
|
|
47
|
+
Updates an existing application.
|
|
48
|
+
|
|
49
|
+
:param applicationId: the application identifier.
|
|
50
|
+
:param applicationForm: an Application (form) describing the new properties.
|
|
51
|
+
:return: the updated application.
|
|
52
|
+
"""
|
|
53
|
+
response = self.api.put(
|
|
54
|
+
f"/api/v1/applications/{applicationId}",
|
|
55
|
+
json=applicationForm.model_dump(exclude_none=True)
|
|
56
|
+
)
|
|
57
|
+
return Application.from_response(response)
|
|
58
|
+
|
|
59
|
+
def searchApplications(self, applicationFilters: ApplicationFilters | None = None) -> list[Application]:
|
|
60
|
+
"""
|
|
61
|
+
Searches applications by filters.
|
|
62
|
+
|
|
63
|
+
:param applicationFilters: the search criteria.
|
|
64
|
+
:return: the list of matching applications.
|
|
65
|
+
"""
|
|
66
|
+
body = applicationFilters.model_dump(exclude_none=True) if applicationFilters else {}
|
|
67
|
+
response = self.api.post("/api/v1/applications/search", json=body)
|
|
68
|
+
return Application.from_response_to_list(response)
|
|
69
|
+
|
|
70
|
+
def deleteApplication(self, applicationId: str) -> None:
|
|
71
|
+
"""
|
|
72
|
+
Deletes an application.
|
|
73
|
+
|
|
74
|
+
:param applicationId: the application identifier.
|
|
75
|
+
"""
|
|
76
|
+
response = self.api.delete(f"/api/v1/applications/{applicationId}")
|
|
77
|
+
response.raise_for_status()
|
|
78
|
+
|
|
79
|
+
# --- Convenience aliases matching the Jython script API ---
|
|
80
|
+
|
|
81
|
+
def create(self, application: Application) -> Application:
|
|
82
|
+
"""
|
|
83
|
+
Creates a new application.
|
|
84
|
+
|
|
85
|
+
:param application: an Application object describing the new application.
|
|
86
|
+
:return: the created application.
|
|
87
|
+
"""
|
|
88
|
+
return self.createApplication(application)
|
|
89
|
+
|
|
90
|
+
def update(self, application: Application) -> Application:
|
|
91
|
+
"""
|
|
92
|
+
Updates an existing application.
|
|
93
|
+
|
|
94
|
+
:param application: an Application object describing the new properties.
|
|
95
|
+
:return: the updated application.
|
|
96
|
+
"""
|
|
97
|
+
if not application.id:
|
|
98
|
+
raise ValueError("application.id must be set to update an application")
|
|
99
|
+
return self.updateApplication(application.id, application)
|
|
100
|
+
|
|
101
|
+
def search(self, filters: ApplicationFilters | None = None) -> list[Application]:
|
|
102
|
+
"""
|
|
103
|
+
Searches applications by filters.
|
|
104
|
+
|
|
105
|
+
:param filters: the search criteria.
|
|
106
|
+
:return: the list of matching applications.
|
|
107
|
+
"""
|
|
108
|
+
return self.searchApplications(filters)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from digitalai.release.release_api_client import ReleaseAPIClient
|
|
4
|
+
|
|
5
|
+
from com.xebialabs.xlrelease.domain.release import Release
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ArchiveApi:
|
|
9
|
+
"""Operations on archived releases."""
|
|
10
|
+
|
|
11
|
+
def __init__(self, api: ReleaseAPIClient):
|
|
12
|
+
"""
|
|
13
|
+
Initializes the ArchiveApi.
|
|
14
|
+
|
|
15
|
+
:param api: an instance of ReleaseAPIClient used to make HTTP requests.
|
|
16
|
+
"""
|
|
17
|
+
self.api = api
|
|
18
|
+
|
|
19
|
+
def getArchivedRelease(self, releaseId: str) -> Release:
|
|
20
|
+
"""
|
|
21
|
+
Returns the archived release for the given ID.
|
|
22
|
+
|
|
23
|
+
:param releaseId: the identifier of the release.
|
|
24
|
+
:return: the archived release.
|
|
25
|
+
"""
|
|
26
|
+
response = self.api.get(f"/api/v1/releases/archived/{releaseId}")
|
|
27
|
+
return Release.from_response(response)
|
|
28
|
+
|
|
29
|
+
def searchArchivedReleases(
|
|
30
|
+
self,
|
|
31
|
+
title: str | None = None,
|
|
32
|
+
tags: list[str] | None = None,
|
|
33
|
+
page: int | None = None,
|
|
34
|
+
resultsPerPage: int | None = None
|
|
35
|
+
) -> list[Release]:
|
|
36
|
+
"""
|
|
37
|
+
Searches archived releases.
|
|
38
|
+
|
|
39
|
+
:param title: filter by release title.
|
|
40
|
+
:param tags: filter by release tags.
|
|
41
|
+
:param page: the page of results to return.
|
|
42
|
+
:param resultsPerPage: the number of results per page.
|
|
43
|
+
:return: the list of matching archived releases.
|
|
44
|
+
"""
|
|
45
|
+
body = {"onlyArchived": True}
|
|
46
|
+
if title is not None:
|
|
47
|
+
body["title"] = title
|
|
48
|
+
if tags is not None:
|
|
49
|
+
body["tags"] = tags
|
|
50
|
+
params = {}
|
|
51
|
+
if page is not None:
|
|
52
|
+
params["page"] = page
|
|
53
|
+
if resultsPerPage is not None:
|
|
54
|
+
params["resultsPerPage"] = resultsPerPage
|
|
55
|
+
response = self.api.post("/api/v1/releases/search", json=body, params=params)
|
|
56
|
+
return Release.from_response_to_list(response)
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from digitalai.release.release_api_client import ReleaseAPIClient
|
|
4
|
+
|
|
5
|
+
from com.xebialabs.xlrelease.domain.attachment import Attachment
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class AttachmentApi:
|
|
9
|
+
"""Operations on attachments."""
|
|
10
|
+
|
|
11
|
+
def __init__(self, api: ReleaseAPIClient):
|
|
12
|
+
"""
|
|
13
|
+
Initializes the AttachmentApi.
|
|
14
|
+
|
|
15
|
+
:param api: an instance of ReleaseAPIClient used to make HTTP requests.
|
|
16
|
+
"""
|
|
17
|
+
self.api = api
|
|
18
|
+
|
|
19
|
+
def getAttachment(self, attachmentId: str) -> bytes:
|
|
20
|
+
"""
|
|
21
|
+
Returns the attachment file with the given ID.
|
|
22
|
+
|
|
23
|
+
:param attachmentId: the identifier of the attachment.
|
|
24
|
+
:return: the attachment file content as bytes.
|
|
25
|
+
"""
|
|
26
|
+
response = self.api.get(
|
|
27
|
+
f"/api/v1/releases/attachments/{attachmentId}",
|
|
28
|
+
headers={"Accept": "application/octet-stream"}
|
|
29
|
+
)
|
|
30
|
+
response.raise_for_status()
|
|
31
|
+
return response.content
|
|
32
|
+
|
|
33
|
+
def addAttachment(self, taskId: str, fileName: str, fileBytes: bytes) -> Attachment:
|
|
34
|
+
"""
|
|
35
|
+
Adds one attachment file to a task.
|
|
36
|
+
|
|
37
|
+
:param taskId: the task identifier.
|
|
38
|
+
:param fileName: the name of the attachment file.
|
|
39
|
+
:param fileBytes: the file content as bytes.
|
|
40
|
+
:return: the domain object of the uploaded attachment.
|
|
41
|
+
"""
|
|
42
|
+
files = {"file": (fileName, fileBytes)}
|
|
43
|
+
response = self.api.post(
|
|
44
|
+
f"/api/v1/tasks/{taskId}/attachments",
|
|
45
|
+
files=files
|
|
46
|
+
)
|
|
47
|
+
response.raise_for_status()
|
|
48
|
+
data = response.json()
|
|
49
|
+
if isinstance(data, list):
|
|
50
|
+
return Attachment.model_validate(data[0])
|
|
51
|
+
return Attachment.model_validate(data)
|
|
52
|
+
|
|
53
|
+
def addAttachments(self, taskId: str, fileList: list[tuple[str, bytes]]) -> list[Attachment]:
|
|
54
|
+
"""
|
|
55
|
+
Adds multiple attachment files to a task.
|
|
56
|
+
|
|
57
|
+
:param taskId: the task identifier.
|
|
58
|
+
:param fileList: list of (fileName, fileBytes) tuples.
|
|
59
|
+
:return: list of uploaded Attachment domain objects.
|
|
60
|
+
"""
|
|
61
|
+
files = [("file", (name, content)) for name, content in fileList]
|
|
62
|
+
response = self.api.post(
|
|
63
|
+
f"/api/v1/tasks/{taskId}/attachments",
|
|
64
|
+
files=files
|
|
65
|
+
)
|
|
66
|
+
response.raise_for_status()
|
|
67
|
+
data = response.json()
|
|
68
|
+
if isinstance(data, list):
|
|
69
|
+
return [Attachment.model_validate(item) for item in data]
|
|
70
|
+
return [Attachment.model_validate(data)]
|
|
71
|
+
|
|
72
|
+
def deleteAttachment(self, taskId: str, attachmentId: str) -> None:
|
|
73
|
+
"""
|
|
74
|
+
Deletes an attachment from a task.
|
|
75
|
+
|
|
76
|
+
:param taskId: the task identifier.
|
|
77
|
+
:param attachmentId: the attachment identifier.
|
|
78
|
+
"""
|
|
79
|
+
response = self.api.delete(f"/api/v1/tasks/{taskId}/attachments/{attachmentId}")
|
|
80
|
+
response.raise_for_status()
|