1
1
Fork 1
mirror of https://github.com/go-gitea/gitea.git synced 2024-05-08 09:46:13 +02:00

Compare commits

...

61 Commits

Author SHA1 Message Date
胖梁 2b5d2c4083
Merge 4683d81648 into 27861d711b 2024-04-27 11:32:55 +08:00
GiteaBot 27861d711b [skip ci] Updated translations via Crowdin 2024-04-27 00:24:31 +00:00
pangliang 4683d81648 extra empty line at the end of a block 2024-04-25 08:41:39 +08:00
silverwind d2588fd3b1
Many fixes to the branch selector 2024-04-25 01:05:12 +02:00
silverwind c159998087
Merge remote-tracking branch 'origin/main' into actions_support_workflow_dispatch_event
* origin/main: (62 commits)
  Add test for #30674 (#30679)
  Fix border-radius of header+segment boxes (#30667)
  Fix a panic bug when head repository deleting (#30674)
  Fix some bug on migrations (#30647)
  Fix checkbox field markup (#30666)
  Avoid doubled border for the PR info segment (#30663)
  Interpolate runs-on with variables when scheduling tasks (#30640)
  Initial support for colorblindness-friendly themes (#30625)
  Fix flash message for flex-container (#30657)
  Perform Newest sort type correctly when sorting issues (#30644)
  Fix project name wrapping, remove horizontal margin on header (#30631)
  Add a db consistency check to remove runners that do not belong to a repository (#30614)
  Fix wrong table name (#30557)
  Fix compare api swagger (#30648)
  [skip ci] Updated translations via Crowdin
  Fix queue test (#30646)
  Enable jquery-related eslint rules that have no violations (#30632)
  Enable more `revive` linter rules (#30608)
  Remove obsolete CSS text classes (#30576)
  Hide diff stats on empty PRs (#30629)
  ...
2024-04-25 00:08:36 +02:00
pangliang ea31b78e39 Replace `interface{}` with `any` 2024-04-17 15:28:32 +08:00
pangliang 83fb4b0594 Merge remote-tracking branch 'origin/main' into actions_support_workflow_dispatch_event 2024-04-17 11:12:35 +08:00
silverwind cf5fe7fb86
Merge branch 'main' into actions_support_workflow_dispatch_event 2024-04-09 00:28:42 +02:00
techknowlogick eb714523c1
Merge branch 'main' into actions_support_workflow_dispatch_event 2024-04-07 16:59:12 -04:00
pangliang 43e0e3dab0 Merge remote-tracking branch 'origin/main' into actions_support_workflow_dispatch_event 2024-04-07 13:24:05 +08:00
pangliang 4097052884 Merge remote-tracking branch 'origin/main' into actions_support_workflow_dispatch_event 2024-03-29 16:24:36 +08:00
pangliang 65de06e9e1 fix lint check fail 2024-03-29 16:21:39 +08:00
silverwind 2d882b078d
Update templates/repo/actions/workflow_dispatch.tmpl 2024-03-26 00:15:49 +01:00
silverwind 8312260add
Update templates/repo/actions/workflow_dispatch.tmpl 2024-03-26 00:15:16 +01:00
silverwind 8d2375717a
Merge branch 'main' into actions_support_workflow_dispatch_event 2024-03-26 00:14:02 +01:00
pangliang 8e7004643e font-size use css class 2024-03-09 17:31:28 +08:00
pangliang 6d3c634c89 unnecessary i tag 2024-03-09 12:29:22 +08:00
pangliang b2092d2d5a some Translate text 2024-03-09 12:21:47 +08:00
pangliang c0b87a502a remove spaces before colon 2024-03-09 12:16:50 +08:00
pangliang 7c9eba6a0c remove project-column-header class 2024-03-09 12:16:05 +08:00
pangliang 1d20af3af8 GetTagNamesByRepoID error handle as branch 2024-03-09 09:17:31 +08:00
pangliang 85ec4508cc change branch dropdown text font-size to small 2024-03-08 22:32:27 +08:00
pangliang 0027bc957f Merge remote-tracking branch 'origin/main' into actions_support_workflow_dispatch_event
# Conflicts:
#	go.mod
#	go.sum
2024-03-08 22:28:53 +08:00
silverwind b261c3c298
Merge branch 'main' into actions_support_workflow_dispatch_event 2024-03-07 08:06:13 +01:00
pangliang 50694f2477 smaller branch dropdown button 2024-03-07 08:13:48 +08:00
pangliang 28350dc0b5 Revert "smaller submit button"
This reverts commit 57653ac0a1.
2024-03-07 08:08:51 +08:00
pangliang 57653ac0a1 smaller submit button 2024-03-06 18:46:00 +08:00
pangliang ce55bd577c Adopted suggested change from @silverwind 2024-03-06 08:34:15 +08:00
pangliang 4a34fc84cd fmt-check fail 2024-03-03 09:55:03 +08:00
pangliang 9fc0e0ddb1 Wrong indentation type(spaces instead of tabs) 2024-03-03 09:54:34 +08:00
pangliang 82e27b8509 Merge remote-tracking branch 'origin/main' into actions_support_workflow_dispatch_event 2024-03-03 09:44:40 +08:00
pangliang e78a88ddd4 lint fail: "undefined: util" 2024-03-03 09:43:40 +08:00
techknowlogick d1f8cef61b
Merge branch 'main' into actions_support_workflow_dispatch_event 2024-03-02 18:40:17 -05:00
pangliang 5b51dfbb8f import fmt 2024-03-01 22:08:57 +08:00
pangliang b3203b4c8c import fmt 2024-03-01 19:58:16 +08:00
pangliang c9aeacc374 rebase github/gitea main 2024-03-01 19:46:31 +08:00
pangliang ab84156a32 update gitea.com/gitea/act to v0.2.59 2024-03-01 19:46:11 +08:00
TKaxv_7S a6db416577 Fix workflow dispatch ui 2024-03-01 19:40:57 +08:00
pangliang 5ddf23ac33 Remove unsupported description section of workflow_dispatch from documentation 2024-03-01 19:40:57 +08:00
pangliang 5e0a0bca4c should omit nil check 2024-03-01 19:40:57 +08:00
pangliang 1f64b24f03 only required is enough. 2024-03-01 19:40:57 +08:00
pangliang faf3b087b1 DetectedWorkflow unnecessary 2024-03-01 19:40:57 +08:00
pangliang 65b0313433 Add WorkflowDispatchPayload for pass Webhook event payload to runner 2024-03-01 19:40:57 +08:00
pangliang c24dede6eb Returns nil when workflow_dispatch is not defined 2024-03-01 19:40:57 +08:00
pangliang 44615a5211 support type "number" form validation 2024-03-01 19:40:57 +08:00
pangliang 78d636f045 AllowTriggerWorkflowDispatchEvent is unnecessary 2024-03-01 19:40:56 +08:00
pangliang 36c47f135a hard code event workflow_dispatch for now 2024-03-01 19:40:56 +08:00
pangliang a7c0016f83 fix go.sum 2024-03-01 19:40:56 +08:00
pangliang 300f068507 ParseRawOn is not required, use WorkflowDispatchConfig instead 2024-03-01 19:40:56 +08:00
pangliang 0e6759196b Checkbox has its own label 2024-03-01 19:40:56 +08:00
pangliang 1b7864d12b Missed Disabled check. 2024-03-01 19:40:56 +08:00
pangliang 5afedfd6d3 There is no need to readWorkflow again 2024-03-01 19:40:56 +08:00
pangliang f4a55d16f1 unnecessary parameters 2024-03-01 19:40:56 +08:00
pangliang 2829a8875b Form validate 2024-03-01 19:40:56 +08:00
pangliang 660cf18de0 Follow the behavior of github, only render templates, do not directly fill in env 2024-03-01 19:40:56 +08:00
pangliang 2d2f9218dc Add ref selector for run workflow from 2024-03-01 19:40:56 +08:00
pangliang d0a70d3414 Use Crowdin to translate them 2024-03-01 19:40:55 +08:00
pangliang e18bbcccd6 Use db.Find instead of writing methods for every object (#28084) 2024-03-01 19:40:55 +08:00
pangliang d973fc1765 workflow_dispatch support inputs config 2024-03-01 19:40:55 +08:00
pangliang 8eb79f3741 fix lint check, /actions/run use isAdmin permission 2024-03-01 19:40:55 +08:00
pangliang fbadf6f79e Actions support workflow dispatch event 2024-03-01 19:40:55 +08:00
14 changed files with 394 additions and 70 deletions

View File

@ -79,12 +79,6 @@ See [Workflow syntax for GitHub Actions](https://docs.github.com/en/actions/usin
Gitea Actions only supports `runs-on: xyz` or `runs-on: [xyz]` now.
### `workflow_dispatch`
See [Workflow syntax for GitHub Actions](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#onworkflow_dispatch).
It's ignored by Gitea Actions now.
### `hashFiles` expression
See [Expressions](https://docs.github.com/en/actions/learn-github-actions/expressions#hashfiles)

View File

@ -79,12 +79,6 @@ Gitea Actions 目前不支持此功能。
Gitea Actions目前只支持`runs-on: xyz`或`runs-on: [xyz]`。
### `workflow_dispatch`
请参阅[GitHub Actions的工作流语法](https://docs.github.com/zh/actions/using-workflows/workflow-syntax-for-github-actions#onworkflow_dispatch)。
Gitea Actions目前不支持此功能。
### `hashFiles`表达式
请参阅[表达式](https://docs.github.com/en/actions/learn-github-actions/expressions#hashfiles)。

View File

@ -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, "", " ")
}

View File

@ -624,6 +624,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.
@ -3651,6 +3652,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.

View File

@ -436,6 +436,7 @@ oauth_signin_submit=Vincular conta
oauth.signin.error=Ocorreu um erro durante o processamento do pedido de autorização. Se este erro persistir, contacte o administrador.
oauth.signin.error.access_denied=O pedido de autorização foi negado.
oauth.signin.error.temporarily_unavailable=A autorização falhou porque o servidor de autenticação está temporariamente indisponível. Tente mais tarde.
oauth_callback_unable_auto_reg=O registo automático está habilitado, mas o fornecedor OAuth2 %[1]s sinalizou campos em falta: %[2]s, por isso não foi possível criar uma conta automaticamente. Crie ou vincule uma conta ou contacte o administrador do sítio.
openid_connect_submit=Estabelecer ligação
openid_connect_title=Estabelecer ligação a uma conta existente
openid_connect_desc=O URI do OpenID escolhido é desconhecido. Associe-o a uma nova conta aqui.

View File

@ -7,10 +7,13 @@ 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"
@ -18,6 +21,7 @@ import (
"code.gitea.io/gitea/modules/git"
"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"
@ -58,8 +62,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
@ -132,6 +141,10 @@ func List(ctx *context.Context) {
workflow.ErrMsg = ctx.Locale.TrString("actions.runs.no_job_without_needs")
}
workflows = append(workflows, workflow)
if workflow.Entry.Name() == workflowID {
curWorkflow = wf
}
}
}
ctx.Data["workflows"] = workflows
@ -142,17 +155,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 := curWorkflow.WorkflowDispatchConfig()
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")
@ -169,7 +211,7 @@ func List(ctx *context.Context) {
PageSize: convert.ToCorrectPageSize(ctx.FormInt("limit")),
},
RepoID: ctx.Repo.Repository.ID,
WorkflowID: workflow,
WorkflowID: workflowID,
TriggerUserID: actorID,
}
@ -206,7 +248,7 @@ 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

View File

@ -18,18 +18,26 @@ import (
actions_model "code.gitea.io/gitea/models/actions"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
access_model "code.gitea.io/gitea/models/perm/access"
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/git"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/storage"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/modules/web"
actions_service "code.gitea.io/gitea/services/actions"
context_module "code.gitea.io/gitea/services/context"
"code.gitea.io/gitea/services/convert"
"github.com/nektos/act/pkg/jobparser"
"github.com/nektos/act/pkg/model"
"xorm.io/builder"
)
@ -715,3 +723,164 @@ func disableOrEnableWorkflowFile(ctx *context_module.Context, isEnable bool) {
url.QueryEscape(ctx.FormString("actor")), url.QueryEscape(ctx.FormString("status")))
ctx.JSONRedirect(redirectURL)
}
func Run(ctx *context_module.Context) {
redirectURL := fmt.Sprintf("%s/actions?workflow=%s&actor=%s&status=%s", ctx.Repo.RepoLink, url.QueryEscape(ctx.FormString("workflow")),
url.QueryEscape(ctx.FormString("actor")), url.QueryEscape(ctx.FormString("status")))
workflowID := ctx.FormString("workflow")
if len(workflowID) == 0 {
ctx.ServerError("workflow", nil)
return
}
ref := ctx.FormString("ref")
if len(ref) == 0 {
ctx.ServerError("ref", nil)
return
}
// can not rerun job when workflow is disabled
cfgUnit := ctx.Repo.Repository.MustGetUnit(ctx, unit.TypeActions)
cfg := cfgUnit.ActionsConfig()
if cfg.IsWorkflowDisabled(workflowID) {
ctx.Flash.Error(ctx.Tr("actions.workflow.disabled"))
ctx.Redirect(redirectURL)
return
}
// get target commit of run from specified ref
refName := git.RefName(ref)
var runTargetCommit *git.Commit
var err error
if refName.IsTag() {
runTargetCommit, err = ctx.Repo.GitRepo.GetTagCommit(refName.TagName())
} else if refName.IsBranch() {
runTargetCommit, err = ctx.Repo.GitRepo.GetBranchCommit(refName.BranchName())
} else {
ctx.Flash.Error(ctx.Tr("form.git_ref_name_error", ref))
ctx.Redirect(redirectURL)
return
}
if err != nil {
ctx.Flash.Error(ctx.Tr("form.target_ref_not_exist", ref))
ctx.Redirect(redirectURL)
return
}
// get workflow entry from default branch commit
defaultBranchCommit, err := ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch)
if err != nil {
ctx.Error(http.StatusInternalServerError, err.Error())
return
}
entries, err := actions.ListWorkflows(defaultBranchCommit)
if err != nil {
ctx.Error(http.StatusInternalServerError, err.Error())
return
}
// find workflow from commit
var workflows []*jobparser.SingleWorkflow
for _, entry := range entries {
if entry.Name() == workflowID {
content, err := actions.GetContentFromEntry(entry)
if err != nil {
ctx.Error(http.StatusInternalServerError, err.Error())
return
}
workflows, err = jobparser.Parse(content)
if err != nil {
ctx.ServerError("workflow", err)
return
}
break
}
}
if len(workflows) == 0 {
ctx.Flash.Error(ctx.Tr("actions.workflow.not_found", workflowID))
ctx.Redirect(redirectURL)
return
}
// get inputs from post
workflow := &model.Workflow{
RawOn: workflows[0].RawOn,
}
inputs := make(map[string]any)
if workflowDispatch := workflow.WorkflowDispatchConfig(); workflowDispatch != nil {
for name, config := range workflowDispatch.Inputs {
value := ctx.Req.PostForm.Get(name)
if config.Type == "boolean" {
// https://www.w3.org/TR/html401/interact/forms.html
// https://stackoverflow.com/questions/11424037/do-checkbox-inputs-only-post-data-if-theyre-checked
// Checkboxes (and radio buttons) are on/off switches that may be toggled by the user.
// A switch is "on" when the control element's checked attribute is set.
// When a form is submitted, only "on" checkbox controls can become successful.
inputs[name] = strconv.FormatBool(value == "on")
} else if value != "" {
inputs[name] = value
} else {
inputs[name] = config.Default
}
}
}
// ctx.Req.PostForm -> WorkflowDispatchPayload.Inputs -> ActionRun.EventPayload -> runner: ghc.Event
// https://docs.github.com/en/actions/learn-github-actions/contexts#github-context
// https://docs.github.com/en/webhooks/webhook-events-and-payloads#workflow_dispatch
workflowDispatchPayload := &api.WorkflowDispatchPayload{
Workflow: workflowID,
Ref: ref,
Repository: convert.ToRepo(ctx, ctx.Repo.Repository, access_model.Permission{AccessMode: perm.AccessModeNone}),
Inputs: inputs,
Sender: convert.ToUserWithAccessMode(ctx, ctx.Doer, perm.AccessModeNone),
}
var eventPayload []byte
if eventPayload, err = workflowDispatchPayload.JSONPayload(); err != nil {
ctx.ServerError("JSONPayload", err)
return
}
run := &actions_model.ActionRun{
Title: strings.SplitN(runTargetCommit.CommitMessage, "\n", 2)[0],
RepoID: ctx.Repo.Repository.ID,
OwnerID: ctx.Repo.Repository.OwnerID,
WorkflowID: workflowID,
TriggerUserID: ctx.Doer.ID,
Ref: ref,
CommitSHA: runTargetCommit.ID.String(),
IsForkPullRequest: false,
Event: "workflow_dispatch",
TriggerEvent: "workflow_dispatch",
EventPayload: string(eventPayload),
Status: actions_model.StatusWaiting,
}
// cancel running jobs of the same workflow
if err := actions_model.CancelPreviousJobs(
ctx,
run.RepoID,
run.Ref,
run.WorkflowID,
run.Event,
); err != nil {
log.Error("CancelRunningJobs: %v", err)
}
// Insert the action run and its associated jobs into the database
if err := actions_model.InsertRun(ctx, run, workflows); err != nil {
ctx.ServerError("workflow", err)
return
}
alljobs, err := db.Find[actions_model.ActionRunJob](ctx, actions_model.FindRunJobOptions{RunID: run.ID})
if err != nil {
log.Error("FindRunJobs: %v", err)
}
actions_service.CreateCommitStatus(ctx, alljobs...)
ctx.Flash.Success(ctx.Tr("actions.workflow.run_success", workflowID))
ctx.Redirect(redirectURL)
}

View File

@ -1375,6 +1375,7 @@ func registerRoutes(m *web.Route) {
m.Get("", actions.List)
m.Post("/disable", reqRepoAdmin, actions.DisableWorkflowFile)
m.Post("/enable", reqRepoAdmin, actions.EnableWorkflowFile)
m.Post("/run", reqRepoAdmin, actions.Run)
m.Group("/runs/{run}", func() {
m.Combo("").

View File

@ -76,6 +76,11 @@
</button>
{{end}}
</div>
{{if .WorkflowDispatchConfig}}
{{template "repo/actions/workflow_dispatch" .}}
{{end}}
{{template "repo/actions/runs_list" .}}
</div>
</div>

View File

@ -0,0 +1,85 @@
<div class="ui blue info message tw-flex tw-justify-between tw-items-center">
<span class="ui text middle">{{ctx.Locale.Tr "actions.workflow.has_workflow_dispatch"}}</span>
<button class="ui mini button show-modal" data-modal="#runWorkflowDispatchModal">{{ctx.Locale.Tr "actions.workflow.run"}}{{svg "octicon-triangle-down" 14 "dropdown icon"}}</button>
</div>
<div id="runWorkflowDispatchModal" class="ui mini modal">
<div class="content">
<form id="runWorkflowDispatchForm" class="ui form" action="{{$.Link}}/run?workflow={{$.CurWorkflow}}&actor={{$.CurActor}}&status={{.Status}}" method="post">
{{.CsrfTokenHtml}}
<div class="ui field required">
<label>{{ctx.Locale.Tr "actions.workflow.from_ref"}}:</label>
<div class="ui filter dropdown button select-branch">
<input type="hidden" name="ref" value="refs/heads/{{index .Branches 0}}">
{{svg "octicon-git-branch"}}
<span class="text branch-name gt-ellipsis">{{index .Branches 0}}</span>
<div class="menu">
<div class="ui icon search input tw-w-auto">
<i class="search icon">{{svg "octicon-search" 16 "search icon"}}</i>
<input type="text" placeholder="{{ctx.Locale.Tr "repo.filter_branch_and_tag"}}">
</div>
<div class="header">
<div class="ui grid">
<div class="two column row">
<a class="reference column muted" href="#" data-target="#branch-list">
<span class="text black">
{{svg "octicon-git-branch" 16 "tw-mr-1"}}{{ctx.Locale.Tr "repo.branches"}}
</span>
</a>
<a class="reference column muted" href="#" data-target="#tag-list">
<span class="text">
{{svg "octicon-tag" 16 "tw-mr-1"}}{{ctx.Locale.Tr "repo.tags"}}
</span>
</a>
</div>
</div>
</div>
<div class="branch-tag-divider"></div>
<div id="branch-list" class="scrolling menu reference-list-menu">
{{range .Branches}}
<div class="item" data-value="refs/heads/{{.}}" title="{{.}}">{{.}}</div>
{{else}}
<div class="item">{{ctx.Locale.Tr "no_results_found"}}</div>
{{end}}
</div>
<div id="tag-list" class="scrolling menu reference-list-menu tw-hidden">
{{range .Tags}}
<div class="item" data-value="refs/tags/{{.}}" title="{{.}}">{{.}}</div>
{{else}}
<div class="item">{{ctx.Locale.Tr "no_results_found"}}</div>
{{end}}
</div>
</div>
</div>
</div>
{{range $key, $item := .WorkflowDispatchConfig.Inputs}}
<div class="ui field {{if .Required}}required{{end}}">
{{if eq .Type "choice"}}
<label>{{$key}}:</label>
<select class="ui fluid dropdown" name="{{$key}}">
{{range .Options}}
<option value="{{.}}" {{if eq $item.Default .}}selected{{end}} >{{.}}</option>
{{end}}
</select>
<span class="help">{{.Description}}</span>
{{else if eq .Type "boolean"}}
<div class="ui inline toggle checkbox">
<label>{{$key}}</label>
<input type="checkbox" name="{{$key}}" {{if eq .Default "true"}}checked{{end}}>
<span class="help">{{.Description}}</span>
</div>
{{else if eq .Type "number"}}
<label>{{$key}}:</label>
<input name="{{$key}}" value="{{.Default}}" {{if .Required}}required{{end}}>
<span class="help">{{.Description}}</span>
{{else}}
<label>{{$key}}:</label>
<input name="{{$key}}" value="{{.Default}}" {{if .Required}}required{{end}}>
<span class="help">{{.Description}}</span>
{{end}}
</div>
{{end}}
<button class="ui tiny primary button" type="submit">Submit</button>
</form>
</div>
</div>

View File

@ -5,15 +5,15 @@
{{$.CsrfTokenHtml}}
</form>
{{/* TODO: share this branch selector dropdown with the same in repo page */}}
<div class="ui {{if not .HasIssuesOrPullsWritePermission}}disabled{{end}} floating filter select-branch dropdown tw-max-w-full" data-no-results="{{ctx.Locale.Tr "no_results_found"}}">
<div class="ui {{if not .HasIssuesOrPullsWritePermission}}disabled{{end}} floating filter select-branch issue-select-branch dropdown tw-max-w-full" data-no-results="{{ctx.Locale.Tr "no_results_found"}}">
<div class="ui basic small button">
<span class="text branch-name gt-ellipsis">{{if .Reference}}{{$.RefEndName}}{{else}}{{ctx.Locale.Tr "repo.issues.no_ref"}}{{end}}</span>
{{if .HasIssuesOrPullsWritePermission}}{{svg "octicon-triangle-down" 14 "dropdown icon"}}{{end}}
</div>
<div class="menu">
<div class="ui icon search input">
<i class="icon">{{svg "octicon-filter" 16}}</i>
<input name="search" placeholder="{{ctx.Locale.Tr "repo.filter_branch_and_tag"}}...">
<i class="search icon">{{svg "octicon-search" 16 "search icon"}}</i>
<input type="text" placeholder="{{ctx.Locale.Tr "repo.filter_branch_and_tag"}}">
</div>
<div class="header">
<div class="ui grid">

View File

@ -2824,14 +2824,14 @@ tbody.commit-list {
}
/* Branch tag selector - TODO: Merge this into the same selector on repo page */
.repository .issue-content .issue-content-right .ui.grid .column.row {
.select-branch .ui.grid .column.row {
padding: 10px;
padding-bottom: 0;
}
.repository .issue-content .issue-content-right .ui.grid .column.muted {
.select-branch .ui.grid .column.muted {
padding: 0;
}
.repository .issue-content .issue-content-right .ui.grid .column.muted .text {
.select-branch .ui.grid .column.muted .text {
display: inline-block;
padding: 10px;
width: 100%;
@ -2839,16 +2839,16 @@ tbody.commit-list {
border: 1px solid transparent;
border-bottom: none;
}
.repository .issue-content .issue-content-right .ui.grid .column.muted .text.black {
.select-branch .ui.grid .column.muted .text.black {
border-color: var(--color-secondary);
background: var(--color-menu);
border-top-left-radius: var(--border-radius);
border-top-right-radius: var(--border-radius);
}
.repository .issue-content .issue-content-right .ui.dropdown .scrolling.menu {
border-top: none;
.select-branch .scrolling.menu {
border-top: none !important;
}
.repository .issue-content .issue-content-right .branch-tag-divider {
.select-branch .branch-tag-divider {
margin-top: -1px;
border-top: 1px solid var(--color-secondary);
}

View File

@ -43,6 +43,50 @@ function reloadConfirmDraftComment() {
window.location.reload();
}
// code specific to the issue branch selector
export function initBranchSelectorIssue() {
const $selectBranch = $('.ui.issue-select-branch');
if (!$selectBranch.length) return;
const $branchMenu = $selectBranch.find('.reference-list-menu');
const $isNewIssue = $branchMenu.hasClass('new-issue');
$branchMenu.find('.item:not(.no-select)').on('click', async function () {
const selectedValue = $(this).data('id');
const editMode = $('#editing_mode').val();
$($(this).data('id-selector')).val(selectedValue);
if ($isNewIssue) {
$selectBranch.find('.ui .branch-name').text($(this).data('name'));
return;
}
if (editMode === 'true') {
const form = document.getElementById('update_issueref_form');
const params = new URLSearchParams();
params.append('ref', selectedValue);
try {
await POST(form.getAttribute('action'), {data: params});
window.location.reload();
} catch (error) {
console.error(error);
}
} else if (editMode === '') {
$selectBranch.find('.ui .branch-name').text(selectedValue);
}
});
}
// code for all branch selectors
export function initBranchSelectorTabs() {
const $selectBranch = $('.ui.select-branch');
if (!$selectBranch.length) return;
$selectBranch.find('.reference.column').on('click', function () {
hideElem($selectBranch.find('.scrolling.reference-list-menu'));
$selectBranch.find('.reference .text').removeClass('black');
showElem($($(this).data('target')));
$(this).find('.text').addClass('black');
return false;
});
}
export function initRepoCommentForm() {
const $commentForm = $('.comment.form');
if (!$commentForm.length) return;
@ -55,44 +99,6 @@ export function initRepoCommentForm() {
initSingleCommentEditor($commentForm);
}
function initBranchSelector() {
const $selectBranch = $('.ui.select-branch');
const $branchMenu = $selectBranch.find('.reference-list-menu');
const $isNewIssue = $branchMenu.hasClass('new-issue');
$branchMenu.find('.item:not(.no-select)').on('click', async function () {
const selectedValue = $(this).data('id');
const editMode = $('#editing_mode').val();
$($(this).data('id-selector')).val(selectedValue);
if ($isNewIssue) {
$selectBranch.find('.ui .branch-name').text($(this).data('name'));
return;
}
if (editMode === 'true') {
const form = document.getElementById('update_issueref_form');
const params = new URLSearchParams();
params.append('ref', selectedValue);
try {
await POST(form.getAttribute('action'), {data: params});
window.location.reload();
} catch (error) {
console.error(error);
}
} else if (editMode === '') {
$selectBranch.find('.ui .branch-name').text(selectedValue);
}
});
$selectBranch.find('.reference.column').on('click', function () {
hideElem($selectBranch.find('.scrolling.reference-list-menu'));
$selectBranch.find('.reference .text').removeClass('black');
showElem($($(this).data('target')));
$(this).find('.text').addClass('black');
return false;
});
}
initBranchSelector();
// List submits
function initListSubmits(selector, outerSelector) {
const $list = $(`.ui.${outerSelector}.list`);

View File

@ -71,7 +71,12 @@ import {initCompWebHookEditor} from './features/comp/WebHookEditor.js';
import {initRepoBranchButton} from './features/repo-branch.js';
import {initCommonOrganization} from './features/common-organization.js';
import {initRepoWikiForm} from './features/repo-wiki.js';
import {initRepoCommentForm, initRepository} from './features/repo-legacy.js';
import {
initRepoCommentForm,
initRepository,
initBranchSelectorIssue,
initBranchSelectorTabs,
} from './features/repo-legacy.js';
import {initCopyContent} from './features/copycontent.js';
import {initCaptcha} from './features/captcha.js';
import {initRepositoryActionView} from './components/RepoActionView.vue';
@ -146,6 +151,8 @@ onDomReady(() => {
initRepoBranchButton();
initRepoCodeView();
initRepoCommentForm();
initBranchSelectorIssue();
initBranchSelectorTabs();
initRepoEllipsisButton();
initRepoDiffCommitBranchesAndTags();
initRepoEditor();