Download CI artifacts.
(
ctx: Context,
dest: pathlib.Path,
run_id: int,
repository: str = "saltstack/salt",
artifact_name: str | None = None,
)
| 267 | |
| 268 | |
| 269 | def download_artifact( |
| 270 | ctx: Context, |
| 271 | dest: pathlib.Path, |
| 272 | run_id: int, |
| 273 | repository: str = "saltstack/salt", |
| 274 | artifact_name: str | None = None, |
| 275 | ) -> str | None: |
| 276 | """ |
| 277 | Download CI artifacts. |
| 278 | """ |
| 279 | found_artifact: str | None = None |
| 280 | github_token = get_github_token(ctx) |
| 281 | if github_token is None: |
| 282 | ctx.error("Downloading artifacts requires being authenticated to GitHub.") |
| 283 | ctx.info( |
| 284 | "Either set 'GITHUB_TOKEN' to a valid token, or configure the 'gh' tool such that " |
| 285 | "'gh auth token' returns a token." |
| 286 | ) |
| 287 | return found_artifact |
| 288 | with ctx.web as web: |
| 289 | headers = { |
| 290 | "Accept": "application/vnd.github+json", |
| 291 | "Authorization": f"Bearer {github_token}", |
| 292 | "X-GitHub-Api-Version": "2022-11-28", |
| 293 | } |
| 294 | web.headers.update(headers) |
| 295 | page = 0 |
| 296 | listed_artifacts: set[str] = set() |
| 297 | while True: |
| 298 | if found_artifact is not None: |
| 299 | break |
| 300 | page += 1 |
| 301 | params = { |
| 302 | "per_page": 100, |
| 303 | "page": page, |
| 304 | } |
| 305 | ret = web.get( |
| 306 | f"https://api.github.com/repos/{repository}/actions/runs/{run_id}/artifacts", |
| 307 | params=params, |
| 308 | ) |
| 309 | if ret.status_code != 200: |
| 310 | ctx.error( |
| 311 | f"Failed to get the artifacts for the run ID {run_id} for repository {repository!r}: {ret.reason}" |
| 312 | ) |
| 313 | ctx.exit(1) |
| 314 | data = ret.json() |
| 315 | if data["total_count"] <= len(listed_artifacts): |
| 316 | ctx.info("Already gone through all of the listed artifacts:") |
| 317 | ctx.print(sorted(listed_artifacts)) |
| 318 | break |
| 319 | ctx.debug(f"Processing artifacts listing (page: {page}) ...") |
| 320 | if not data["artifacts"]: |
| 321 | break |
| 322 | for artifact in data["artifacts"]: |
| 323 | listed_artifacts.add(artifact["name"]) |
| 324 | ctx.debug( |
| 325 | f"Checking if {artifact['name']!r} matches {artifact_name!r} " |
| 326 | f"({len(listed_artifacts)}/{data['total_count']}) ..." |
no test coverage detected