Skip to content

Commit

Permalink
Merge remote-tracking branch 'giteaofficial/main'
Browse files Browse the repository at this point in the history
* giteaofficial/main:
  add CfTurnstileSitekey context data to all captcha templates (go-gitea#31874)
  Add tag name in the commits list (go-gitea#31082)
  Fix actions notify bug (go-gitea#31866)
  Actions support workflow dispatch event (go-gitea#28163)
  • Loading branch information
zjjhot committed Aug 20, 2024
2 parents 8de67cb + 0d24c9f commit 17fe70a
Show file tree
Hide file tree
Showing 23 changed files with 666 additions and 35 deletions.
2 changes: 2 additions & 0 deletions models/migrations/migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,8 @@ var migrations = []Migration{
NewMigration("Add index to action_task stopped log_expired", v1_23.AddIndexToActionTaskStoppedLogExpired),
// v303 -> v304
NewMigration("Add metadata column for comment table", v1_23.AddCommentMetaDataColumn),
// v304 -> v305
NewMigration("Add index for release sha1", v1_23.AddIndexForReleaseSha1),
}

// GetCurrentDBVersion returns the current db version
Expand Down
13 changes: 13 additions & 0 deletions models/migrations/v1_23/v304.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package v1_23 //nolint

import "xorm.io/xorm"

func AddIndexForReleaseSha1(x *xorm.Engine) error {
type Release struct {
Sha1 string `xorm:"INDEX VARCHAR(64)"`
}
return x.Sync(new(Release))
}
16 changes: 15 additions & 1 deletion models/repo/release.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ type Release struct {
Target string
TargetBehind string `xorm:"-"` // to handle non-existing or empty target
Title string
Sha1 string `xorm:"VARCHAR(64)"`
Sha1 string `xorm:"INDEX VARCHAR(64)"`
NumCommits int64
NumCommitsBehind int64 `xorm:"-"`
Note string `xorm:"TEXT"`
Expand Down Expand Up @@ -537,3 +537,17 @@ func InsertReleases(ctx context.Context, rels ...*Release) error {

return committer.Commit()
}

func FindTagsByCommitIDs(ctx context.Context, repoID int64, commitIDs ...string) (map[string][]*Release, error) {
releases := make([]*Release, 0, len(commitIDs))
if err := db.GetEngine(ctx).Where("repo_id=?", repoID).
In("sha1", commitIDs).
Find(&releases); err != nil {
return nil, err
}
res := make(map[string][]*Release, len(releases))
for _, r := range releases {
res[r.Sha1] = append(res[r.Sha1], r)
}
return res, nil
}
13 changes: 13 additions & 0 deletions models/repo/release_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,16 @@ func TestMigrate_InsertReleases(t *testing.T) {
err := InsertReleases(db.DefaultContext, r)
assert.NoError(t, err)
}

func Test_FindTagsByCommitIDs(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())

sha1Rels, err := FindTagsByCommitIDs(db.DefaultContext, 1, "65f1bf27bc3bf70f64657658635e66094edbcb4d")
assert.NoError(t, err)
assert.Len(t, sha1Rels, 1)
rels := sha1Rels["65f1bf27bc3bf70f64657658635e66094edbcb4d"]
assert.Len(t, rels, 3)
assert.Equal(t, "v1.1", rels[0].TagName)
assert.Equal(t, "delete-tag", rels[1].TagName)
assert.Equal(t, "v1.0", rels[2].TagName)
}
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"`
Repository *Repository `json:"repository"`
Sender *User `json:"sender"`
}

// JSONPayload implements Payload
func (p *WorkflowDispatchPayload) JSONPayload() ([]byte, error) {
return json.MarshalIndent(p, "", " ")
}
7 changes: 7 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 @@ -1273,6 +1274,7 @@ commit_graph.color = Color
commit.contained_in = This commit is contained in:
commit.contained_in_default_branch = This commit is part of the default branch
commit.load_referencing_branches_and_tags = Load branches and tags referencing this commit
commit.load_tags_failed = Load tags failed because of internal error
blame = Blame
download_file = Download file
normal_view = Normal View
Expand Down Expand Up @@ -3701,6 +3703,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
3 changes: 3 additions & 0 deletions routers/web/auth/linkaccount.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ func LinkAccount(ctx *context.Context) {
ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey
ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey
ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL
ctx.Data["CfTurnstileSitekey"] = setting.Service.CfTurnstileSitekey
ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration
ctx.Data["AllowOnlyInternalRegistration"] = setting.Service.AllowOnlyInternalRegistration
ctx.Data["ShowRegistrationButton"] = false
Expand Down Expand Up @@ -132,6 +133,7 @@ func LinkAccountPostSignIn(ctx *context.Context) {
ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey
ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey
ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL
ctx.Data["CfTurnstileSitekey"] = setting.Service.CfTurnstileSitekey
ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration
ctx.Data["ShowRegistrationButton"] = false

Expand Down Expand Up @@ -219,6 +221,7 @@ func LinkAccountPostRegister(ctx *context.Context) {
ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey
ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey
ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL
ctx.Data["CfTurnstileSitekey"] = setting.Service.CfTurnstileSitekey
ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration
ctx.Data["ShowRegistrationButton"] = false

Expand Down
1 change: 1 addition & 0 deletions routers/web/auth/openid.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ func RegisterOpenID(ctx *context.Context) {
ctx.Data["RecaptchaURL"] = setting.Service.RecaptchaURL
ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey
ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL
ctx.Data["CfTurnstileSitekey"] = setting.Service.CfTurnstileSitekey
ctx.Data["OpenID"] = oid
userName, _ := ctx.Session.Get("openid_determined_username").(string)
if userName != "" {
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) {
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

0 comments on commit 17fe70a

Please sign in to comment.