Skip to content

Commit 9e5c63b

Browse files
committed
Merge branch 'main' of github.com:bencurio/gitea into bencurio-main
2 parents 09a3b07 + 1969e6b commit 9e5c63b

File tree

8 files changed

+999
-0
lines changed

8 files changed

+999
-0
lines changed

modules/structs/repo_actions.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,37 @@ type ActionTaskResponse struct {
3232
Entries []*ActionTask `json:"workflow_runs"`
3333
TotalCount int64 `json:"total_count"`
3434
}
35+
36+
// CreateActionWorkflowDispatch represents the payload for triggering a workflow dispatch event
37+
// swagger:model
38+
type CreateActionWorkflowDispatch struct {
39+
// required: true
40+
// example: refs/heads/main
41+
Ref string `json:"ref" binding:"Required"`
42+
// required: false
43+
Inputs map[string]any `json:"inputs,omitempty"`
44+
}
45+
46+
// ActionWorkflow represents a ActionWorkflow
47+
type ActionWorkflow struct {
48+
ID string `json:"id"`
49+
NodeID string `json:"node_id"`
50+
Name string `json:"name"`
51+
Path string `json:"path"`
52+
State string `json:"state"`
53+
// swagger:strfmt date-time
54+
CreatedAt time.Time `json:"created_at"`
55+
// swagger:strfmt date-time
56+
UpdatedAt time.Time `json:"updated_at"`
57+
URL string `json:"url"`
58+
HTMLURL string `json:"html_url"`
59+
BadgeURL string `json:"badge_url"`
60+
// swagger:strfmt date-time
61+
DeletedAt time.Time `json:"deleted_at"`
62+
}
63+
64+
// ActionWorkflowResponse returns a ActionWorkflow
65+
type ActionWorkflowResponse struct {
66+
Workflows []*ActionWorkflow `json:"workflows"`
67+
TotalCount int64 `json:"total_count"`
68+
}

routers/api/v1/api.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -915,6 +915,22 @@ func Routes() *web.Router {
915915
})
916916
}
917917

