Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Actions support workflow dispatch event #28163

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
fbadf6f
Actions support workflow dispatch event
pangliang Nov 22, 2023
8eb79f3
fix lint check, /actions/run use isAdmin permission
pangliang Nov 23, 2023
d973fc1
workflow_dispatch support inputs config
pangliang Nov 29, 2023
e18bbcc
Use db.Find instead of writing methods for every object (#28084)
pangliang Nov 29, 2023
d0a70d3
Use Crowdin to translate them
pangliang Dec 4, 2023
2d2f921
Add ref selector for run workflow from
pangliang Dec 5, 2023
660cf18
Follow the behavior of github, only render templates, do not directly…
pangliang Dec 5, 2023
2829a88
Form validate
pangliang Dec 5, 2023
f4a55d1
unnecessary parameters
pangliang Dec 7, 2023
5afedfd
There is no need to readWorkflow again
pangliang Dec 7, 2023
1b7864d
Missed Disabled check.
pangliang Dec 7, 2023
0e67591
Checkbox has its own label
pangliang Dec 7, 2023
300f068
ParseRawOn is not required, use WorkflowDispatchConfig instead
pangliang Dec 7, 2023
a7c0016
fix go.sum
pangliang Dec 7, 2023
36c47f1
hard code event workflow_dispatch for now
pangliang Dec 7, 2023
78d636f
AllowTriggerWorkflowDispatchEvent is unnecessary
pangliang Dec 7, 2023
44615a5
support type "number" form validation
pangliang Dec 7, 2023
c24dede
Returns nil when workflow_dispatch is not defined
pangliang Dec 7, 2023
65b0313
Add WorkflowDispatchPayload for pass Webhook event payload to runner
pangliang Dec 7, 2023
faf3b08
DetectedWorkflow unnecessary
pangliang Dec 7, 2023
1f64b24
only required is enough.
pangliang Dec 11, 2023
5e0a0bc
should omit nil check
pangliang Dec 11, 2023
5ddf23a
Remove unsupported description section of workflow_dispatch from docu…
pangliang Dec 11, 2023
a6db416
Fix workflow dispatch ui
TKaxv-7S Dec 11, 2023
ab84156
update gitea.com/gitea/act to v0.2.59
pangliang Mar 1, 2024
c9aeacc
rebase github/gitea main
pangliang Mar 1, 2024
b3203b4
import fmt
pangliang Mar 1, 2024
5b51dfb
import fmt
pangliang Mar 1, 2024
d1f8cef
Merge branch 'main' into actions_support_workflow_dispatch_event
techknowlogick Mar 2, 2024
e78a88d
lint fail: "undefined: util"
pangliang Mar 3, 2024
82e27b8
Merge remote-tracking branch 'origin/main' into actions_support_workf…
pangliang Mar 3, 2024
9fc0e0d
Wrong indentation type(spaces instead of tabs)
pangliang Mar 3, 2024
4a34fc8
fmt-check fail
pangliang Mar 3, 2024
ce55bd5
Adopted suggested change from @silverwind
pangliang Mar 6, 2024
57653ac
smaller submit button
pangliang Mar 6, 2024
28350dc
Revert "smaller submit button"
pangliang Mar 7, 2024
50694f2
smaller branch dropdown button
pangliang Mar 7, 2024
b261c3c
Merge branch 'main' into actions_support_workflow_dispatch_event
silverwind Mar 7, 2024
0027bc9
Merge remote-tracking branch 'origin/main' into actions_support_workf…
pangliang Mar 8, 2024
85ec450
change branch dropdown text font-size to small
pangliang Mar 8, 2024
1d20af3
GetTagNamesByRepoID error handle as branch
pangliang Mar 9, 2024
7c9eba6
remove project-column-header class
pangliang Mar 9, 2024
c0b87a5
remove spaces before colon
pangliang Mar 9, 2024
b2092d2
some Translate text
pangliang Mar 9, 2024
6d3c634
unnecessary i tag
pangliang Mar 9, 2024
8e70046
font-size use css class
pangliang Mar 9, 2024
8d23757
Merge branch 'main' into actions_support_workflow_dispatch_event
silverwind Mar 25, 2024
8312260
Update templates/repo/actions/workflow_dispatch.tmpl
silverwind Mar 25, 2024
2d882b0
Update templates/repo/actions/workflow_dispatch.tmpl
silverwind Mar 25, 2024
65de06e
fix lint check fail
pangliang Mar 29, 2024
4097052
Merge remote-tracking branch 'origin/main' into actions_support_workf…
pangliang Mar 29, 2024
43e0e3d
Merge remote-tracking branch 'origin/main' into actions_support_workf…
pangliang Apr 7, 2024
eb71452
Merge branch 'main' into actions_support_workflow_dispatch_event
techknowlogick Apr 7, 2024
cf5fe7f
Merge branch 'main' into actions_support_workflow_dispatch_event
silverwind Apr 8, 2024
83fb4b0
Merge remote-tracking branch 'origin/main' into actions_support_workf…
pangliang Apr 17, 2024
ea31b78
Replace `interface{}` with `any`
pangliang Apr 17, 2024
c159998
Merge remote-tracking branch 'origin/main' into actions_support_workf…
silverwind Apr 24, 2024
d2588fd
Many fixes to the branch selector
silverwind Apr 24, 2024
4683d81
extra empty line at the end of a block
pangliang Apr 25, 2024
899abcf
add workflow dispatch
denyskon Aug 14, 2024
91358ac
Merge branch 'workflow-dispatch' into actions_support_workflow_dispat…
denyskon Aug 14, 2024
052acfe
Merge pull request #5 from denyskon/actions_support_workflow_dispatch…
pangliang Aug 16, 2024
283d475
Use a separate WorkflowDispatch structure in the view to keep the inp…
pangliang Aug 16, 2024
20896ed
Fix lint check error
pangliang Aug 16, 2024
ef3a18a
Fix checks-backend error
pangliang Aug 16, 2024
ecb0f41
Fix checks-backend error
pangliang Aug 16, 2024
d682687
Fix checks-backend error
pangliang Aug 16, 2024
ddd8b37
Merge branch 'main' into actions_support_workflow_dispatch_event
GiteaBot Aug 16, 2024
791e790
Update templates/repo/actions/workflow_dispatch.tmpl
lunny Aug 17, 2024
94029b6
Update templates/repo/issue/branch_selector_field.tmpl
lunny Aug 17, 2024
2ea6fa2
Merge branch 'main' into actions_support_workflow_dispatch_event
GiteaBot Aug 17, 2024
b88ae0f
Merge branch 'main' into actions_support_workflow_dispatch_event
GiteaBot Aug 18, 2024
e3e321b
Merge branch 'main' into actions_support_workflow_dispatch_event
GiteaBot Aug 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions modules/structs/hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -494,3 +494,17 @@ type PackagePayload struct {
func (p *PackagePayload) JSONPayload() ([]byte, error) {
return json.MarshalIndent(p, "", " ")
}

// WorkflowDispatchPayload represents a workflow dispatch payload
type WorkflowDispatchPayload struct {
Workflow string `json:"workflow"`
Ref string `json:"ref"`
Inputs map[string]any `json:"inputs"`
lunny marked this conversation as resolved.
Show resolved Hide resolved
Repository *Repository `json:"repository"`
Sender *User `json:"sender"`
}

// JSONPayload implements Payload
func (p *WorkflowDispatchPayload) JSONPayload() ([]byte, error) {
return json.MarshalIndent(p, "", " ")
}
6 changes: 6 additions & 0 deletions options/locale/locale_en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,7 @@ org_still_own_repo = "This organization still owns one or more repositories, del
org_still_own_packages = "This organization still owns one or more packages, delete them first."

target_branch_not_exist = Target branch does not exist.
target_ref_not_exist = Target ref does not exist %s

admin_cannot_delete_self = You cannot delete yourself when you are an admin. Please remove your admin privileges first.

Expand Down Expand Up @@ -3701,6 +3702,11 @@ workflow.disable_success = Workflow '%s' disabled successfully.
workflow.enable = Enable Workflow
workflow.enable_success = Workflow '%s' enabled successfully.
workflow.disabled = Workflow is disabled.
workflow.run = Run Workflow
workflow.not_found = Workflow '%s' not found.
workflow.run_success = Workflow '%s' run successfully.
workflow.from_ref = Use workflow from
workflow.has_workflow_dispatch = This workflow has a workflow_dispatch event trigger.

need_approval_desc = Need approval to run workflows for fork pull request.

Expand Down
145 changes: 136 additions & 9 deletions routers/web/repo/actions/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,28 @@ import (
"bytes"
"fmt"
"net/http"
"slices"
"strings"

actions_model "code.gitea.io/gitea/models/actions"
"code.gitea.io/gitea/models/db"
git_model "code.gitea.io/gitea/models/git"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit"
"code.gitea.io/gitea/modules/actions"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/optional"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/routers/web/repo"
"code.gitea.io/gitea/services/context"
"code.gitea.io/gitea/services/convert"

"github.com/nektos/act/pkg/model"
"gopkg.in/yaml.v3"
)

const (
Expand Down Expand Up @@ -58,8 +64,13 @@ func MustEnableActions(ctx *context.Context) {
func List(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("actions.actions")
ctx.Data["PageIsActions"] = true
workflowID := ctx.FormString("workflow")
actorID := ctx.FormInt64("actor")
status := ctx.FormInt("status")
ctx.Data["CurWorkflow"] = workflowID

var workflows []Workflow
var curWorkflow *model.Workflow
if empty, err := ctx.Repo.GitRepo.IsEmpty(); err != nil {
ctx.ServerError("IsEmpty", err)
return
Expand Down Expand Up @@ -140,6 +151,10 @@ func List(ctx *context.Context) {
workflow.ErrMsg = ctx.Locale.TrString("actions.runs.no_job")
}
workflows = append(workflows, workflow)

if workflow.Entry.Name() == workflowID {
curWorkflow = wf
}
}
}
ctx.Data["workflows"] = workflows
Expand All @@ -150,17 +165,46 @@ func List(ctx *context.Context) {
page = 1
}

workflow := ctx.FormString("workflow")
actorID := ctx.FormInt64("actor")
status := ctx.FormInt("status")
ctx.Data["CurWorkflow"] = workflow

actionsConfig := ctx.Repo.Repository.MustGetUnit(ctx, unit.TypeActions).ActionsConfig()
ctx.Data["ActionsConfig"] = actionsConfig

if len(workflow) > 0 && ctx.Repo.IsAdmin() {
if len(workflowID) > 0 && ctx.Repo.IsAdmin() {
ctx.Data["AllowDisableOrEnableWorkflow"] = true
ctx.Data["CurWorkflowDisabled"] = actionsConfig.IsWorkflowDisabled(workflow)
isWorkflowDisabled := actionsConfig.IsWorkflowDisabled(workflowID)
ctx.Data["CurWorkflowDisabled"] = isWorkflowDisabled

if !isWorkflowDisabled && curWorkflow != nil {
workflowDispatchConfig := workflowDispatchConfig(curWorkflow)
if workflowDispatchConfig != nil {
ctx.Data["WorkflowDispatchConfig"] = workflowDispatchConfig

branchOpts := git_model.FindBranchOptions{
RepoID: ctx.Repo.Repository.ID,
IsDeletedBranch: optional.Some(false),
ListOptions: db.ListOptions{
ListAll: true,
},
}
branches, err := git_model.FindBranchNames(ctx, branchOpts)
if err != nil {
ctx.ServerError("FindBranchNames", err)
return
}
// always put default branch on the top if it exists
if slices.Contains(branches, ctx.Repo.Repository.DefaultBranch) {
lunny marked this conversation as resolved.
Show resolved Hide resolved
branches = util.SliceRemoveAll(branches, ctx.Repo.Repository.DefaultBranch)
branches = append([]string{ctx.Repo.Repository.DefaultBranch}, branches...)
}
ctx.Data["Branches"] = branches

tags, err := repo_model.GetTagNamesByRepoID(ctx, ctx.Repo.Repository.ID)
if err != nil {
ctx.ServerError("GetTagNamesByRepoID", err)
return
}
ctx.Data["Tags"] = tags
}
}
}

// if status or actor query param is not given to frontend href, (href="/<repoLink>/actions")
Expand All @@ -177,7 +221,7 @@ func List(ctx *context.Context) {
PageSize: convert.ToCorrectPageSize(ctx.FormInt("limit")),
},
RepoID: ctx.Repo.Repository.ID,
WorkflowID: workflow,
WorkflowID: workflowID,
TriggerUserID: actorID,
}

Expand Down Expand Up @@ -214,11 +258,94 @@ func List(ctx *context.Context) {

pager := context.NewPagination(int(total), opts.PageSize, opts.Page, 5)
pager.SetDefaultParams(ctx)
pager.AddParamString("workflow", workflow)
pager.AddParamString("workflow", workflowID)
pager.AddParamString("actor", fmt.Sprint(actorID))
pager.AddParamString("status", fmt.Sprint(status))
ctx.Data["Page"] = pager
ctx.Data["HasWorkflowsOrRuns"] = len(workflows) > 0 || len(runs) > 0

ctx.HTML(http.StatusOK, tplListActions)
}

type WorkflowDispatchInput struct {
Name string `yaml:"name"`
Description string `yaml:"description"`
Required bool `yaml:"required"`
Default string `yaml:"default"`
Type string `yaml:"type"`
Options []string `yaml:"options"`
}

type WorkflowDispatch struct {
Inputs []WorkflowDispatchInput
}

func workflowDispatchConfig(w *model.Workflow) *WorkflowDispatch {
switch w.RawOn.Kind {
case yaml.ScalarNode:
var val string
if !decodeNode(w.RawOn, &val) {
return nil
}
if val == "workflow_dispatch" {
return &WorkflowDispatch{}
}
case yaml.SequenceNode:
var val []string
if !decodeNode(w.RawOn, &val) {
return nil
}
for _, v := range val {
if v == "workflow_dispatch" {
return &WorkflowDispatch{}
}
}
case yaml.MappingNode:
var val map[string]yaml.Node
if !decodeNode(w.RawOn, &val) {
return nil
}

workflowDispatchNode, found := val["workflow_dispatch"]
if !found {
return nil
}

var workflowDispatch WorkflowDispatch
var workflowDispatchVal map[string]yaml.Node
if !decodeNode(workflowDispatchNode, &workflowDispatchVal) {
return &workflowDispatch
}

inputsNode, found := workflowDispatchVal["inputs"]
if !found || inputsNode.Kind != yaml.MappingNode {
return &workflowDispatch
}

i := 0
for {
if i+1 >= len(inputsNode.Content) {
break
}
var input WorkflowDispatchInput
if decodeNode(*inputsNode.Content[i+1], &input) {
input.Name = inputsNode.Content[i].Value
workflowDispatch.Inputs = append(workflowDispatch.Inputs, input)
}
i += 2
}
return &workflowDispatch

default:
return nil
}
return nil
}

func decodeNode(node yaml.Node, out any) bool {
if err := node.Decode(out); err != nil {
log.Warn("Failed to decode node %v into %T: %v", node, out, err)
return false
}
return true
}
Loading