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