Compare commits

...

11 Commits

Author SHA1 Message Date
gitea-actions[bot] f329466d1c chore(release): build 06.15.00 [skip ci] 2026-06-12 03:21:49 +00:00
jmiller 05a89339e1 Merge pull request 'chore: update changelog with 06.15.00 features' (#614) from fix/changelog-update into main
Generic: Project CI / Tests (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Generic: Repo Health / Access control (push) Successful in 2s
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Project CI / Lint & Validate (push) Successful in 41s
Deploy MokoGitea / deploy (push) Failing after 6m22s
2026-06-12 03:19:12 +00:00
Jonathan Miller 75e640dd17 chore: update changelog with 06.15.00 features (#597, #598)
Generic: Project CI / Tests (pull_request) Blocked by required conditions
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Universal: PR Check / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (pull_request) Blocked by required conditions
Branch Policy Check / Verify merge target (pull_request) Failing after 2s
Universal: PR Check / Branch Policy (pull_request) Failing after 3s
Generic: Repo Health / Access control (pull_request) Successful in 3s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Universal: PR Check / Validate PR (pull_request) Failing after 18s
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Failing after 3s
Generic: Repo Health / Access control (push) Successful in 3s
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Generic: Project CI / Lint & Validate (pull_request) Successful in 1m1s
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
PR RC Release / Build RC Release (pull_request) Failing after 1m30s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 1m41s
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 4m54s
Universal: Auto Version Bump / Version Bump (push) Successful in 13s
2026-06-11 22:18:44 -05:00
gitea-actions[bot] 09f17439ec chore(release): build 06.15.00 [skip ci] 2026-06-12 03:00:57 +00:00
jmiller 9d45a767e7 Merge pull request 'feat(issues): make status_id, priority_id, type_id required on create (#598)' (#613) from feature/598-required-issue-metadata into main 2026-06-12 02:59:37 +00:00
jmiller ece24c6d38 Merge pull request 'feat(custom-fields): add required flag UI and API validation (#597)' (#612) from feature/597-required-custom-fields into main
Generic: Project CI / Tests (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
Generic: Project CI / Lint & Validate (push) Successful in 47s
Deploy MokoGitea / deploy (push) Failing after 6m52s
2026-06-12 02:59:10 +00:00
Jonathan Miller e0d4f5fd15 fix: handle SetIssueStatusID/PriorityID/TypeID errors on create
Universal: Auto Version Bump / Version Bump (push) Successful in 9s
Generic: Project CI / Tests (pull_request) Blocked by required conditions
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Universal: PR Check / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (pull_request) Blocked by required conditions
Branch Policy Check / Verify merge target (pull_request) Failing after 2s
Universal: PR Check / Branch Policy (pull_request) Failing after 2s
Generic: Repo Health / Access control (pull_request) Successful in 3s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Universal: PR Check / Validate PR (pull_request) Failing after 13s
Generic: Project CI / Lint & Validate (pull_request) Successful in 50s
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Successful in 3s
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 1m36s
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 4m36s
Explicit caller-provided values now return 500 on failure instead of
silently discarding the error. Default auto-assignment still uses
best-effort (log and continue) since it's a fallback.
2026-06-11 21:57:39 -05:00
Jonathan Miller c67e7373fb fix: move required custom field validation before issue creation
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
Universal: Auto Version Bump / Version Bump (push) Successful in 10s
Generic: Project CI / Tests (pull_request) Blocked by required conditions
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Universal: PR Check / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (pull_request) Blocked by required conditions
Branch Policy Check / Verify merge target (pull_request) Failing after 2s
Universal: PR Check / Branch Policy (pull_request) Failing after 3s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (pull_request) Successful in 2s
Universal: PR Check / Validate PR (pull_request) Failing after 11s
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Failing after 2s
Generic: Project CI / Lint & Validate (pull_request) Successful in 51s
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 1m22s
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 4m19s
Validation now runs before NewIssue() to prevent orphaned issues
when a required field is missing. Reuses the defs query for both
validation and saving.
2026-06-11 21:56:14 -05:00
Jonathan Miller cbaca15cda feat(issues): make status_id, priority_id, type_id required on create (#598)
Generic: Project CI / Tests (pull_request) Blocked by required conditions
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Universal: PR Check / Report Issues (pull_request) Blocked by required conditions
Branch Policy Check / Verify merge target (pull_request) Failing after 4s
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (pull_request) Blocked by required conditions
Universal: PR Check / Branch Policy (pull_request) Failing after 6s
Universal: PR Check / Validate PR (pull_request) Failing after 19s
Generic: Project CI / Lint & Validate (pull_request) Successful in 42s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Generic: Repo Health / Access control (pull_request) Successful in 4s
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
Branch Cleanup / Delete merged branch (pull_request) Has been skipped
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Universal: Auto Version Bump / Version Bump (push) Successful in 11s
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
Universal: Build & Release / Build & Release Pipeline (pull_request) Has been skipped
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 3m21s
PR RC Release / Build RC Release (pull_request) Failing after 2m55s
- Change CreateIssueOption fields from *int64 (optional) to int64
- API auto-assigns org defaults when value is 0
- MCP gitea_issue_create now requires status_id, priority_id, type_id
  (pass 0 for org default)
- Keep optional on gitea_issue_update (partial updates)

Co-Authored-By: Moko Consulting <hello@mokoconsulting.tech>
2026-06-11 21:49:37 -05:00
Jonathan Miller 245b5a8e6a feat(custom-fields): add required flag UI and API validation (#597)
Generic: Project CI / Tests (pull_request) Blocked by required conditions
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Universal: PR Check / Report Issues (pull_request) Blocked by required conditions
Branch Policy Check / Verify merge target (pull_request) Failing after 4s
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Universal: PR Check / Branch Policy (pull_request) Failing after 4s
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Site Health (pull_request) Has been skipped
Universal: PR Check / Validate PR (pull_request) Failing after 15s
Generic: Repo Health / Access control (pull_request) Successful in 5s
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Generic: Project CI / Lint & Validate (pull_request) Successful in 1m0s
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 3s
Branch Cleanup / Delete merged branch (pull_request) Has been skipped
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
PR RC Release / Build RC Release (pull_request) Failing after 1m30s
Universal: Auto Version Bump / Version Bump (push) Successful in 11s
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
Universal: Build & Release / Build & Release Pipeline (pull_request) Has been skipped
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 2m37s
- Add required checkbox to org custom field settings form
- Show red asterisk (*) indicator on required fields in the list
- Validate required custom fields on API issue create (return 422)
- Add locale strings for required field UI

The Required column already exists in the DB (migration v343) and is
already validated in the web form. This adds the missing org settings
UI checkbox and API-side validation.

Co-Authored-By: Moko Consulting <hello@mokoconsulting.tech>
2026-06-11 21:46:24 -05:00
Jonathan Miller d61680d5b3 fix: use string client values per Joomla update spec (#611)
Generic: Project CI / Tests (push) Blocked by required conditions
Generic: Repo Health / Scripts governance (push) Blocked by required conditions
Generic: Repo Health / Repository health (push) Blocked by required conditions
Generic: Repo Health / Report Issues (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
Generic: Project CI / Lint & Validate (push) Successful in 46s
Deploy MokoGitea / deploy (push) Failing after 3m15s
2026-06-12 00:39:07 +00:00
7 changed files with 78 additions and 54 deletions
+1 -1
View File
@@ -4,7 +4,7 @@
<name>MokoGitea</name>
<org>MokoConsulting</org>
<description>Moko fork of Gitea - adding project board REST API endpoints and custom enhancements</description>
<version>06.14.00</version>
<version>06.15.00</version>
<version-prefix>v1.26.1+MOKO</version-prefix>
<license spdx="GPL-3.0-or-later">GNU General Public License v3</license>
</identity>
+1 -1
View File
@@ -5,7 +5,7 @@
# FILE INFORMATION
# DEFGROUP: Gitea.Workflow
# INGROUP: mokoplatform.Automation
# VERSION: 06.14.00
# VERSION: 06.15.00
# BRIEF: Auto-create feature branch when an issue is opened
name: "Universal: Issue Branch"
+19 -21
View File
@@ -2,7 +2,21 @@
## [Unreleased]
## [06.14.00] --- 2026-06-11
## [06.15.00] --- 2026-06-12
## [06.15.00] --- 2026-06-12
* FEATURES
* feat(custom-fields): required flag UI and API validation (#597, PR #612)
* Required checkbox in org custom field settings
* Red asterisk indicator on required fields
* API returns 422 when required custom fields are missing
* Validation runs before issue creation (no orphaned issues)
* feat(issues): make status_id, priority_id, type_id required on issue create (#598, PR #613)
* `CreateIssueOption` fields changed from optional `*int64` to `int64`
* Auto-assigns org defaults when value is 0
* MCP `gitea_issue_create` now requires these fields (pass 0 for defaults)
* Explicit metadata errors now return 500 instead of being silently discarded
## [06.14.00] --- 2026-06-11
@@ -11,14 +25,16 @@
* fix(ui): raw file button opens in new tab with rel="noopener noreferrer" (#581, PR #600)
* fix: update server feed generation bugs (#601, PR #605)
* default targetplatform changed from `(5|6)\\..*` to `6\\..*` for Joomla 6 compat
* `<client>` element changed from string to numeric `0`/`1`
* `<client>` uses string values `site`/`administrator` per Joomla update spec (#611)
* pre-release version suffix number preserved (e.g. `-rc2` not `-rc`)
* feed generator uses `FullElementName()` for auto-constructed element names
* fix: wiki API sub-page support and content response (#606, #607, PR #608)
* wiki routes use wildcard to support pages with path separators
* `ListWikiPages` returns pages in subdirectories
* error logging for empty content_base64 responses
* fix: remove `swapoff -a` from deploy workflow that caused MySQL crashes
* fix: deploy workflow clones wrong repo and runs swapoff (#609)
* removed `swapoff -a` that crashed MySQL during deploys
* fixed source repo URL from MokoGitea to MokoGitea-APP
* MCP
* metadata update tool now exposes element_name, display_name, description, license_name, language fields
@@ -43,21 +59,3 @@ All notable changes to MokoGitea are documented here. Versions follow the format
* MIGRATIONS
* migration 354: add wiki_mode and wiki_url columns to user table for org wiki settings
## [v1.26.1-moko.06.12] - 2026-06-07
* FEATURES
* feat(security): dependency vulnerability scanner - parses go.mod, package.json, composer.json, requirements.txt and checks against OSV.dev API (#551)
* feat(cdn): built-in CDN for release asset delivery via cdn.mokoconsulting.tech with per-asset public/private toggles (#561)
* feat(cdn): IP/CIDR and referrer domain allowlists for CDN abuse prevention
* feat(cdn): releases in update streams excluded from CDN (update server takes precedence)
* FIXES
* fix(licensing): hide "Require license key" option for Joomla update servers (Joomla limitation)
* fix(settings): remove duplicate description from manifest page (#559)
* INFRASTRUCTURE
* chore: rename moko-platform to MokoPlatform across codebase (#548)
* CDN CNAME: cdn.mokoconsulting.tech with auto-TLS via Let's Encrypt
* Nginx reverse proxy for CDN hostname on production server
* DreamHost MCP server path and API key configured
+4 -4
View File
@@ -114,10 +114,10 @@ type CreateIssueOption struct {
Closed bool `json:"closed"`
// custom field values keyed by field name
CustomFields map[string]string `json:"custom_fields,omitempty"`
// org-level issue metadata IDs
StatusID *int64 `json:"status_id,omitempty"`
PriorityID *int64 `json:"priority_id,omitempty"`
TypeID *int64 `json:"type_id,omitempty"`
// org-level issue metadata IDs (auto-assigned from org defaults when 0)
StatusID int64 `json:"status_id"`
PriorityID int64 `json:"priority_id"`
TypeID int64 `json:"type_id"`
}
// EditIssueOption options for editing an issue
+2
View File
@@ -2976,6 +2976,8 @@
"org.settings.custom_field_options": "Options (JSON)",
"org.settings.custom_field_options_help": "For dropdown fields, enter options as a JSON array.",
"org.settings.custom_field_description": "Description",
"org.settings.custom_field_required": "Required",
"org.settings.custom_field_required_help": "When checked, this field must be filled in when creating or editing issues.",
"org.settings.custom_field_created": "Custom field created.",
"org.settings.custom_field_updated": "Custom field updated.",
"org.settings.custom_field_deleted": "Custom field deleted.",
+43 -26
View File
@@ -722,6 +722,22 @@ func CreateIssue(ctx *context.APIContext) {
form.Labels = make([]int64, 0)
}
// Validate required custom fields BEFORE creating the issue to avoid
// leaving orphaned issues when validation fails.
customFieldDefs, defErr := issues_model.GetCustomFieldsByOwner(ctx, ctx.Repo.Repository.OwnerID, issues_model.CustomFieldScopeIssue)
if defErr != nil {
ctx.APIErrorInternal(defErr)
return
}
for _, def := range customFieldDefs {
if def.Required {
if v, ok := form.CustomFields[def.Name]; !ok || strings.TrimSpace(v) == "" {
ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("custom field %q is required", def.Name))
return
}
}
}
if err := issue_service.NewIssue(ctx, ctx.Repo.Repository, issue, form.Labels, nil, assigneeIDs, form.Projects); err != nil {
if errors.Is(err, user_model.ErrBlockedUser) {
ctx.APIError(http.StatusForbidden, err)
@@ -733,35 +749,30 @@ func CreateIssue(ctx *context.APIContext) {
return
}
// Save custom field values if provided (resolve field names to IDs).
if len(form.CustomFields) > 0 {
defs, defErr := issues_model.GetCustomFieldsByOwner(ctx, ctx.Repo.Repository.OwnerID, issues_model.CustomFieldScopeIssue)
if defErr != nil {
ctx.APIErrorInternal(defErr)
return
}
if len(defs) > 0 {
vals := make(map[int64]string)
for _, def := range defs {
if v, ok := form.CustomFields[def.Name]; ok {
vals[def.ID] = v
}
// Save custom field values (reuse defs from validation above).
if len(customFieldDefs) > 0 && len(form.CustomFields) > 0 {
vals := make(map[int64]string)
for _, def := range customFieldDefs {
if v, ok := form.CustomFields[def.Name]; ok {
vals[def.ID] = v
}
if len(vals) > 0 {
if setErr := issues_model.SetCustomFieldValues(ctx, issue.ID, vals); setErr != nil {
ctx.APIErrorInternal(setErr)
return
}
}
if len(vals) > 0 {
if setErr := issues_model.SetCustomFieldValues(ctx, issue.ID, vals); setErr != nil {
ctx.APIErrorInternal(setErr)
return
}
}
}
// Set org-level issue metadata (status/priority/type).
// If not provided, auto-assign the org default.
if form.StatusID != nil && *form.StatusID > 0 {
_ = issues_model.SetIssueStatusID(ctx, issue.ID, *form.StatusID)
// Use provided value if > 0, otherwise auto-assign org default.
if form.StatusID > 0 {
if err := issues_model.SetIssueStatusID(ctx, issue.ID, form.StatusID); err != nil {
ctx.APIErrorInternal(err)
return
}
} else {
// Auto-assign first non-closing status.
if defs, err := issues_model.GetIssueStatusDefsByOrg(ctx, ctx.Repo.Repository.OwnerID); err == nil {
for _, d := range defs {
if !d.ClosesIssue {
@@ -771,8 +782,11 @@ func CreateIssue(ctx *context.APIContext) {
}
}
}
if form.PriorityID != nil && *form.PriorityID > 0 {
_ = issues_model.SetIssuePriorityID(ctx, issue.ID, *form.PriorityID)
if form.PriorityID > 0 {
if err := issues_model.SetIssuePriorityID(ctx, issue.ID, form.PriorityID); err != nil {
ctx.APIErrorInternal(err)
return
}
} else {
if defs, err := issues_model.GetIssuePriorityDefsByOrg(ctx, ctx.Repo.Repository.OwnerID); err == nil {
for _, d := range defs {
@@ -783,8 +797,11 @@ func CreateIssue(ctx *context.APIContext) {
}
}
}
if form.TypeID != nil && *form.TypeID > 0 {
_ = issues_model.SetIssueTypeID(ctx, issue.ID, *form.TypeID)
if form.TypeID > 0 {
if err := issues_model.SetIssueTypeID(ctx, issue.ID, form.TypeID); err != nil {
ctx.APIErrorInternal(err)
return
}
} else {
if defs, err := issues_model.GetIssueTypeDefsByOrg(ctx, ctx.Repo.Repository.OwnerID); err == nil {
for _, d := range defs {
+8 -1
View File
@@ -19,7 +19,7 @@
<tbody>
{{range .CustomFields}}
<tr>
<td><strong>{{.Name}}</strong>{{if .Description}}<br><small class="text grey">{{.Description}}</small>{{end}}</td>
<td><strong>{{.Name}}</strong>{{if .Required}} <span class="tw-text-red" data-tooltip-content="Required">*</span>{{end}}{{if .Description}}<br><small class="text grey">{{.Description}}</small>{{end}}</td>
<td>{{if eq .Scope "issue"}}{{svg "octicon-issue-opened" 14}} Issue{{else}}{{svg "octicon-repo" 14}} Repo{{end}}</td>
<td><code>{{.FieldType}}</code></td>
<td>{{if .Options}}<code class="tw-text-xs">{{.Options}}</code>{{else}}<span class="text grey">-</span>{{end}}</td>
@@ -79,6 +79,13 @@
<input name="description" placeholder="Help text shown to users">
</div>
</div>
<div class="field">
<div class="ui checkbox">
<input type="checkbox" name="required">
<label>{{ctx.Locale.Tr "org.settings.custom_field_required"}}</label>
</div>
<p class="help">{{ctx.Locale.Tr "org.settings.custom_field_required_help"}}</p>
</div>
<button class="ui primary button" type="submit">{{ctx.Locale.Tr "org.settings.custom_field_add"}}</button>
</form>
</div>