| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -242,7 +242,12 @@ List the jobs of a pipeline:: | |||
| 242 | 242 | ||
| 243 | 243 | Get the artifacts of a job:: | |
| 244 | 244 | ||
| 245 | - build_or_job.artifacts() | ||
| 245 | + job.artifacts.download() | ||
| 246 | + | ||
| 247 | + .. attention:: | ||
| 248 | + | ||
| 249 | + An older method ``job.artifacts()`` is deprecated and will be | ||
| 250 | + removed in a future version. | ||
| 246 | 251 | ||
| 247 | 252 | Get the artifacts of a job by its name from the latest successful pipeline of | |
| 248 | 253 | a branch or tag:: | |
@@ -264,13 +269,13 @@ You can download artifacts as a stream. Provide a callable to handle the | |||
| 264 | 269 | stream:: | |
| 265 | 270 | ||
| 266 | 271 | with open("archive.zip", "wb") as f: | |
| 267 | - build_or_job.artifacts(streamed=True, action=f.write) | ||
| 272 | + job.artifacts.download(streamed=True, action=f.write) | ||
| 268 | 273 | ||
| 269 | 274 | You can also directly stream the output into a file, and unzip it afterwards:: | |
| 270 | 275 | ||
| 271 | 276 | zipfn = "___artifacts.zip" | |
| 272 | 277 | with open(zipfn, "wb") as f: | |
| 273 | - build_or_job.artifacts(streamed=True, action=f.write) | ||
| 278 | + job.artifacts.download(streamed=True, action=f.write) | ||
| 274 | 279 | subprocess.run(["unzip", "-bo", zipfn]) | |
| 275 | 280 | os.unlink(zipfn) | |
| 276 | 281 | ||
@@ -293,7 +298,12 @@ Delete all artifacts of a project that can be deleted:: | |||
| 293 | 298 | ||
| 294 | 299 | Get a single artifact file:: | |
| 295 | 300 | ||
| 296 | - build_or_job.artifact('path/to/file') | ||
| 301 | + job.artifacts.raw('path/to/file') | ||
| 302 | + | ||
| 303 | + .. attention:: | ||
| 304 | + | ||
| 305 | + An older method ``job.artifact()`` is deprecated and will be | ||
| 306 | + removed in a future version. | ||
| 297 | 307 | ||
| 298 | 308 | Get a single artifact file by branch and job:: | |
| 299 | 309 | ||
@@ -306,15 +316,15 @@ Get a single artifact file by branch and job:: | |||
| 306 | 316 | ||
| 307 | 317 | Mark a job artifact as kept when expiration is set:: | |
| 308 | 318 | ||
| 309 | - build_or_job.keep_artifacts() | ||
| 319 | + job.keep_artifacts() | ||
| 310 | 320 | ||
| 311 | 321 | Delete the artifacts of a job:: | |
| 312 | 322 | ||
| 313 | - build_or_job.delete_artifacts() | ||
| 323 | + job.delete_artifacts() | ||
| 314 | 324 | ||
| 315 | 325 | Get a job trace:: | |
| 316 | 326 | ||
| 317 | - build_or_job.trace() | ||
| 327 | + job.trace() | ||
| 318 | 328 | ||
| 319 | 329 | .. warning:: | |
| 320 | 330 | ||
@@ -323,16 +333,16 @@ Get a job trace:: | |||
| 323 | 333 | ||
| 324 | 334 | Cancel/retry a job:: | |
| 325 | 335 | ||
| 326 | - build_or_job.cancel() | ||
| 327 | - build_or_job.retry() | ||
| 336 | + job.cancel() | ||
| 337 | + job.retry() | ||
| 328 | 338 | ||
| 329 | 339 | Play (trigger) a job:: | |
| 330 | 340 | ||
| 331 | - build_or_job.play() | ||
| 341 | + job.play() | ||
| 332 | 342 | ||
| 333 | 343 | Erase a job (artifacts and trace):: | |
| 334 | 344 | ||
| 335 | - build_or_job.erase() | ||
| 345 | + job.erase() | ||
| 336 | 346 | ||
| 337 | 347 | ||
| 338 | 348 | Pipeline bridges | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2,6 +2,7 @@ | |||
| 2 | 2 | GitLab API: | |
| 3 | 3 | https://docs.gitlab.com/ee/api/job_artifacts.html | |
| 4 | 4 | """ | |
| 5 | + import warnings | ||
| 5 | 6 | from typing import Any, Callable, Iterator, Optional, TYPE_CHECKING, Union | |
| 6 | 7 | ||
| 7 | 8 | import requests | |
@@ -11,7 +12,12 @@ | |||
| 11 | 12 | from gitlab import utils | |
| 12 | 13 | from gitlab.base import RESTManager, RESTObject | |
| 13 | 14 | ||
| 14 | - __all__ = ["ProjectArtifact", "ProjectArtifactManager"] | ||
| 15 | + __all__ = [ | ||
| 16 | + "ProjectArtifact", | ||
| 17 | + "ProjectArtifactManager", | ||
| 18 | + "ProjectJobArtifact", | ||
| 19 | + "ProjectJobArtifactManager", | ||
| 20 | + ] | ||
| 15 | 21 | ||
| 16 | 22 | ||
| 17 | 23 | class ProjectArtifact(RESTObject): | |
@@ -165,3 +171,111 @@ def raw( | |||
| 165 | 171 | return utils.response_content( | |
| 166 | 172 | result, streamed, action, chunk_size, iterator=iterator | |
| 167 | 173 | ) | |
| 174 | + | ||
| 175 | + | ||
| 176 | + class ProjectJobArtifact(RESTObject): | ||
| 177 | + """Dummy object to manage custom actions on artifacts""" | ||
| 178 | + | ||
| 179 | + _id_attr = "artifact_path" | ||
| 180 | + | ||
| 181 | + | ||
| 182 | + class ProjectJobArtifactManager(RESTManager): | ||
| 183 | + _path = "/projects/{project_id}/jobs/{job_id}/artifacts" | ||
| 184 | + _from_parent_attrs = {"project_id": "project_id", "job_id": "id"} | ||
| 185 | + | ||
| 186 | + @cli.register_custom_action("ProjectJob", custom_action="artifacts") | ||
| 187 | + def __call__( | ||
| 188 | + self, | ||
| 189 | + *args: Any, | ||
| 190 | + **kwargs: Any, | ||
| 191 | + ) -> Optional[Union[bytes, Iterator[Any]]]: | ||
| 192 | + warnings.warn( | ||
| 193 | + "The job.artifacts() method is deprecated and will be " | ||
| 194 | + "removed in a future version. Use job.artifacts.download() instead.\n", | ||
| 195 | + DeprecationWarning, | ||
| 196 | + ) | ||
| 197 | + return self.download( | ||
| 198 | + *args, | ||
| 199 | + **kwargs, | ||
| 200 | + ) | ||
| 201 | + | ||
| 202 | + @cli.register_custom_action("ProjectJobArtifactManager") | ||
| 203 | + @exc.on_http_error(exc.GitlabGetError) | ||
| 204 | + def download( | ||
| 205 | + self, | ||
| 206 | + streamed: bool = False, | ||
| 207 | + action: Optional[Callable[..., Any]] = None, | ||
| 208 | + chunk_size: int = 1024, | ||
| 209 | + iterator: bool = False, | ||
| 210 | + **kwargs: Any, | ||
| 211 | + ) -> Optional[Union[bytes, Iterator[Any]]]: | ||
| 212 | + """Get the job artifacts. | ||
| 213 | + | ||
| 214 | + Args: | ||
| 215 | + streamed: If True the data will be processed by chunks of | ||
| 216 | + `chunk_size` and each chunk is passed to `action` for | ||
| 217 | + treatment | ||
| 218 | + action: Callable responsible of dealing with chunk of | ||
| 219 | + data | ||
| 220 | + chunk_size: Size of each chunk | ||
| 221 | + iterator: If True directly return the underlying response | ||
| 222 | + iterator | ||
| 223 | + **kwargs: Extra options to send to the server (e.g. sudo) | ||
| 224 | + | ||
| 225 | + Raises: | ||
| 226 | + GitlabAuthenticationError: If authentication is not correct | ||
| 227 | + GitlabGetError: If the artifacts could not be retrieved | ||
| 228 | + | ||
| 229 | + Returns: | ||
| 230 | + The artifacts if `streamed` is False, None otherwise. | ||
| 231 | + """ | ||
| 232 | + if TYPE_CHECKING: | ||
| 233 | + assert self.path is not None | ||
| 234 | + result = self.gitlab.http_get(self.path, streamed=streamed, raw=True, **kwargs) | ||
| 235 | + | ||
| 236 | + if TYPE_CHECKING: | ||
| 237 | + assert isinstance(result, requests.Response) | ||
| 238 | + return utils.response_content( | ||
| 239 | + result, streamed, action, chunk_size, iterator=iterator | ||
| 240 | + ) | ||
| 241 | + | ||
| 242 | + @cli.register_custom_action("ProjectJobArtifactManager", ("artifact_path",)) | ||
| 243 | + @cli.register_custom_action("ProjectJob") | ||
| 244 | + @exc.on_http_error(exc.GitlabGetError) | ||
| 245 | + def raw( | ||
| 246 | + self, | ||
| 247 | + path: str, | ||
| 248 | + streamed: bool = False, | ||
| 249 | + action: Optional[Callable[..., Any]] = None, | ||
| 250 | + chunk_size: int = 1024, | ||
| 251 | + iterator: bool = False, | ||
| 252 | + **kwargs: Any, | ||
| 253 | + ) -> Optional[Union[bytes, Iterator[Any]]]: | ||
| 254 | + """Get a single artifact file from within the job's artifacts archive. | ||
| 255 | + | ||
| 256 | + Args: | ||
| 257 | + path: Path of the artifact | ||
| 258 | + streamed: If True the data will be processed by chunks of | ||
| 259 | + `chunk_size` and each chunk is passed to `action` for | ||
| 260 | + treatment | ||
| 261 | + action: Callable responsible of dealing with chunk of | ||
| 262 | + data | ||
| 263 | + chunk_size: Size of each chunk | ||
| 264 | + iterator: If True directly return the underlying response | ||
| 265 | + iterator | ||
| 266 | + **kwargs: Extra options to send to the server (e.g. sudo) | ||
| 267 | + | ||
| 268 | + Raises: | ||
| 269 | + GitlabAuthenticationError: If authentication is not correct | ||
| 270 | + GitlabGetError: If the artifacts could not be retrieved | ||
| 271 | + | ||
| 272 | + Returns: | ||
| 273 | + The artifacts if `streamed` is False, None otherwise. | ||
| 274 | + """ | ||
| 275 | + path = f"{self.path}/{path}" | ||
| 276 | + result = self.gitlab.http_get(path, streamed=streamed, raw=True, **kwargs) | ||
| 277 | + if TYPE_CHECKING: | ||
| 278 | + assert isinstance(result, requests.Response) | ||
| 279 | + return utils.response_content( | ||
| 280 | + result, streamed, action, chunk_size, iterator=iterator | ||
| 281 | + ) | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -9,13 +9,17 @@ | |||
| 9 | 9 | from gitlab.mixins import RefreshMixin, RetrieveMixin | |
| 10 | 10 | from gitlab.types import ArrayAttribute | |
| 11 | 11 | ||
| 12 | + from .artifacts import ProjectJobArtifactManager # noqa: F401 | ||
| 13 | + | ||
| 12 | 14 | __all__ = [ | |
| 13 | 15 | "ProjectJob", | |
| 14 | 16 | "ProjectJobManager", | |
| 15 | 17 | ] | |
| 16 | 18 | ||
| 17 | 19 | ||
| 18 | 20 | class ProjectJob(RefreshMixin, RESTObject): | |
| 21 | + artifacts: ProjectJobArtifactManager | ||
| 22 | + | ||
| 19 | 23 | @cli.register_custom_action("ProjectJob") | |
| 20 | 24 | @exc.on_http_error(exc.GitlabJobCancelError) | |
| 21 | 25 | def cancel(self, **kwargs: Any) -> Dict[str, Any]: | |
@@ -112,89 +116,14 @@ def delete_artifacts(self, **kwargs: Any) -> None: | |||
| 112 | 116 | path = f"{self.manager.path}/{self.encoded_id}/artifacts" | |
| 113 | 117 | self.manager.gitlab.http_delete(path, **kwargs) | |
| 114 | 118 | ||
| 115 | - @cli.register_custom_action("ProjectJob") | ||
| 116 | - @exc.on_http_error(exc.GitlabGetError) | ||
| 117 | - def artifacts( | ||
| 118 | - self, | ||
| 119 | - streamed: bool = False, | ||
| 120 | - action: Optional[Callable[..., Any]] = None, | ||
| 121 | - chunk_size: int = 1024, | ||
| 122 | - *, | ||
| 123 | - iterator: bool = False, | ||
| 124 | - **kwargs: Any, | ||
| 125 | - ) -> Optional[Union[bytes, Iterator[Any]]]: | ||
| 126 | - """Get the job artifacts. | ||
| 127 | - | ||
| 128 | - Args: | ||
| 129 | - streamed: If True the data will be processed by chunks of | ||
| 130 | - `chunk_size` and each chunk is passed to `action` for | ||
| 131 | - treatment | ||
| 132 | - iterator: If True directly return the underlying response | ||
| 133 | - iterator | ||
| 134 | - action: Callable responsible of dealing with chunk of | ||
| 135 | - data | ||
| 136 | - chunk_size: Size of each chunk | ||
| 137 | - **kwargs: Extra options to send to the server (e.g. sudo) | ||
| 138 | - | ||
| 139 | - Raises: | ||
| 140 | - GitlabAuthenticationError: If authentication is not correct | ||
| 141 | - GitlabGetError: If the artifacts could not be retrieved | ||
| 142 | - | ||
| 143 | - Returns: | ||
| 144 | - The artifacts if `streamed` is False, None otherwise. | ||
| 145 | - """ | ||
| 146 | - path = f"{self.manager.path}/{self.encoded_id}/artifacts" | ||
| 147 | - result = self.manager.gitlab.http_get( | ||
| 148 | - path, streamed=streamed, raw=True, **kwargs | ||
| 149 | - ) | ||
| 150 | - if TYPE_CHECKING: | ||
| 151 | - assert isinstance(result, requests.Response) | ||
| 152 | - return utils.response_content( | ||
| 153 | - result, streamed, action, chunk_size, iterator=iterator | ||
| 154 | - ) | ||
| 155 | - | ||
| 156 | 119 | @cli.register_custom_action("ProjectJob") | |
| 157 | 120 | @exc.on_http_error(exc.GitlabGetError) | |
| 158 | 121 | def artifact( | |
| 159 | 122 | self, | |
| 160 | - path: str, | ||
| 161 | - streamed: bool = False, | ||
| 162 | - action: Optional[Callable[..., Any]] = None, | ||
| 163 | - chunk_size: int = 1024, | ||
| 164 | - *, | ||
| 165 | - iterator: bool = False, | ||
| 123 | + *args: Any, | ||
| 166 | 124 | **kwargs: Any, | |
| 167 | 125 | ) -> Optional[Union[bytes, Iterator[Any]]]: | |
| 168 | - """Get a single artifact file from within the job's artifacts archive. | ||
| 169 | - | ||
| 170 | - Args: | ||
| 171 | - path: Path of the artifact | ||
| 172 | - streamed: If True the data will be processed by chunks of | ||
| 173 | - `chunk_size` and each chunk is passed to `action` for | ||
| 174 | - treatment | ||
| 175 | - iterator: If True directly return the underlying response | ||
| 176 | - iterator | ||
| 177 | - action: Callable responsible of dealing with chunk of | ||
| 178 | - data | ||
| 179 | - chunk_size: Size of each chunk | ||
| 180 | - **kwargs: Extra options to send to the server (e.g. sudo) | ||
| 181 | - | ||
| 182 | - Raises: | ||
| 183 | - GitlabAuthenticationError: If authentication is not correct | ||
| 184 | - GitlabGetError: If the artifacts could not be retrieved | ||
| 185 | - | ||
| 186 | - Returns: | ||
| 187 | - The artifacts if `streamed` is False, None otherwise. | ||
| 188 | - """ | ||
| 189 | - path = f"{self.manager.path}/{self.encoded_id}/artifacts/{path}" | ||
| 190 | - result = self.manager.gitlab.http_get( | ||
| 191 | - path, streamed=streamed, raw=True, **kwargs | ||
| 192 | - ) | ||
| 193 | - if TYPE_CHECKING: | ||
| 194 | - assert isinstance(result, requests.Response) | ||
| 195 | - return utils.response_content( | ||
| 196 | - result, streamed, action, chunk_size, iterator=iterator | ||
| 197 | - ) | ||
| 126 | + return self.artifacts.raw(*args, **kwargs) | ||
| 198 | 127 | ||
| 199 | 128 | @cli.register_custom_action("ProjectJob") | |
| 200 | 129 | @exc.on_http_error(exc.GitlabGetError) | |
| Back | FazBrowse Home | New Git URL |
0 commit comments