0
0
mirror of https://github.com/go-gitea/gitea.git synced 2026-05-06 21:28:23 +02:00

improvements

This commit is contained in:
Lunny Xiao 2025-10-25 16:46:18 -07:00
parent ae282397be
commit 37196261a6
No known key found for this signature in database
GPG Key ID: C3B7C91B632F738A
5 changed files with 133 additions and 111 deletions

View File

@ -71,7 +71,7 @@ const (
ProjectWorkflowsUserEmail = "workflows@gitea.io"
)
func IsGiteaWorkflowsUserName(name string) bool {
func IsProjectWorkflowsUserName(name string) bool {
return strings.EqualFold(name, ProjectWorkflowsUserName)
}
@ -103,7 +103,7 @@ func GetSystemUserByName(name string) *User {
if IsGiteaActionsUserName(name) {
return NewActionsUser()
}
if IsGiteaWorkflowsUserName(name) {
if IsProjectWorkflowsUserName(name) {
return NewProjectWorkflowsUser()
}
return nil

View File

@ -25,6 +25,13 @@ func TestSystemUser(t *testing.T) {
assert.True(t, u.IsGiteaActions())
assert.True(t, IsGiteaActionsUserName("Gitea-actionS"))
_, err = GetPossibleUserByID(t.Context(), -3)
u, err = GetPossibleUserByID(t.Context(), -3)
require.NoError(t, err)
assert.Equal(t, "project-workflows", u.Name)
assert.Equal(t, "project-workflows", u.LowerName)
assert.True(t, u.IsProjectWorkflows())
assert.True(t, IsProjectWorkflowsUserName("Project-Workflows"))
_, err = GetPossibleUserByID(t.Context(), -4)
require.Error(t, err)
}

View File

@ -4,7 +4,6 @@
package projects
import (
stdCtx "context"
"io"
"net/http"
"strconv"
@ -17,6 +16,7 @@ import (
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/templates"
"code.gitea.io/gitea/services/context"
project_service "code.gitea.io/gitea/services/projects"
)
var (
@ -24,85 +24,6 @@ var (
tmplOrgWorkflows = templates.TplName("org/projects/workflows")
)
// getFilterSummary returns a human-readable summary of the filters
func getFilterSummary(ctx stdCtx.Context, filters []project_model.WorkflowFilter) string {
if len(filters) == 0 {
return ""
}
var summary strings.Builder
labelIDs := make([]int64, 0)
for _, filter := range filters {
switch filter.Type {
case project_model.WorkflowFilterTypeIssueType:
switch filter.Value {
case "issue":
if summary.Len() > 0 {
summary.WriteString(" ")
}
summary.WriteString("(Issues only)")
case "pull_request":
if summary.Len() > 0 {
summary.WriteString(" ")
}
summary.WriteString("(Pull requests only)")
}
case project_model.WorkflowFilterTypeSourceColumn:
columnID, _ := strconv.ParseInt(filter.Value, 10, 64)
if columnID <= 0 {
continue
}
col, err := project_model.GetColumn(ctx, columnID)
if err != nil {
log.Error("GetColumn: %v", err)
continue
}
if summary.Len() > 0 {
summary.WriteString(" ")
}
summary.WriteString("(Source: " + col.Title + ")")
case project_model.WorkflowFilterTypeTargetColumn:
columnID, _ := strconv.ParseInt(filter.Value, 10, 64)
if columnID <= 0 {
continue
}
col, err := project_model.GetColumn(ctx, columnID)
if err != nil {
log.Error("GetColumn: %v", err)
continue
}
if summary.Len() > 0 {
summary.WriteString(" ")
}
summary.WriteString("(Target: " + col.Title + ")")
case project_model.WorkflowFilterTypeLabels:
labelID, _ := strconv.ParseInt(filter.Value, 10, 64)
if labelID > 0 {
labelIDs = append(labelIDs, labelID)
}
}
}
if len(labelIDs) > 0 {
labels, err := issues_model.GetLabelsByIDs(ctx, labelIDs)
if err != nil {
log.Error("GetLabelsByIDs: %v", err)
} else {
if summary.Len() > 0 {
summary.WriteString(" ")
}
summary.WriteString("(Labels: ")
for i, label := range labels {
summary.WriteString(label.Name)
if i < len(labels)-1 {
summary.WriteString(", ")
}
}
summary.WriteString(")")
}
}
return summary.String()
}
// convertFormToFilters converts form filters to WorkflowFilter objects
func convertFormToFilters(formFilters map[string]any) []project_model.WorkflowFilter {
filters := make([]project_model.WorkflowFilter, 0)
@ -111,7 +32,7 @@ func convertFormToFilters(formFilters map[string]any) []project_model.WorkflowFi
switch key {
case "labels":
// Handle labels array
if labelInterfaces, ok := value.([]interface{}); ok && len(labelInterfaces) > 0 {
if labelInterfaces, ok := value.([]any); ok && len(labelInterfaces) > 0 {
for _, labelInterface := range labelInterfaces {
if label, ok := labelInterface.(string); ok && label != "" {
filters = append(filters, project_model.WorkflowFilter{
@ -152,7 +73,7 @@ func convertFormToActions(formActions map[string]any) []project_model.WorkflowAc
}
}
case "add_labels":
// Handle both []string and []interface{} from JSON unmarshaling
// Handle both []string and []any from JSON unmarshaling
if labels, ok := value.([]string); ok && len(labels) > 0 {
for _, label := range labels {
if label != "" {
@ -162,7 +83,7 @@ func convertFormToActions(formActions map[string]any) []project_model.WorkflowAc
})
}
}
} else if labelInterfaces, ok := value.([]interface{}); ok && len(labelInterfaces) > 0 {
} else if labelInterfaces, ok := value.([]any); ok && len(labelInterfaces) > 0 {
for _, labelInterface := range labelInterfaces {
if label, ok := labelInterface.(string); ok && label != "" {
actions = append(actions, project_model.WorkflowAction{
@ -173,7 +94,7 @@ func convertFormToActions(formActions map[string]any) []project_model.WorkflowAc
}
}
case "remove_labels":
// Handle both []string and []interface{} from JSON unmarshaling
// Handle both []string and []any from JSON unmarshaling
if labels, ok := value.([]string); ok && len(labels) > 0 {
for _, label := range labels {
if label != "" {
@ -183,7 +104,7 @@ func convertFormToActions(formActions map[string]any) []project_model.WorkflowAc
})
}
}
} else if labelInterfaces, ok := value.([]interface{}); ok && len(labelInterfaces) > 0 {
} else if labelInterfaces, ok := value.([]any); ok && len(labelInterfaces) > 0 {
for _, labelInterface := range labelInterfaces {
if label, ok := labelInterface.(string); ok && label != "" {
actions = append(actions, project_model.WorkflowAction{
@ -243,7 +164,7 @@ func WorkflowsEvents(ctx *context.Context) {
Capabilities project_model.WorkflowEventCapabilities `json:"capabilities"`
Filters []project_model.WorkflowFilter `json:"filters"`
Actions []project_model.WorkflowAction `json:"actions"`
FilterSummary string `json:"filter_summary"` // Human readable filter description
Summary string `json:"summary"` // Human readable filter description
Enabled bool `json:"enabled"`
IsConfigured bool `json:"isConfigured"` // Whether this workflow is configured/saved
}
@ -263,7 +184,7 @@ func WorkflowsEvents(ctx *context.Context) {
if len(existingWorkflows) > 0 {
// Add all existing workflows for this event
for _, wf := range existingWorkflows {
filterSummary := getFilterSummary(ctx, wf.WorkflowFilters)
workflowSummary := project_service.GetWorkflowSummary(ctx, wf)
outputWorkflows = append(outputWorkflows, &WorkflowConfig{
ID: wf.ID,
EventID: strconv.FormatInt(wf.ID, 10),
@ -272,7 +193,7 @@ func WorkflowsEvents(ctx *context.Context) {
Capabilities: capabilities[event],
Filters: wf.WorkflowFilters,
Actions: wf.WorkflowActions,
FilterSummary: filterSummary,
Summary: workflowSummary,
Enabled: wf.Enabled,
IsConfigured: true,
})
@ -285,7 +206,7 @@ func WorkflowsEvents(ctx *context.Context) {
DisplayName: string(ctx.Tr(event.LangKey())),
WorkflowEvent: string(event),
Capabilities: capabilities[event],
FilterSummary: "",
Summary: "",
Enabled: true, // Default to enabled for new workflows
IsConfigured: false,
})
@ -537,17 +458,17 @@ func WorkflowsPost(ctx *context.Context) {
}
// Return the newly created workflow with filter summary
filterSummary := getFilterSummary(ctx, wf.WorkflowFilters)
workflowSummary := project_service.GetWorkflowSummary(ctx, wf)
ctx.JSON(http.StatusOK, map[string]any{
"success": true,
"workflow": map[string]any{
"id": wf.ID,
"event_id": strconv.FormatInt(wf.ID, 10),
"display_name": string(ctx.Tr(wf.WorkflowEvent.LangKey())),
"filters": wf.WorkflowFilters,
"actions": wf.WorkflowActions,
"filter_summary": filterSummary,
"enabled": wf.Enabled,
"id": wf.ID,
"event_id": strconv.FormatInt(wf.ID, 10),
"display_name": string(ctx.Tr(wf.WorkflowEvent.LangKey())),
"filters": wf.WorkflowFilters,
"actions": wf.WorkflowActions,
"summary": workflowSummary,
"enabled": wf.Enabled,
},
})
} else {
@ -570,17 +491,17 @@ func WorkflowsPost(ctx *context.Context) {
}
// Return the updated workflow with filter summary
filterSummary := getFilterSummary(ctx, wf.WorkflowFilters)
workflowSummary := project_service.GetWorkflowSummary(ctx, wf)
ctx.JSON(http.StatusOK, map[string]any{
"success": true,
"workflow": map[string]any{
"id": wf.ID,
"event_id": strconv.FormatInt(wf.ID, 10),
"display_name": string(ctx.Tr(wf.WorkflowEvent.LangKey())) + filterSummary,
"filters": wf.WorkflowFilters,
"actions": wf.WorkflowActions,
"filter_summary": filterSummary,
"enabled": wf.Enabled,
"id": wf.ID,
"event_id": strconv.FormatInt(wf.ID, 10),
"display_name": string(ctx.Tr(wf.WorkflowEvent.LangKey())),
"filters": wf.WorkflowFilters,
"actions": wf.WorkflowActions,
"summary": workflowSummary,
"enabled": wf.Enabled,
},
})
}

View File

@ -0,0 +1,94 @@
// Copyright 2025 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package projects
import (
"context"
"strconv"
"strings"
issues_model "code.gitea.io/gitea/models/issues"
project_model "code.gitea.io/gitea/models/project"
"code.gitea.io/gitea/modules/log"
)
// GetWorkflowSummary returns a human-readable summary of the workflow
func GetWorkflowSummary(ctx context.Context, wf *project_model.Workflow) string {
filters := wf.WorkflowFilters
if len(filters) == 0 {
return ""
}
var summary strings.Builder
labelIDs := make([]int64, 0)
for _, filter := range filters {
switch filter.Type {
case project_model.WorkflowFilterTypeIssueType:
switch filter.Value {
case "issue":
if summary.Len() > 0 {
summary.WriteString(" ")
}
summary.WriteString("(Issues only)")
case "pull_request":
if summary.Len() > 0 {
summary.WriteString(" ")
}
summary.WriteString("(Pull requests only)")
}
case project_model.WorkflowFilterTypeSourceColumn:
columnID, _ := strconv.ParseInt(filter.Value, 10, 64)
if columnID <= 0 {
continue
}
col, err := project_model.GetColumn(ctx, columnID)
if err != nil {
log.Error("GetColumn: %v", err)
continue
}
if summary.Len() > 0 {
summary.WriteString(" ")
}
summary.WriteString("(Source: " + col.Title + ")")
case project_model.WorkflowFilterTypeTargetColumn:
columnID, _ := strconv.ParseInt(filter.Value, 10, 64)
if columnID <= 0 {
continue
}
col, err := project_model.GetColumn(ctx, columnID)
if err != nil {
log.Error("GetColumn: %v", err)
continue
}
if summary.Len() > 0 {
summary.WriteString(" ")
}
summary.WriteString("(Target: " + col.Title + ")")
case project_model.WorkflowFilterTypeLabels:
labelID, _ := strconv.ParseInt(filter.Value, 10, 64)
if labelID > 0 {
labelIDs = append(labelIDs, labelID)
}
}
}
if len(labelIDs) > 0 {
labels, err := issues_model.GetLabelsByIDs(ctx, labelIDs)
if err != nil {
log.Error("GetLabelsByIDs: %v", err)
} else {
if summary.Len() > 0 {
summary.WriteString(" ")
}
summary.WriteString("(Labels: ")
for i, label := range labels {
summary.WriteString(label.Name)
if i < len(labels)-1 {
summary.WriteString(", ")
}
}
summary.WriteString(")")
}
}
return summary.String()
}

View File

@ -351,7 +351,7 @@ const createNewWorkflow = (eventType: any, capabilities: any, displayName: any)
capabilities,
filters: [] as any[],
actions: [] as any[],
filter_summary: '',
summary: '',
workflow_event: eventType,
enabled: true, // Ensure new workflows are enabled by default
};
@ -683,8 +683,8 @@ onUnmounted(() => {
<div class="workflow-title">
{{ getWorkflowDisplayName(item, index) }}
</div>
<div v-if="item.filter_summary" class="workflow-subtitle">
{{ item.filter_summary }}
<div v-if="item.summary" class="workflow-subtitle">
{{ item.summary }}
</div>
</div>
</div>