Files
gitea/services/projects/project.go
Oleks 1011241a67 feat(api): add REST API for repository project boards
Cherry-pick of upstream PR go-gitea/gitea#37518 onto feat/projects-api.
The PR is itself a rebase of #36831 onto main, adapted for the
multi-projects-per-issue model added in #36784.

Endpoints (all under /repos/{owner}/{repo}/projects...):
  GET    .                                 list projects
  POST   .                                 create project
  GET    /{id}                              get project
  PATCH  /{id}                              update project
  DELETE /{id}                              delete project
  GET    /{id}/columns                      list columns
  POST   /{id}/columns                      create column
  PATCH  /columns/{id}                      update column
  DELETE /columns/{id}                      delete column
  GET    /columns/{id}/issues               list issues in column
  POST   /columns/{id}/issues/{issue_id}    add/move issue to column
  DELETE /columns/{id}/issues/{issue_id}    remove issue from column
  POST   /columns/{id}/issues/{issue_id}/move  move between columns

Source: https://github.com/go-gitea/gitea/pull/37518
2026-05-13 10:59:58 +03:00

45 lines
1.3 KiB
Go

// Copyright 2026 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package project
import (
"context"
"code.gitea.io/gitea/models/db"
project_model "code.gitea.io/gitea/models/project"
"code.gitea.io/gitea/modules/optional"
)
// UpdateProjectOptions represents updatable project fields. Fields with no value are left unchanged.
type UpdateProjectOptions struct {
Title optional.Option[string]
Description optional.Option[string]
CardType optional.Option[project_model.CardType]
IsClosed optional.Option[bool]
}
// UpdateProject applies the provided options to the project atomically.
func UpdateProject(ctx context.Context, project *project_model.Project, opts UpdateProjectOptions) error {
return db.WithTx(ctx, func(ctx context.Context) error {
if opts.Title.Has() {
project.Title = opts.Title.Value()
}
if opts.Description.Has() {
project.Description = opts.Description.Value()
}
if opts.CardType.Has() {
project.CardType = opts.CardType.Value()
}
if err := project_model.UpdateProject(ctx, project); err != nil {
return err
}
if opts.IsClosed.Has() && opts.IsClosed.Value() != project.IsClosed {
if err := project_model.ChangeProjectStatus(ctx, project, opts.IsClosed.Value()); err != nil {
return err
}
}
return nil
})
}