|
4 | 4 | package repo |
5 | 5 |
|
6 | 6 | import ( |
7 | | - "code.gitea.io/gitea/models/perm" |
8 | | - access_model "code.gitea.io/gitea/models/perm/access" |
9 | | - "code.gitea.io/gitea/models/unit" |
10 | | - "code.gitea.io/gitea/modules/actions" |
11 | | - "code.gitea.io/gitea/modules/git" |
12 | 7 | "errors" |
13 | | - "github.com/nektos/act/pkg/jobparser" |
14 | | - "github.com/nektos/act/pkg/model" |
15 | 8 | "net/http" |
16 | | - "strconv" |
17 | | - "strings" |
18 | 9 |
|
19 | 10 | actions_model "code.gitea.io/gitea/models/actions" |
20 | 11 | "code.gitea.io/gitea/models/db" |
@@ -629,7 +620,20 @@ func (a ActionWorkflow) ListRepositoryWorkflows(ctx *context.APIContext) { |
629 | 620 | // "$ref": "#/responses/conflict" |
630 | 621 | // "422": |
631 | 622 | // "$ref": "#/responses/validationError" |
632 | | - panic("implement me") |
| 623 | + // "500": |
| 624 | + // "$ref": "#/responses/error" |
| 625 | + |
| 626 | + workflows, err := actions_service.ListActionWorkflows(ctx) |
| 627 | + if err != nil { |
| 628 | + return |
| 629 | + } |
| 630 | + |
| 631 | + if len(workflows) == 0 { |
| 632 | + ctx.JSON(http.StatusNotFound, nil) |
| 633 | + } |
| 634 | + |
| 635 | + ctx.SetTotalCountHeader(int64(len(workflows))) |
| 636 | + ctx.JSON(http.StatusOK, workflows) |
633 | 637 | } |
634 | 638 |
|
635 | 639 | func (a ActionWorkflow) GetWorkflow(ctx *context.APIContext) { |
@@ -667,7 +671,75 @@ func (a ActionWorkflow) GetWorkflow(ctx *context.APIContext) { |
667 | 671 | // "$ref": "#/responses/conflict" |
668 | 672 | // "422": |
669 | 673 | // "$ref": "#/responses/validationError" |
670 | | - panic("implement me") |
| 674 | + // "500": |
| 675 | + // "$ref": "#/responses/error" |
| 676 | + |
| 677 | + workflowID := ctx.PathParam("workflow_id") |
| 678 | + if len(workflowID) == 0 { |
| 679 | + ctx.Error(http.StatusUnprocessableEntity, "MissingWorkflowParameter", util.NewInvalidArgumentErrorf("workflow_id is required parameter")) |
| 680 | + return |
| 681 | + } |
| 682 | + |
| 683 | + workflow, err := actions_service.GetActionWorkflow(ctx, workflowID) |
| 684 | + if err != nil { |
| 685 | + return |
| 686 | + } |
| 687 | + |
| 688 | + if workflow == nil { |
| 689 | + ctx.JSON(http.StatusNotFound, nil) |
| 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 | + // "409": |
| 727 | + // "$ref": "#/responses/conflict" |
| 728 | + // "422": |
| 729 | + // "$ref": "#/responses/validationError" |
| 730 | + |
| 731 | + workflowID := ctx.PathParam("workflow_id") |
| 732 | + if len(workflowID) == 0 { |
| 733 | + ctx.Error(http.StatusUnprocessableEntity, "MissingWorkflowParameter", util.NewInvalidArgumentErrorf("workflow_id is required parameter")) |
| 734 | + return |
| 735 | + } |
| 736 | + |
| 737 | + err := actions_service.DisableActionWorkflow(ctx, workflowID) |
| 738 | + if err != nil { |
| 739 | + ctx.Error(http.StatusInternalServerError, "DisableActionWorkflow", err) |
| 740 | + } |
| 741 | + |
| 742 | + ctx.Status(http.StatusNoContent) |
671 | 743 | } |
672 | 744 |
|
673 | 745 | func (a ActionWorkflow) DispatchWorkflow(ctx *context.APIContext) { |
@@ -724,137 +796,57 @@ func (a ActionWorkflow) DispatchWorkflow(ctx *context.APIContext) { |
724 | 796 | return |
725 | 797 | } |
726 | 798 |
|
727 | | - // can not rerun job when workflow is disabled |
728 | | - cfgUnit := ctx.Repo.Repository.MustGetUnit(ctx, unit.TypeActions) |
729 | | - cfg := cfgUnit.ActionsConfig() |
730 | | - if cfg.IsWorkflowDisabled(workflowID) { |
731 | | - ctx.Error(http.StatusInternalServerError, "WorkflowDisabled", ctx.Tr("actions.workflow.disabled")) |
732 | | - return |
733 | | - } |
| 799 | + actions_service.DispatchActionWorkflow(ctx, workflowID, opt) |
734 | 800 |
|
735 | | - // get target commit of run from specified ref |
736 | | - refName := git.RefName(ref) |
737 | | - var runTargetCommit *git.Commit |
738 | | - var err error |
739 | | - if refName.IsTag() { |
740 | | - runTargetCommit, err = ctx.Repo.GitRepo.GetTagCommit(refName.TagName()) |
741 | | - } else if refName.IsBranch() { |
742 | | - // [E] PANIC: runtime error: invalid memory address or nil pointer dereference |
743 | | - runTargetCommit, err = ctx.Repo.GitRepo.GetBranchCommit(refName.BranchName()) |
744 | | - } else { |
745 | | - ctx.Error(http.StatusInternalServerError, "WorkflowRefNameError", ctx.Tr("form.git_ref_name_error", ref)) |
746 | | - return |
747 | | - } |
748 | | - if err != nil { |
749 | | - ctx.Error(http.StatusNotFound, "WorkflowRefNotFound", ctx.Tr("form.target_ref_not_exist", ref)) |
750 | | - return |
751 | | - } |
752 | | - |
753 | | - // get workflow entry from default branch commit |
754 | | - defaultBranchCommit, err := ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch) |
755 | | - if err != nil { |
756 | | - ctx.Error(http.StatusInternalServerError, "WorkflowDefaultBranchError", err.Error()) |
757 | | - return |
758 | | - } |
759 | | - entries, err := actions.ListWorkflows(defaultBranchCommit) |
760 | | - if err != nil { |
761 | | - ctx.Error(http.StatusInternalServerError, "WorkflowListError", err.Error()) |
762 | | - } |
763 | | - |
764 | | - // find workflow from commit |
765 | | - var workflows []*jobparser.SingleWorkflow |
766 | | - for _, entry := range entries { |
767 | | - if entry.Name() == workflowID { |
768 | | - content, err := actions.GetContentFromEntry(entry) |
769 | | - if err != nil { |
770 | | - ctx.Error(http.StatusInternalServerError, "WorkflowGetContentError", err.Error()) |
771 | | - return |
772 | | - } |
773 | | - workflows, err = jobparser.Parse(content) |
774 | | - if err != nil { |
775 | | - ctx.Error(http.StatusInternalServerError, "WorkflowParseError", err.Error()) |
776 | | - return |
777 | | - } |
778 | | - break |
779 | | - } |
780 | | - } |
781 | | - |
782 | | - if len(workflows) == 0 { |
783 | | - ctx.Error(http.StatusNotFound, "WorkflowNotFound", ctx.Tr("actions.workflow.not_found", workflowID)) |
784 | | - return |
785 | | - } |
786 | | - |
787 | | - workflow := &model.Workflow{ |
788 | | - RawOn: workflows[0].RawOn, |
789 | | - } |
790 | | - inputs := make(map[string]any) |
791 | | - if workflowDispatch := workflow.WorkflowDispatchConfig(); workflowDispatch != nil { |
792 | | - for name, config := range workflowDispatch.Inputs { |
793 | | - value, exists := opt.Inputs[name] |
794 | | - if !exists { |
795 | | - continue |
796 | | - } |
797 | | - if config.Type == "boolean" { |
798 | | - inputs[name] = strconv.FormatBool(value == "on") |
799 | | - } else if value != "" { |
800 | | - inputs[name] = value.(string) |
801 | | - } else { |
802 | | - inputs[name] = config.Default |
803 | | - } |
804 | | - } |
805 | | - } |
806 | | - |
807 | | - workflowDispatchPayload := &api.WorkflowDispatchPayload{ |
808 | | - Workflow: workflowID, |
809 | | - Ref: ref, |
810 | | - Repository: convert.ToRepo(ctx, ctx.Repo.Repository, access_model.Permission{AccessMode: perm.AccessModeNone}), |
811 | | - Inputs: inputs, |
812 | | - Sender: convert.ToUserWithAccessMode(ctx, ctx.Doer, perm.AccessModeNone), |
813 | | - } |
814 | | - var eventPayload []byte |
815 | | - if eventPayload, err = workflowDispatchPayload.JSONPayload(); err != nil { |
816 | | - ctx.Error(http.StatusInternalServerError, "WorkflowDispatchJSONParseError", err.Error()) |
817 | | - return |
818 | | - } |
819 | | - |
820 | | - run := &actions_model.ActionRun{ |
821 | | - Title: strings.SplitN(runTargetCommit.CommitMessage, "\n", 2)[0], |
822 | | - RepoID: ctx.Repo.Repository.ID, |
823 | | - OwnerID: ctx.Repo.Repository.Owner.ID, |
824 | | - WorkflowID: workflowID, |
825 | | - TriggerUserID: ctx.Doer.ID, |
826 | | - Ref: ref, |
827 | | - CommitSHA: runTargetCommit.ID.String(), |
828 | | - IsForkPullRequest: false, |
829 | | - Event: "workflow_dispatch", |
830 | | - TriggerEvent: "workflow_dispatch", |
831 | | - EventPayload: string(eventPayload), |
832 | | - Status: actions_model.StatusWaiting, |
833 | | - } |
| 801 | + ctx.Status(http.StatusNoContent) |
| 802 | +} |
834 | 803 |
|
835 | | - // cancel running jobs of the same workflow |
836 | | - if err := actions_model.CancelPreviousJobs( |
837 | | - ctx, |
838 | | - run.RepoID, |
839 | | - run.Ref, |
840 | | - run.WorkflowID, |
841 | | - run.Event, |
842 | | - ); err != nil { |
843 | | - ctx.Error(http.StatusInternalServerError, "WorkflowCancelPreviousJobsError", err.Error()) |
844 | | - return |
845 | | - } |
| 804 | +func (a ActionWorkflow) EnableWorkflow(ctx *context.APIContext) { |
| 805 | + // swagger:operation PUT /repos/{owner}/{repo}/actions/workflows/{workflow_id}/enable repository EnableWorkflow |
| 806 | + // --- |
| 807 | + // summary: Enable a workflow |
| 808 | + // produces: |
| 809 | + // - application/json |
| 810 | + // parameters: |
| 811 | + // - name: owner |
| 812 | + // in: path |
| 813 | + // description: owner of the repo |
| 814 | + // type: string |
| 815 | + // required: true |
| 816 | + // - name: repo |
| 817 | + // in: path |
| 818 | + // description: name of the repo |
| 819 | + // type: string |
| 820 | + // required: true |
| 821 | + // - name: workflow_id |
| 822 | + // in: path |
| 823 | + // description: id of the workflow |
| 824 | + // type: string |
| 825 | + // required: true |
| 826 | + // responses: |
| 827 | + // "204": |
| 828 | + // description: No Content |
| 829 | + // "400": |
| 830 | + // "$ref": "#/responses/error" |
| 831 | + // "403": |
| 832 | + // "$ref": "#/responses/forbidden" |
| 833 | + // "404": |
| 834 | + // "$ref": "#/responses/notFound" |
| 835 | + // "409": |
| 836 | + // "$ref": "#/responses/conflict" |
| 837 | + // "422": |
| 838 | + // "$ref": "#/responses/validationError" |
846 | 839 |
|
847 | | - if err := actions_model.InsertRun(ctx, run, workflows); err != nil { |
848 | | - ctx.Error(http.StatusInternalServerError, "WorkflowInsertRunError", err.Error()) |
| 840 | + workflowID := ctx.PathParam("workflow_id") |
| 841 | + if len(workflowID) == 0 { |
| 842 | + ctx.Error(http.StatusUnprocessableEntity, "MissingWorkflowParameter", util.NewInvalidArgumentErrorf("workflow_id is required parameter")) |
849 | 843 | return |
850 | 844 | } |
851 | 845 |
|
852 | | - alljobs, err := db.Find[actions_model.ActionRunJob](ctx, actions_model.FindRunJobOptions{RunID: run.ID}) |
| 846 | + err := actions_service.EnableActionWorkflow(ctx, workflowID) |
853 | 847 | if err != nil { |
854 | | - ctx.Error(http.StatusInternalServerError, "WorkflowFindRunJobError", err.Error()) |
855 | | - return |
| 848 | + ctx.Error(http.StatusInternalServerError, "EnableActionWorkflow", err) |
856 | 849 | } |
857 | | - actions_service.CreateCommitStatus(ctx, alljobs...) |
858 | 850 |
|
859 | 851 | ctx.Status(http.StatusNoContent) |
860 | 852 | } |
0 commit comments