Artifacts download api for artifact actions v4 (#33510)

* download endpoint has to use 302 redirect
* fake blob download used if direct download not possible
* downloading v3 artifacts not possible

New repo apis based on GitHub Rest V3
- GET /runs/{run}/artifacts (Cannot use run index of url due to not
being unique)
- GET /artifacts
- GET + DELETE /artifacts/{artifact_id}
- GET /artifacts/{artifact_id}/zip
- (GET /artifacts/{artifact_id}/zip/raw this is a workaround for a http
302 assertion in actions/toolkit)
- api docs removed this is protected by a signed url like the internal
artifacts api and no longer usable with any token or swagger
  - returns http 401 if the signature is invalid
    - or change the artifact id
    - or expired after 1 hour

Closes #33353
Closes #32124

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
ChristopherHX 2025-02-16 01:32:54 +01:00 committed by GitHub
parent 01bf8da02e
commit 2b8cfb557d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 1146 additions and 27 deletions

View file

@ -3919,6 +3919,187 @@
}
}
},
"/repos/{owner}/{repo}/actions/artifacts": {
"get": {
"produces": [
"application/json"
],
"tags": [
"repository"
],
"summary": "Lists all artifacts for a repository",
"operationId": "getArtifacts",
"parameters": [
{
"type": "string",
"description": "name of the owner",
"name": "owner",
"in": "path",
"required": true
},
{
"type": "string",
"description": "name of the repository",
"name": "repo",
"in": "path",
"required": true
},
{
"type": "string",
"description": "name of the artifact",
"name": "name",
"in": "query"
}
],
"responses": {
"200": {
"$ref": "#/responses/ArtifactsList"
},
"400": {
"$ref": "#/responses/error"
},
"404": {
"$ref": "#/responses/notFound"
}
}
}
},
"/repos/{owner}/{repo}/actions/artifacts/{artifact_id}": {
"get": {
"produces": [
"application/json"
],
"tags": [
"repository"
],
"summary": "Gets a specific artifact for a workflow run",
"operationId": "getArtifact",
"parameters": [
{
"type": "string",
"description": "name of the owner",
"name": "owner",
"in": "path",
"required": true
},
{
"type": "string",
"description": "name of the repository",
"name": "repo",
"in": "path",
"required": true
},
{
"type": "string",
"description": "id of the artifact",
"name": "artifact_id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"$ref": "#/responses/Artifact"
},
"400": {
"$ref": "#/responses/error"
},
"404": {
"$ref": "#/responses/notFound"
}
}
},
"delete": {
"produces": [
"application/json"
],
"tags": [
"repository"
],
"summary": "Deletes a specific artifact for a workflow run",
"operationId": "deleteArtifact",
"parameters": [
{
"type": "string",
"description": "name of the owner",
"name": "owner",
"in": "path",
"required": true
},
{
"type": "string",
"description": "name of the repository",
"name": "repo",
"in": "path",
"required": true
},
{
"type": "string",
"description": "id of the artifact",
"name": "artifact_id",
"in": "path",
"required": true
}
],
"responses": {
"204": {
"description": "No Content"
},
"400": {
"$ref": "#/responses/error"
},
"404": {
"$ref": "#/responses/notFound"
}
}
}
},
"/repos/{owner}/{repo}/actions/artifacts/{artifact_id}/zip": {
"get": {
"produces": [
"application/json"
],
"tags": [
"repository"
],
"summary": "Downloads a specific artifact for a workflow run redirects to blob url",
"operationId": "downloadArtifact",
"parameters": [
{
"type": "string",
"description": "name of the owner",
"name": "owner",
"in": "path",
"required": true
},
{
"type": "string",
"description": "name of the repository",
"name": "repo",
"in": "path",
"required": true
},
{
"type": "string",
"description": "id of the artifact",
"name": "artifact_id",
"in": "path",
"required": true
}
],
"responses": {
"302": {
"description": "redirect to the blob download"
},
"400": {
"$ref": "#/responses/error"
},
"404": {
"$ref": "#/responses/notFound"
}
}
}
},
"/repos/{owner}/{repo}/actions/runners/registration-token": {
"get": {
"produces": [
@ -3952,6 +4133,58 @@
}
}
},
"/repos/{owner}/{repo}/actions/runs/{run}/artifacts": {
"get": {
"produces": [
"application/json"
],
"tags": [
"repository"
],
"summary": "Lists all artifacts for a repository run",
"operationId": "getArtifactsOfRun",
"parameters": [
{
"type": "string",
"description": "name of the owner",
"name": "owner",
"in": "path",
"required": true
},
{
"type": "string",
"description": "name of the repository",
"name": "repo",
"in": "path",
"required": true
},
{
"type": "integer",
"description": "runid of the workflow run",
"name": "run",
"in": "path",
"required": true
},
{
"type": "string",
"description": "name of the artifact",
"name": "name",
"in": "query"
}
],
"responses": {
"200": {
"$ref": "#/responses/ArtifactsList"
},
"400": {
"$ref": "#/responses/error"
},
"404": {
"$ref": "#/responses/notFound"
}
}
}
},
"/repos/{owner}/{repo}/actions/secrets": {
"get": {
"produces": [
@ -18837,6 +19070,76 @@
},
"x-go-package": "code.gitea.io/gitea/modules/structs"
},
"ActionArtifact": {
"description": "ActionArtifact represents a ActionArtifact",
"type": "object",
"properties": {
"archive_download_url": {
"type": "string",
"x-go-name": "ArchiveDownloadURL"
},
"created_at": {
"type": "string",
"format": "date-time",
"x-go-name": "CreatedAt"
},
"expired": {
"type": "boolean",
"x-go-name": "Expired"
},
"expires_at": {
"type": "string",
"format": "date-time",
"x-go-name": "ExpiresAt"
},
"id": {
"type": "integer",
"format": "int64",
"x-go-name": "ID"
},
"name": {
"type": "string",
"x-go-name": "Name"
},
"size_in_bytes": {
"type": "integer",
"format": "int64",
"x-go-name": "SizeInBytes"
},
"updated_at": {
"type": "string",
"format": "date-time",
"x-go-name": "UpdatedAt"
},
"url": {
"type": "string",
"x-go-name": "URL"
},
"workflow_run": {
"$ref": "#/definitions/ActionWorkflowRun"
}
},
"x-go-package": "code.gitea.io/gitea/modules/structs"
},
"ActionArtifactsResponse": {
"description": "ActionArtifactsResponse returns ActionArtifacts",
"type": "object",
"properties": {
"artifacts": {
"type": "array",
"items": {
"$ref": "#/definitions/ActionArtifact"
},
"x-go-name": "Entries"
},
"total_count": {
"type": "integer",
"format": "int64",
"x-go-name": "TotalCount"
}
},
"x-go-package": "code.gitea.io/gitea/modules/structs"
},
"ActionTask": {
"description": "ActionTask represents a ActionTask",
"type": "object",
@ -18999,6 +19302,27 @@
},
"x-go-package": "code.gitea.io/gitea/modules/structs"
},
"ActionWorkflowRun": {
"description": "ActionWorkflowRun represents a WorkflowRun",
"type": "object",
"properties": {
"head_sha": {
"type": "string",
"x-go-name": "HeadSha"
},
"id": {
"type": "integer",
"format": "int64",
"x-go-name": "ID"
},
"repository_id": {
"type": "integer",
"format": "int64",
"x-go-name": "RepositoryID"
}
},
"x-go-package": "code.gitea.io/gitea/modules/structs"
},
"Activity": {
"type": "object",
"properties": {
@ -26064,6 +26388,18 @@
"$ref": "#/definitions/AnnotatedTag"
}
},
"Artifact": {
"description": "Artifact",
"schema": {
"$ref": "#/definitions/ActionArtifact"
}
},
"ArtifactsList": {
"description": "ArtifactsList",
"schema": {
"$ref": "#/definitions/ActionArtifactsResponse"
}
},
"Attachment": {
"description": "Attachment",
"schema": {