194c44c
use axum::extract::{Path, State};
use axum::response::Redirect;
use export::rest::AppResponseData;
use jwt::Session;
use crate::errors::ApiError;
use crate::handlers::runs::RepoPath;
use crate::service::CiService;
use crate::triggers::ArtifactDto;
#[derive(Debug, Clone, serde::Serialize, utoipa::ToSchema)]
pub struct ArtifactListDto {
pub artifacts: Vec<ArtifactDto>,
}
#[utoipa::path(
get,
path = "/repos/{space_name}/{repo_name}/pipelines/{run_id}/artifacts",
tag = "pipelines",
description = "列出一次运行的全部产物。",
params(RepoPath, ("run_id" = uuid::Uuid, Path)),
responses((status = 200, description = "artifacts", body = AppResponseData<ArtifactListDto>))
)]
pub async fn list_artifacts(
State(service): State<CiService>,
session: Session,
Path((space_name, repo_name, run_id)): Path<(String, String, uuid::Uuid)>,
) -> Result<AppResponseData<ArtifactListDto>, ApiError> {
let (repo, _space) = service.resolve_repo(&space_name, &repo_name).await?;
service.require_read(&session, &repo).await?;
let detail = service.run_detail(run_id).await?;
if detail.run.repo_id != repo.id {
return Err(ApiError::not_found());
}
Ok(AppResponseData::ok(ArtifactListDto {
artifacts: detail.artifacts,
}))
}
#[utoipa::path(
get,
path = "/repos/{space_name}/{repo_name}/pipelines/artifacts/{artifact_id}/download",
tag = "pipelines",
description = "重定向到产物的预签名下载地址。",
params(RepoPath, ("artifact_id" = uuid::Uuid, Path)),
responses((status = 302, description = "redirect to object storage"))
)]
pub async fn download_artifact(
State(service): State<CiService>,
session: Session,
Path((space_name, repo_name, artifact_id)): Path<(String, String, uuid::Uuid)>,
) -> Result<Redirect, ApiError> {
let (repo, _space) = service.resolve_repo(&space_name, &repo_name).await?;
service.require_read(&session, &repo).await?;
let artifact = service.artifact_row(artifact_id).await?;
let detail = service.run_detail(artifact.run_id).await?;
if detail.run.repo_id != repo.id {
return Err(ApiError::not_found());
}
let url = service.artifact_download_url(artifact_id).await?;
Ok(Redirect::temporary(&url))
}