@@ -6,6 +6,7 @@ package repo
66import (
77 "errors"
88 "net/http"
9+ "strings"
910
1011 actions_model "code.gitea.io/gitea/models/actions"
1112 "code.gitea.io/gitea/models/db"
@@ -19,6 +20,8 @@ import (
1920 "code.gitea.io/gitea/services/context"
2021 "code.gitea.io/gitea/services/convert"
2122 secret_service "code.gitea.io/gitea/services/secrets"
23+
24+ "github.com/nektos/act/pkg/model"
2225)
2326
2427// ListActionsSecrets list an repo's actions secrets
@@ -581,3 +584,270 @@ func ListActionTasks(ctx *context.APIContext) {
581584
582585 ctx .JSON (http .StatusOK , & res )
583586}
587+
588+ func ActionsListRepositoryWorkflows (ctx * context.APIContext ) {
589+ // swagger:operation GET /repos/{owner}/{repo}/actions/workflows repository ActionsListRepositoryWorkflows
590+ // ---
591+ // summary: List repository workflows
592+ // produces:
593+ // - application/json
594+ // parameters:
595+ // - name: owner
596+ // in: path
597+ // description: owner of the repo
598+ // type: string
599+ // required: true
600+ // - name: repo
601+ // in: path
602+ // description: name of the repo
603+ // type: string
604+ // required: true
605+ // responses:
606+ // "200":
607+ // "$ref": "#/responses/ActionWorkflowList"
608+ // "400":
609+ // "$ref": "#/responses/error"
610+ // "403":
611+ // "$ref": "#/responses/forbidden"
612+ // "404":
613+ // "$ref": "#/responses/notFound"
614+ // "422":
615+ // "$ref": "#/responses/validationError"
616+ // "500":
617+ // "$ref": "#/responses/error"
618+
619+ workflows , err := actions_service .ListActionWorkflows (ctx )
620+ if err != nil {
621+ ctx .Error (http .StatusInternalServerError , "ListActionWorkflows" , err )
622+ return
623+ }
624+
625+ ctx .JSON (http .StatusOK , & api.ActionWorkflowResponse {Workflows : workflows , TotalCount : int64 (len (workflows ))})
626+ }
627+
628+ func ActionsGetWorkflow (ctx * context.APIContext ) {
629+ // swagger:operation GET /repos/{owner}/{repo}/actions/workflows/{workflow_id} repository ActionsGetWorkflow
630+ // ---
631+ // summary: Get a workflow
632+ // produces:
633+ // - application/json
634+ // parameters:
635+ // - name: owner
636+ // in: path
637+ // description: owner of the repo
638+ // type: string
639+ // required: true
640+ // - name: repo
641+ // in: path
642+ // description: name of the repo
643+ // type: string
644+ // required: true
645+ // - name: workflow_id
646+ // in: path
647+ // description: id of the workflow
648+ // type: string
649+ // required: true
650+ // responses:
651+ // "200":
652+ // "$ref": "#/responses/ActionWorkflow"
653+ // "400":
654+ // "$ref": "#/responses/error"
655+ // "403":
656+ // "$ref": "#/responses/forbidden"
657+ // "404":
658+ // "$ref": "#/responses/notFound"
659+ // "422":
660+ // "$ref": "#/responses/validationError"
661+ // "500":
662+ // "$ref": "#/responses/error"
663+
664+ workflowID := ctx .PathParam ("workflow_id" )
665+ workflow , err := actions_service .GetActionWorkflow (ctx , workflowID )
666+ if err != nil {
667+ if errors .Is (err , util .ErrNotExist ) {
668+ ctx .Error (http .StatusNotFound , "GetActionWorkflow" , err )
669+ } else {
670+ ctx .Error (http .StatusInternalServerError , "GetActionWorkflow" , err )
671+ }
672+ return
673+ }
674+
675+ ctx .JSON (http .StatusOK , workflow )
676+ }
677+
678+ func ActionsDisableWorkflow (ctx * context.APIContext ) {
679+ // swagger:operation PUT /repos/{owner}/{repo}/actions/workflows/{workflow_id}/disable repository ActionsDisableWorkflow
680+ // ---
681+ // summary: Disable a workflow
682+ // produces:
683+ // - application/json
684+ // parameters:
685+ // - name: owner
686+ // in: path
687+ // description: owner of the repo
688+ // type: string
689+ // required: true
690+ // - name: repo
691+ // in: path
692+ // description: name of the repo
693+ // type: string
694+ // required: true
695+ // - name: workflow_id
696+ // in: path
697+ // description: id of the workflow
698+ // type: string
699+ // required: true
700+ // responses:
701+ // "204":
702+ // description: No Content
703+ // "400":
704+ // "$ref": "#/responses/error"
705+ // "403":
706+ // "$ref": "#/responses/forbidden"
707+ // "404":
708+ // "$ref": "#/responses/notFound"
709+ // "422":
710+ // "$ref": "#/responses/validationError"
711+
712+ workflowID := ctx .PathParam ("workflow_id" )
713+ err := actions_service .EnableOrDisableWorkflow (ctx , workflowID , false )
714+ if err != nil {
715+ if errors .Is (err , util .ErrNotExist ) {
716+ ctx .Error (http .StatusNotFound , "DisableActionWorkflow" , err )
717+ } else {
718+ ctx .Error (http .StatusInternalServerError , "DisableActionWorkflow" , err )
719+ }
720+ return
721+ }
722+
723+ ctx .Status (http .StatusNoContent )
724+ }
725+
726+ func ActionsDispatchWorkflow (ctx * context.APIContext ) {
727+ // swagger:operation POST /repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches repository ActionsDispatchWorkflow
728+ // ---
729+ // summary: Create a workflow dispatch event
730+ // produces:
731+ // - application/json
732+ // parameters:
733+ // - name: owner
734+ // in: path
735+ // description: owner of the repo
736+ // type: string
737+ // required: true
738+ // - name: repo
739+ // in: path
740+ // description: name of the repo
741+ // type: string
742+ // required: true
743+ // - name: workflow_id
744+ // in: path
745+ // description: id of the workflow
746+ // type: string
747+ // required: true
748+ // - name: body
749+ // in: body
750+ // schema:
751+ // "$ref": "#/definitions/CreateActionWorkflowDispatch"
752+ // responses:
753+ // "204":
754+ // description: No Content
755+ // "400":
756+ // "$ref": "#/responses/error"
757+ // "403":
758+ // "$ref": "#/responses/forbidden"
759+ // "404":
760+ // "$ref": "#/responses/notFound"
761+ // "422":
762+ // "$ref": "#/responses/validationError"
763+
764+ workflowID := ctx .PathParam ("workflow_id" )
765+ opt := web .GetForm (ctx ).(* api.CreateActionWorkflowDispatch )
766+ if opt .Ref == "" {
767+ ctx .Error (http .StatusUnprocessableEntity , "MissingWorkflowParameter" , util .NewInvalidArgumentErrorf ("ref is required parameter" ))
768+ return
769+ }
770+
771+ err := actions_service .DispatchActionWorkflow (ctx , ctx .Doer , ctx .Repo .Repository , ctx .Repo .GitRepo , workflowID , opt .Ref , func (workflowDispatch * model.WorkflowDispatch , inputs map [string ]any ) error {
772+ if strings .Contains (ctx .Req .Header .Get ("Content-Type" ), "form-urlencoded" ) {
773+ // The chi framework's "Binding" doesn't support to bind the form map values into a map[string]string
774+ // So we have to manually read the `inputs[key]` from the form
775+ for name , config := range workflowDispatch .Inputs {
776+ value := ctx .FormString ("inputs[" + name + "]" , config .Default )
777+ inputs [name ] = value
778+ }
779+ } else {
780+ for name , config := range workflowDispatch .Inputs {
781+ value , ok := opt .Inputs [name ]
782+ if ok {
783+ inputs [name ] = value
784+ } else {
785+ inputs [name ] = config .Default
786+ }
787+ }
788+ }
789+ return nil
790+ })
791+ if err != nil {
792+ if errors .Is (err , util .ErrNotExist ) {
793+ ctx .Error (http .StatusNotFound , "DispatchActionWorkflow" , err )
794+ } else if errors .Is (err , util .ErrPermissionDenied ) {
795+ ctx .Error (http .StatusForbidden , "DispatchActionWorkflow" , err )
796+ } else {
797+ ctx .Error (http .StatusInternalServerError , "DispatchActionWorkflow" , err )
798+ }
799+ return
800+ }
801+
802+ ctx .Status (http .StatusNoContent )
803+ }
804+
805+ func ActionsEnableWorkflow (ctx * context.APIContext ) {
806+ // swagger:operation PUT /repos/{owner}/{repo}/actions/workflows/{workflow_id}/enable repository ActionsEnableWorkflow
807+ // ---
808+ // summary: Enable a workflow
809+ // produces:
810+ // - application/json
811+ // parameters:
812+ // - name: owner
813+ // in: path
814+ // description: owner of the repo
815+ // type: string
816+ // required: true
817+ // - name: repo
818+ // in: path
819+ // description: name of the repo
820+ // type: string
821+ // required: true
822+ // - name: workflow_id
823+ // in: path
824+ // description: id of the workflow
825+ // type: string
826+ // required: true
827+ // responses:
828+ // "204":
829+ // description: No Content
830+ // "400":
831+ // "$ref": "#/responses/error"
832+ // "403":
833+ // "$ref": "#/responses/forbidden"
834+ // "404":
835+ // "$ref": "#/responses/notFound"
836+ // "409":
837+ // "$ref": "#/responses/conflict"
838+ // "422":
839+ // "$ref": "#/responses/validationError"
840+
841+ workflowID := ctx .PathParam ("workflow_id" )
842+ err := actions_service .EnableOrDisableWorkflow (ctx , workflowID , true )
843+ if err != nil {
844+ if errors .Is (err , util .ErrNotExist ) {
845+ ctx .Error (http .StatusNotFound , "EnableActionWorkflow" , err )
846+ } else {
847+ ctx .Error (http .StatusInternalServerError , "EnableActionWorkflow" , err )
848+ }
849+ return
850+ }
851+
852+ ctx .Status (http .StatusNoContent )
853+ }
0 commit comments