mirror of
https://github.com/go-gitea/gitea.git
synced 2025-07-20 23:28:28 +02:00
wip
This commit is contained in:
parent
edb24592fc
commit
013a0af385
@ -89,10 +89,12 @@ type ActionWorkflowRun struct {
|
|||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
URL string `json:"url"`
|
URL string `json:"url"`
|
||||||
HTMLURL string `json:"html_url"`
|
HTMLURL string `json:"html_url"`
|
||||||
|
DisplayTitle string `json:"display_title"`
|
||||||
|
Path string `json:"path"`
|
||||||
Event string `json:"event"`
|
Event string `json:"event"`
|
||||||
RunAttempt int64 `json:"run_attempt"`
|
RunAttempt int64 `json:"run_attempt"`
|
||||||
RunNumber int64 `json:"run_number"`
|
RunNumber int64 `json:"run_number"`
|
||||||
RepositoryID int64 `json:"repository_id"`
|
RepositoryID int64 `json:"repository_id,omitempty"`
|
||||||
HeadSha string `json:"head_sha"`
|
HeadSha string `json:"head_sha"`
|
||||||
HeadBranch string `json:"head_branch,omitempty"`
|
HeadBranch string `json:"head_branch,omitempty"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
@ -103,6 +105,18 @@ type ActionWorkflowRun struct {
|
|||||||
CompletedAt time.Time `json:"completed_at,omitempty"`
|
CompletedAt time.Time `json:"completed_at,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ActionArtifactsResponse returns ActionArtifacts
|
||||||
|
type ActionWorkflowRunsResponse struct {
|
||||||
|
Entries []*ActionWorkflowRun `json:"workflow_runs"`
|
||||||
|
TotalCount int64 `json:"total_count"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ActionArtifactsResponse returns ActionArtifacts
|
||||||
|
type ActionWorkflowJobsResponse struct {
|
||||||
|
Entries []*ActionWorkflowJob `json:"workflow_jobs"`
|
||||||
|
TotalCount int64 `json:"total_count"`
|
||||||
|
}
|
||||||
|
|
||||||
// ActionArtifactsResponse returns ActionArtifacts
|
// ActionArtifactsResponse returns ActionArtifacts
|
||||||
type ActionArtifactsResponse struct {
|
type ActionArtifactsResponse struct {
|
||||||
Entries []*ActionArtifact `json:"artifacts"`
|
Entries []*ActionArtifact `json:"artifacts"`
|
||||||
|
@ -1243,6 +1243,8 @@ func Routes() *web.Router {
|
|||||||
}, reqToken(), reqAdmin())
|
}, reqToken(), reqAdmin())
|
||||||
m.Group("/actions", func() {
|
m.Group("/actions", func() {
|
||||||
m.Get("/tasks", repo.ListActionTasks)
|
m.Get("/tasks", repo.ListActionTasks)
|
||||||
|
m.Get("/runs", repo.GetWorkflowRuns)
|
||||||
|
m.Get("/runs/{run}/jobs", repo.GetWorkflowJobs)
|
||||||
m.Get("/runs/{run}/artifacts", repo.GetArtifactsOfRun)
|
m.Get("/runs/{run}/artifacts", repo.GetArtifactsOfRun)
|
||||||
m.Get("/artifacts", repo.GetArtifacts)
|
m.Get("/artifacts", repo.GetArtifacts)
|
||||||
m.Group("/artifacts/{artifact_id}", func() {
|
m.Group("/artifacts/{artifact_id}", func() {
|
||||||
|
@ -21,11 +21,13 @@ import (
|
|||||||
repo_model "code.gitea.io/gitea/models/repo"
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
secret_model "code.gitea.io/gitea/models/secret"
|
secret_model "code.gitea.io/gitea/models/secret"
|
||||||
"code.gitea.io/gitea/modules/actions"
|
"code.gitea.io/gitea/modules/actions"
|
||||||
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/modules/httplib"
|
"code.gitea.io/gitea/modules/httplib"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
api "code.gitea.io/gitea/modules/structs"
|
api "code.gitea.io/gitea/modules/structs"
|
||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
"code.gitea.io/gitea/modules/web"
|
"code.gitea.io/gitea/modules/web"
|
||||||
|
"code.gitea.io/gitea/modules/webhook"
|
||||||
"code.gitea.io/gitea/routers/api/v1/shared"
|
"code.gitea.io/gitea/routers/api/v1/shared"
|
||||||
"code.gitea.io/gitea/routers/api/v1/utils"
|
"code.gitea.io/gitea/routers/api/v1/utils"
|
||||||
actions_service "code.gitea.io/gitea/services/actions"
|
actions_service "code.gitea.io/gitea/services/actions"
|
||||||
@ -868,6 +870,264 @@ func ActionsEnableWorkflow(ctx *context.APIContext) {
|
|||||||
ctx.Status(http.StatusNoContent)
|
ctx.Status(http.StatusNoContent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func convertToInternal(s string) actions_model.Status {
|
||||||
|
switch s {
|
||||||
|
case "pending":
|
||||||
|
return actions_model.StatusBlocked
|
||||||
|
case "queued":
|
||||||
|
return actions_model.StatusWaiting
|
||||||
|
case "in_progress":
|
||||||
|
return actions_model.StatusRunning
|
||||||
|
case "failure":
|
||||||
|
return actions_model.StatusFailure
|
||||||
|
case "success":
|
||||||
|
return actions_model.StatusSuccess
|
||||||
|
case "skipped":
|
||||||
|
return actions_model.StatusSkipped
|
||||||
|
default:
|
||||||
|
return actions_model.StatusUnknown
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetArtifacts Lists all artifacts for a repository.
|
||||||
|
func GetWorkflowRuns(ctx *context.APIContext) {
|
||||||
|
// swagger:operation GET /repos/{owner}/{repo}/actions/runs repository getWorkflowRuns
|
||||||
|
// ---
|
||||||
|
// summary: Lists all runs for a repository run
|
||||||
|
// produces:
|
||||||
|
// - application/json
|
||||||
|
// parameters:
|
||||||
|
// - name: owner
|
||||||
|
// in: path
|
||||||
|
// description: name of the owner
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// - name: repo
|
||||||
|
// in: path
|
||||||
|
// description: name of the repository
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// - name: run
|
||||||
|
// in: path
|
||||||
|
// description: runid of the workflow run
|
||||||
|
// type: integer
|
||||||
|
// required: true
|
||||||
|
// - name: name
|
||||||
|
// in: query
|
||||||
|
// description: name of the artifact
|
||||||
|
// type: string
|
||||||
|
// required: false
|
||||||
|
// responses:
|
||||||
|
// "200":
|
||||||
|
// "$ref": "#/responses/ArtifactsList"
|
||||||
|
// "400":
|
||||||
|
// "$ref": "#/responses/error"
|
||||||
|
// "404":
|
||||||
|
// "$ref": "#/responses/notFound"
|
||||||
|
|
||||||
|
repoID := ctx.Repo.Repository.ID
|
||||||
|
|
||||||
|
opts := actions_model.FindRunOptions{
|
||||||
|
RepoID: repoID,
|
||||||
|
ListOptions: utils.GetListOptions(ctx),
|
||||||
|
}
|
||||||
|
|
||||||
|
if event := ctx.Req.URL.Query().Get("event"); event != "" {
|
||||||
|
opts.TriggerEvent = webhook.HookEventType(event)
|
||||||
|
}
|
||||||
|
if branch := ctx.Req.URL.Query().Get("branch"); branch != "" {
|
||||||
|
opts.Ref = string(git.RefNameFromBranch(branch))
|
||||||
|
}
|
||||||
|
if status := ctx.Req.URL.Query().Get("status"); status != "" {
|
||||||
|
opts.Status = []actions_model.Status{convertToInternal(status)}
|
||||||
|
}
|
||||||
|
// if actor := ctx.Req.URL.Query().Get("actor"); actor != "" {
|
||||||
|
// user_model.
|
||||||
|
// opts.TriggerUserID =
|
||||||
|
// }
|
||||||
|
|
||||||
|
runs, total, err := db.FindAndCount[actions_model.ActionRun](ctx, opts)
|
||||||
|
if err != nil {
|
||||||
|
ctx.APIErrorInternal(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
res := new(api.ActionWorkflowRunsResponse)
|
||||||
|
res.TotalCount = total
|
||||||
|
|
||||||
|
res.Entries = make([]*api.ActionWorkflowRun, len(runs))
|
||||||
|
for i := range runs {
|
||||||
|
convertedRun, err := convert.ToActionWorkflowRun(ctx.Repo.Repository, runs[i])
|
||||||
|
if err != nil {
|
||||||
|
ctx.APIErrorInternal(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res.Entries[i] = convertedRun
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.JSON(http.StatusOK, &res)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetWorkflowRun Gets a specific workflow run.
|
||||||
|
func GetWorkflowRun(ctx *context.APIContext) {
|
||||||
|
// swagger:operation GET /repos/{owner}/{repo}/actions/runs/{run} repository GetWorkflowRun
|
||||||
|
// ---
|
||||||
|
// summary: Gets a specific workflow run
|
||||||
|
// produces:
|
||||||
|
// - application/json
|
||||||
|
// parameters:
|
||||||
|
// - name: owner
|
||||||
|
// in: path
|
||||||
|
// description: name of the owner
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// - name: repo
|
||||||
|
// in: path
|
||||||
|
// description: name of the repository
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// - name: run
|
||||||
|
// in: path
|
||||||
|
// description: id of the run
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// responses:
|
||||||
|
// "200":
|
||||||
|
// "$ref": "#/responses/Artifact"
|
||||||
|
// "400":
|
||||||
|
// "$ref": "#/responses/error"
|
||||||
|
// "404":
|
||||||
|
// "$ref": "#/responses/notFound"
|
||||||
|
|
||||||
|
runID := ctx.PathParamInt64("run")
|
||||||
|
job, _, _ := db.GetByID[actions_model.ActionRun](ctx, runID)
|
||||||
|
|
||||||
|
if job.RepoID != ctx.Repo.Repository.ID {
|
||||||
|
ctx.APIError(http.StatusNotFound, util.ErrNotExist)
|
||||||
|
}
|
||||||
|
|
||||||
|
convertedArtifact, err := convert.ToActionWorkflowRun(ctx.Repo.Repository, job)
|
||||||
|
if err != nil {
|
||||||
|
ctx.APIErrorInternal(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.JSON(http.StatusOK, convertedArtifact)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetWorkflowJobs Lists all jobs for a workflow run.
|
||||||
|
func GetWorkflowJobs(ctx *context.APIContext) {
|
||||||
|
// swagger:operation GET /repos/{owner}/{repo}/actions/runs/{run}/jobs repository getWorkflowJobs
|
||||||
|
// ---
|
||||||
|
// summary: Lists all jobs for a workflow run
|
||||||
|
// produces:
|
||||||
|
// - application/json
|
||||||
|
// parameters:
|
||||||
|
// - name: owner
|
||||||
|
// in: path
|
||||||
|
// description: name of the owner
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// - name: repo
|
||||||
|
// in: path
|
||||||
|
// description: name of the repository
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// - name: run
|
||||||
|
// in: path
|
||||||
|
// description: runid of the workflow run
|
||||||
|
// type: integer
|
||||||
|
// required: true
|
||||||
|
// - name: name
|
||||||
|
// in: query
|
||||||
|
// description: name of the artifact
|
||||||
|
// type: string
|
||||||
|
// required: false
|
||||||
|
// responses:
|
||||||
|
// "200":
|
||||||
|
// "$ref": "#/responses/ArtifactsList"
|
||||||
|
// "400":
|
||||||
|
// "$ref": "#/responses/error"
|
||||||
|
// "404":
|
||||||
|
// "$ref": "#/responses/notFound"
|
||||||
|
|
||||||
|
repoID := ctx.Repo.Repository.ID
|
||||||
|
|
||||||
|
runID := ctx.PathParamInt64("run")
|
||||||
|
|
||||||
|
artifacts, total, err := db.FindAndCount[actions_model.ActionRunJob](ctx, actions_model.FindRunJobOptions{
|
||||||
|
RepoID: repoID,
|
||||||
|
RunID: runID,
|
||||||
|
ListOptions: utils.GetListOptions(ctx),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ctx.APIErrorInternal(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
res := new(api.ActionWorkflowJobsResponse)
|
||||||
|
res.TotalCount = total
|
||||||
|
|
||||||
|
res.Entries = make([]*api.ActionWorkflowJob, len(artifacts))
|
||||||
|
for i := range artifacts {
|
||||||
|
convertedWorkflowJob, err := convert.ToActionWorkflowJob(ctx, ctx.Repo.Repository, artifacts[i])
|
||||||
|
if err != nil {
|
||||||
|
ctx.APIErrorInternal(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res.Entries[i] = convertedWorkflowJob
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.JSON(http.StatusOK, &res)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetWorkflowJob Gets a specific workflow job for a workflow run.
|
||||||
|
func GetWorkflowJob(ctx *context.APIContext) {
|
||||||
|
// swagger:operation GET /repos/{owner}/{repo}/actions/jobs/{job_id} repository getWorkflowJob
|
||||||
|
// ---
|
||||||
|
// summary: Gets a specific workflow job for a workflow run
|
||||||
|
// produces:
|
||||||
|
// - application/json
|
||||||
|
// parameters:
|
||||||
|
// - name: owner
|
||||||
|
// in: path
|
||||||
|
// description: name of the owner
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// - name: repo
|
||||||
|
// in: path
|
||||||
|
// description: name of the repository
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// - name: job_id
|
||||||
|
// in: path
|
||||||
|
// description: id of the job
|
||||||
|
// type: string
|
||||||
|
// required: true
|
||||||
|
// responses:
|
||||||
|
// "200":
|
||||||
|
// "$ref": "#/responses/Artifact"
|
||||||
|
// "400":
|
||||||
|
// "$ref": "#/responses/error"
|
||||||
|
// "404":
|
||||||
|
// "$ref": "#/responses/notFound"
|
||||||
|
|
||||||
|
jobID := ctx.PathParamInt64("job_id")
|
||||||
|
job, _, _ := db.GetByID[actions_model.ActionRunJob](ctx, jobID)
|
||||||
|
|
||||||
|
if job.RepoID != ctx.Repo.Repository.ID {
|
||||||
|
ctx.APIError(http.StatusNotFound, util.ErrNotExist)
|
||||||
|
}
|
||||||
|
|
||||||
|
convertedWorkflowJob, err := convert.ToActionWorkflowJob(ctx, ctx.Repo.Repository, job)
|
||||||
|
if err != nil {
|
||||||
|
ctx.APIErrorInternal(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.JSON(http.StatusOK, convertedWorkflowJob)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// GetArtifacts Lists all artifacts for a repository.
|
// GetArtifacts Lists all artifacts for a repository.
|
||||||
func GetArtifactsOfRun(ctx *context.APIContext) {
|
func GetArtifactsOfRun(ctx *context.APIContext) {
|
||||||
// swagger:operation GET /repos/{owner}/{repo}/actions/runs/{run}/artifacts repository getArtifactsOfRun
|
// swagger:operation GET /repos/{owner}/{repo}/actions/runs/{run}/artifacts repository getArtifactsOfRun
|
||||||
|
@ -14,6 +14,7 @@ import (
|
|||||||
actions_model "code.gitea.io/gitea/models/actions"
|
actions_model "code.gitea.io/gitea/models/actions"
|
||||||
asymkey_model "code.gitea.io/gitea/models/asymkey"
|
asymkey_model "code.gitea.io/gitea/models/asymkey"
|
||||||
"code.gitea.io/gitea/models/auth"
|
"code.gitea.io/gitea/models/auth"
|
||||||
|
"code.gitea.io/gitea/models/db"
|
||||||
git_model "code.gitea.io/gitea/models/git"
|
git_model "code.gitea.io/gitea/models/git"
|
||||||
issues_model "code.gitea.io/gitea/models/issues"
|
issues_model "code.gitea.io/gitea/models/issues"
|
||||||
"code.gitea.io/gitea/models/organization"
|
"code.gitea.io/gitea/models/organization"
|
||||||
@ -230,6 +231,118 @@ func ToActionTask(ctx context.Context, t *actions_model.ActionTask) (*api.Action
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ToActionWorkflowRun(repo *repo_model.Repository, run *actions_model.ActionRun) (*api.ActionWorkflowRun, error) {
|
||||||
|
status, conclusion := toActionStatus(run.Status)
|
||||||
|
return &api.ActionWorkflowRun{
|
||||||
|
ID: run.ID,
|
||||||
|
URL: fmt.Sprintf("%s/actions/runs/%d", repo.APIURL(), run.ID),
|
||||||
|
HTMLURL: run.HTMLURL(),
|
||||||
|
RunNumber: run.Index,
|
||||||
|
StartedAt: run.Started.AsLocalTime(),
|
||||||
|
CompletedAt: run.Stopped.AsLocalTime(),
|
||||||
|
Event: run.TriggerEvent,
|
||||||
|
DisplayTitle: run.Title,
|
||||||
|
HeadBranch: git.RefName(run.Ref).BranchName(),
|
||||||
|
HeadSha: run.CommitSHA,
|
||||||
|
Status: status,
|
||||||
|
Conclusion: conclusion,
|
||||||
|
Path: fmt.Sprint("%s@%s", run.WorkflowID, run.Ref),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func toActionStatus(status actions_model.Status) (string, string) {
|
||||||
|
var action string
|
||||||
|
var conclusion string
|
||||||
|
switch status {
|
||||||
|
// This is a naming conflict of the webhook between Gitea and GitHub Actions
|
||||||
|
case actions_model.StatusWaiting:
|
||||||
|
action = "queued"
|
||||||
|
case actions_model.StatusBlocked:
|
||||||
|
action = "waiting"
|
||||||
|
case actions_model.StatusRunning:
|
||||||
|
action = "in_progress"
|
||||||
|
}
|
||||||
|
if status.IsDone() {
|
||||||
|
action = "completed"
|
||||||
|
switch status {
|
||||||
|
case actions_model.StatusSuccess:
|
||||||
|
conclusion = "success"
|
||||||
|
case actions_model.StatusCancelled:
|
||||||
|
conclusion = "cancelled"
|
||||||
|
case actions_model.StatusFailure:
|
||||||
|
conclusion = "failure"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return action, conclusion
|
||||||
|
}
|
||||||
|
|
||||||
|
func ToActionWorkflowJob(ctx context.Context, repo *repo_model.Repository, job *actions_model.ActionRunJob) (*api.ActionWorkflowJob, error) {
|
||||||
|
err := job.LoadAttributes(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
jobIndex := 0
|
||||||
|
jobs, err := actions_model.GetRunJobsByRunID(ctx, job.RunID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for i, j := range jobs {
|
||||||
|
if j.ID == job.ID {
|
||||||
|
jobIndex = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status, conclusion := toActionStatus(job.Status)
|
||||||
|
var runnerID int64
|
||||||
|
var runnerName string
|
||||||
|
var steps []*api.ActionWorkflowStep
|
||||||
|
|
||||||
|
if job.TaskID != 0 {
|
||||||
|
task, _, _ := db.GetByID[actions_model.ActionTask](ctx, job.TaskID)
|
||||||
|
|
||||||
|
runnerID = task.RunnerID
|
||||||
|
if runner, ok, _ := db.GetByID[actions_model.ActionRunner](ctx, runnerID); ok {
|
||||||
|
runnerName = runner.Name
|
||||||
|
}
|
||||||
|
for i, step := range task.Steps {
|
||||||
|
stepStatus, stepConclusion := toActionStatus(job.Status)
|
||||||
|
steps = append(steps, &api.ActionWorkflowStep{
|
||||||
|
Name: step.Name,
|
||||||
|
Number: int64(i),
|
||||||
|
Status: stepStatus,
|
||||||
|
Conclusion: stepConclusion,
|
||||||
|
StartedAt: step.Started.AsTime().UTC(),
|
||||||
|
CompletedAt: step.Stopped.AsTime().UTC(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &api.ActionWorkflowJob{
|
||||||
|
ID: job.ID,
|
||||||
|
// missing api endpoint for this location
|
||||||
|
URL: fmt.Sprintf("%s/actions/jobs/%d", repo.APIURL(), job.ID),
|
||||||
|
HTMLURL: fmt.Sprintf("%s/jobs/%d", job.Run.HTMLURL(), jobIndex),
|
||||||
|
RunID: job.RunID,
|
||||||
|
// Missing api endpoint for this location, artifacts are available under a nested url
|
||||||
|
RunURL: fmt.Sprintf("%s/actions/runs/%d", repo.APIURL(), job.RunID),
|
||||||
|
Name: job.Name,
|
||||||
|
Labels: job.RunsOn,
|
||||||
|
RunAttempt: job.Attempt,
|
||||||
|
HeadSha: job.Run.CommitSHA,
|
||||||
|
HeadBranch: git.RefName(job.Run.Ref).BranchName(),
|
||||||
|
Status: status,
|
||||||
|
Conclusion: conclusion,
|
||||||
|
RunnerID: runnerID,
|
||||||
|
RunnerName: runnerName,
|
||||||
|
Steps: steps,
|
||||||
|
CreatedAt: job.Created.AsTime().UTC(),
|
||||||
|
StartedAt: job.Started.AsTime().UTC(),
|
||||||
|
CompletedAt: job.Stopped.AsTime().UTC(),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
// ToActionArtifact convert a actions_model.ActionArtifact to an api.ActionArtifact
|
// ToActionArtifact convert a actions_model.ActionArtifact to an api.ActionArtifact
|
||||||
func ToActionArtifact(repo *repo_model.Repository, art *actions_model.ActionArtifact) (*api.ActionArtifact, error) {
|
func ToActionArtifact(repo *repo_model.Repository, art *actions_model.ActionArtifact) (*api.ActionArtifact, error) {
|
||||||
url := fmt.Sprintf("%s/actions/artifacts/%d", repo.APIURL(), art.ID)
|
url := fmt.Sprintf("%s/actions/artifacts/%d", repo.APIURL(), art.ID)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user