918+
addActionsWorkflowRoutes := func(
919+
m *web.Router,
920+
reqChecker func(ctx *context.APIContext),
921+
actw actions.WorkflowAPI,
922+
) {
923+
m.Group("/actions", func() {
924+
m.Group("/workflows", func() {
925+
m.Get("", reqToken(), reqChecker, actw.ListRepositoryWorkflows)
926+
m.Get("/{workflow_id}", reqToken(), reqChecker, actw.GetWorkflow)
927+
m.Put("/{workflow_id}/disable", reqToken(), reqChecker, actw.DisableWorkflow)
928+
m.Post("/{workflow_id}/dispatches", reqToken(), reqChecker, bind(api.CreateActionWorkflowDispatch{}), actw.DispatchWorkflow)
929+
m.Put("/{workflow_id}/enable", reqToken(), reqChecker, actw.EnableWorkflow)
930+
}, context.ReferencesGitRepo(), reqRepoWriter(unit.TypeActions))
931+
})
932+
}
933+
918934
m.Group("", func() {
919935
// Miscellaneous (no scope required)
920936
if setting.API.EnableSwagger {
@@ -1160,6 +1176,11 @@ func Routes() *web.Router {
11601176
reqOwner(),
11611177
repo.NewAction(),
11621178
)
1179+
addActionsWorkflowRoutes(
1180+
m,
1181+
reqRepoWriter(unit.TypeActions),
1182+
repo.NewActionWorkflow(),
1183+
)
11631184
m.Group("/hooks/git", func() {
11641185
m.Combo("").Get(repo.ListGitHooks)
11651186
m.Group("/{id}", func() {

routers/api/v1/repo/action.go

Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,3 +581,270 @@ func ListActionTasks(ctx *context.APIContext) {
581581

582582
ctx.JSON(http.StatusOK, &res)
583583
}
584+
585+
// ActionWorkflow implements actions_service.WorkflowAPI
586+
type ActionWorkflow struct{}
587+
588+
// NewActionWorkflow creates a new ActionWorkflow service
589+
func NewActionWorkflow() actions_service.WorkflowAPI {
590+
return ActionWorkflow{}
591+
}
592+
593+
func (a ActionWorkflow) ListRepositoryWorkflows(ctx *context.APIContext) {
594+
// swagger:operation GET /repos/{owner}/{repo}/actions/workflows repository ListRepositoryWorkflows
595+
// ---
596+
// summary: List repository workflows
597+
// produces:
598+
// - application/json
599+
// parameters:
600+
// - name: owner
601+
// in: path
602+
// description: owner of the repo
603+
// type: string
604+
// required: true
605+
// - name: repo
606+
// in: path
607+
// description: name of the repo
608+
// type: string
609+
// required: true
610+
// responses:
611+
// "200":
612+
// "$ref": "#/responses/ActionWorkflowList"
613+
// "400":
614+
// "$ref": "#/responses/error"
615+
// "403":
616+
// "$ref": "#/responses/forbidden"
617+
// "404":
618+
// "$ref": "#/responses/notFound"
619+
// "422":
620+
// "$ref": "#/responses/validationError"
621+
// "500":
622+
// "$ref": "#/responses/error"
623+
624+
workflows, err := actions_service.ListActionWorkflows(ctx)
625+
if err != nil {
626+
ctx.Error(http.StatusInternalServerError, "ListActionWorkflows", err)
627+
return
628+
}
629+
630+
if len(workflows) == 0 {
631+
ctx.Error(http.StatusNotFound, "ListActionWorkflows", err)
632+
return
633+
}
634+
635+
ctx.SetTotalCountHeader(int64(len(workflows)))
636+
ctx.JSON(http.StatusOK, workflows)
637+
}
638+
639+
func (a ActionWorkflow) GetWorkflow(ctx *context.APIContext) {
640+
// swagger:operation GET /repos/{owner}/{repo}/actions/workflows/{workflow_id} repository GetWorkflow
641+
// ---
642+
// summary: Get a workflow
643+
// produces:
644+
// - application/json
645+
// parameters:
646+
// - name: owner
647+
// in: path
648+
// description: owner of the repo
649+
// type: string
650+
// required: true
651+
// - name: repo
652+
// in: path
653+
// description: name of the repo
654+
// type: string
655+
// required: true
656+
// - name: workflow_id
657+
// in: path
658+
// description: id of the workflow
659+
// type: string
660+
// required: true
661+
// responses:
662+
// "200":
663+
// "$ref": "#/responses/ActionWorkflow"
664+
// "400":
665+
// "$ref": "#/responses/error"
666+
// "403":
667+
// "$ref": "#/responses/forbidden"
668+
// "404":
669+
// "$ref": "#/responses/notFound"
670+
// "422":
671+
// "$ref": "#/responses/validationError"
672+
// "500":
673+
// "$ref": "#/responses/error"
674+
675+
workflowID := ctx.PathParam("workflow_id")
676+
if len(workflowID) == 0 {
677+
ctx.Error(http.StatusUnprocessableEntity, "MissingWorkflowParameter", util.NewInvalidArgumentErrorf("workflow_id is required parameter"))
678+
return
679+
}
680+
681+
workflow, err := actions_service.GetActionWorkflow(ctx, workflowID)
682+
if err != nil {
683+
ctx.Error(http.StatusInternalServerError, "GetActionWorkflow", err)
684+
return
685+
}
686+
687+
if workflow == nil {
688+
ctx.Error(http.StatusNotFound, "GetActionWorkflow", err)
689+
return
690+
}
691+
692+
ctx.JSON(http.StatusOK, workflow)
693+
}
694+
695+
func (a ActionWorkflow) DisableWorkflow(ctx *context.APIContext) {
696+
// swagger:operation PUT /repos/{owner}/{repo}/actions/workflows/{workflow_id}/disable repository DisableWorkflow
697+
// ---
698+
// summary: Disable a workflow
699+
// produces:
700+
// - application/json
701+
// parameters:
702+
// - name: owner
703+
// in: path
704+
// description: owner of the repo
705+
// type: string
706+
// required: true
707+
// - name: repo
708+
// in: path
709+
// description: name of the repo
710+
// type: string
711+
// required: true
712+
// - name: workflow_id
713+
// in: path
714+
// description: id of the workflow
715+
// type: string
716+
// required: true
717+
// responses:
718+
// "204":
719+
// description: No Content
720+
// "400":
721+
// "$ref": "#/responses/error"
722+
// "403":
723+
// "$ref": "#/responses/forbidden"
724+
// "404":
725+
// "$ref": "#/responses/notFound"
726+
// "422":
727+
// "$ref": "#/responses/validationError"
728+
729+
workflowID := ctx.PathParam("workflow_id")
730+
if len(workflowID) == 0 {
731+
ctx.Error(http.StatusUnprocessableEntity, "MissingWorkflowParameter", util.NewInvalidArgumentErrorf("workflow_id is required parameter"))
732+
return
733+
}
734+
735+
err := actions_service.DisableActionWorkflow(ctx, workflowID)
736+
if err != nil {
737+
ctx.Error(http.StatusInternalServerError, "DisableActionWorkflow", err)
738+
return
739+
}
740+
741+
ctx.Status(http.StatusNoContent)
742+
}
743+
744+
func (a ActionWorkflow) DispatchWorkflow(ctx *context.APIContext) {
745+
// swagger:operation POST /repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches repository DispatchWorkflow
746+
// ---
747+
// summary: Create a workflow dispatch event
748+
// produces:
749+
// - application/json
750+
// parameters:
751+
// - name: owner
752+
// in: path
753+
// description: owner of the repo
754+
// type: string
755+
// required: true
756+
// - name: repo
757+
// in: path
758+
// description: name of the repo
759+
// type: string
760+
// required: true
761+
// - name: workflow_id
762+
// in: path
763+
// description: id of the workflow
764+
// type: string
765+
// required: true
766+
// - name: body
767+
// in: body
768+
// schema:
769+
// "$ref": "#/definitions/CreateActionWorkflowDispatch"
770+
// responses:
771+
// "204":
772+
// description: No Content
773+
// "400":
774+
// "$ref": "#/responses/error"
775+
// "403":
776+
// "$ref": "#/responses/forbidden"
777+
// "404":
778+
// "$ref": "#/responses/notFound"
779+
// "422":
780+
// "$ref": "#/responses/validationError"
781+
782+
opt := web.GetForm(ctx).(*api.CreateActionWorkflowDispatch)
783+
784+
workflowID := ctx.PathParam("workflow_id")
785+
if len(workflowID) == 0 {
786+
ctx.Error(http.StatusUnprocessableEntity, "MissingWorkflowParameter", util.NewInvalidArgumentErrorf("workflow_id is required parameter"))
787+
return
788+
}
789+
790+
ref := opt.Ref
791+
if len(ref) == 0 {
792+
ctx.Error(http.StatusUnprocessableEntity, "MissingWorkflowParameter", util.NewInvalidArgumentErrorf("ref is required parameter"))
793+
return
794+
}
795+
796+
actions_service.DispatchActionWorkflow(ctx, workflowID, opt)
797+
798+
ctx.Status(http.StatusNoContent)
799+
}
800+
801+
func (a ActionWorkflow) EnableWorkflow(ctx *context.APIContext) {
802+
// swagger:operation PUT /repos/{owner}/{repo}/actions/workflows/{workflow_id}/enable repository EnableWorkflow
803+
// ---
804+
// summary: Enable a workflow
805+
// produces:
806+
// - application/json
807+
// parameters:
808+
// - name: owner
809+
// in: path
810+
// description: owner of the repo
811+
// type: string
812+
// required: true
813+
// - name: repo
814+
// in: path
815+
// description: name of the repo
816+
// type: string
817+
// required: true
818+
// - name: workflow_id
819+
// in: path
820+
// description: id of the workflow
821+
// type: string
822+
// required: true
823+
// responses:
824+
// "204":
825+
// description: No Content
826+
// "400":
827+
// "$ref": "#/responses/error"
828+
// "403":
829+
// "$ref": "#/responses/forbidden"
830+
// "404":
831+
// "$ref": "#/responses/notFound"
832+
// "409":
833+
// "$ref": "#/responses/conflict"
834+
// "422":
835+
// "$ref": "#/responses/validationError"
836+
837+
workflowID := ctx.PathParam("workflow_id")
838+
if len(workflowID) == 0 {
839+
ctx.Error(http.StatusUnprocessableEntity, "MissingWorkflowParameter", util.NewInvalidArgumentErrorf("workflow_id is required parameter"))
840+
return
841+
}
842+
843+
err := actions_service.EnableActionWorkflow(ctx, workflowID)
844+
if err != nil {
845+
ctx.Error(http.StatusInternalServerError, "EnableActionWorkflow", err)
846+
return
847+
}
848+
849+
ctx.Status(http.StatusNoContent)
850+
}

routers/api/v1/swagger/action.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,17 @@ type swaggerResponseVariableList struct {
3232
// in:body
3333
Body []api.ActionVariable `json:"body"`
3434
}
35+
36+
// ActionWorkflow
37+
// swagger:response ActionWorkflow
38+
type swaggerResponseActionWorkflow struct {
39+
// in:body
40+
Body api.ActionWorkflow `json:"body"`
41+
}
42+
43+
// ActionWorkflowList
44+
// swagger:response ActionWorkflowList
45+
type swaggerResponseActionWorkflowList struct {
46+
// in:body
47+
Body []api.ActionWorkflow `json:"body"`
48+
}

routers/api/v1/swagger/options.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,9 @@ type swaggerParameterBodies struct {
211211
// in:body
212212
RenameOrgOption api.RenameOrgOption
213213

214+
// in:body
215+
CreateActionWorkflowDispatch api.CreateActionWorkflowDispatch
216+
214217
// in:body
215218
UpdateVariableOption api.UpdateVariableOption
216219
}

0 commit comments

Comments
 (0)