This adds a complete REST API implementation for managing repository
project boards, including projects, columns, and adding issues to columns.
API Endpoints:
- GET /repos/{owner}/{repo}/projects - List projects
- POST /repos/{owner}/{repo}/projects - Create project
- GET /repos/{owner}/{repo}/projects/{id} - Get project
- PATCH /repos/{owner}/{repo}/projects/{id} - Update project
- DELETE /repos/{owner}/{repo}/projects/{id} - Delete project
- GET /repos/{owner}/{repo}/projects/{id}/columns - List columns
- POST /repos/{owner}/{repo}/projects/{id}/columns - Create column
- PATCH /repos/{owner}/{repo}/projects/columns/{id} - Update column
- DELETE /repos/{owner}/{repo}/projects/columns/{id} - Delete column
- POST /repos/{owner}/{repo}/projects/columns/{id}/issues - Add issue
Features:
- Full Swagger/OpenAPI documentation
- Proper permission checks
- Pagination support for list endpoints
- State filtering (open/closed/all)
- Comprehensive error handling
- Token-based authentication with scope validation
- Archive repository protection
New Files:
- modules/structs/project.go: API data structures
- routers/api/v1/repo/project.go: API handlers
- routers/api/v1/swagger/project.go: Swagger responses
- services/convert/project.go: Model converters
- tests/integration/api_repo_project_test.go: Integration tests
Modified Files:
- models/project/issue.go: Added AddOrUpdateIssueToColumn function
- routers/api/v1/api.go: Registered project API routes
- routers/api/v1/swagger/options.go: Added project option types
- templates/swagger/v1_json.tmpl: Regenerated swagger spec
fix(api): remove duplicated permission checks in project handlers
Route middleware reqRepoReader(unit.TypeProjects) wraps the entire
/projects route group, and reqRepoWriter(unit.TypeProjects) is applied
to each mutating route individually in api.go. These middleware run
before any handler fires and already gate access correctly.
The inline CanRead/CanWrite checks at the top of all 10 handlers were
therefore unreachable dead code — removed from ListProjects, GetProject,
CreateProject, EditProject, DeleteProject, ListProjectColumns,
CreateProjectColumn, EditProjectColumn, DeleteProjectColumn, and
AddIssueToProjectColumn.
The now-unused "code.gitea.io/gitea/models/unit" import is also removed.
Addresses review feedback on: https://github.com/go-gitea/gitea/pull/36008
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
fix(api): replace AddOrUpdateIssueToColumn with IssueAssignOrRemoveProject
The custom AddOrUpdateIssueToColumn function introduced by this PR was
missing three things that the existing IssueAssignOrRemoveProject provides:
1. db.WithTx transaction wrapper — raw DB updates without a transaction
can leave the database in a partial state on error.
2. CreateComment(CommentTypeProject) — assigning an issue to a project
column via the UI creates a comment on the issue timeline. The API
doing the same action silently was an inconsistency.
3. CanBeAccessedByOwnerRepo ownership check — IssueAssignOrRemoveProject
validates that the issue is accessible within the repo/org context
before mutating state.
AddOrUpdateIssueToColumn is removed entirely. AddIssueToProjectColumn
now delegates to issues_model.IssueAssignOrRemoveProject, which already
has the issue object loaded earlier in the handler.
Addresses review feedback on: https://github.com/go-gitea/gitea/pull/36008
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
fix(api): remove unnecessary pagination from ListProjectColumns
Project columns are few in number by design (typically 3-8 per board).
The previous implementation fetched all columns from the DB then sliced
the result in memory — adding complexity and a misleading Link header
without any practical benefit.
ListProjectColumns now returns all columns directly. The page/limit
query parameters and associated swagger docs are removed.
Addresses review feedback on: https://github.com/go-gitea/gitea/pull/36008
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
fix(api): regenerate swagger spec after removing ListProjectColumns pagination
Removes the page and limit parameters from the generated swagger spec
for the ListProjectColumns endpoint, matching the handler change that
dropped in-memory pagination.
Co-authored-by: Claude <noreply@anthropic.com>
test(api): remove pagination assertion from TestAPIListProjectColumns
ListProjectColumns no longer supports pagination — it returns all columns
directly. Remove the page/limit test case that expected 2 of 3 columns.
Co-authored-by: Claude <noreply@anthropic.com>
fix(api): implement proper pagination for ListProjectColumns
Per contribution guidelines, list endpoints must support page/limit
query params and set X-Total-Count header.
- Add CountColumns and GetColumnsPaginated to project model (DB-level,
not in-memory slicing)
- ListProjectColumns uses utils.GetListOptions, calls paginated model
functions, and sets X-Total-Count via ctx.SetTotalCountHeader
- Restore page/limit swagger doc params on the endpoint
- Regenerate swagger spec
- Integration test covers: full list with X-Total-Count, page 1 of 2,
page 2 of 2, and 404 for non-existent project
Co-authored-by: Claude <noreply@anthropic.com>
Gitea
Purpose
The goal of this project is to make the easiest, fastest, and most painless way of setting up a self-hosted Git service.
As Gitea is written in Go, it works across all the platforms and architectures that are supported by Go, including Linux, macOS, and Windows on x86, amd64, ARM and PowerPC architectures. This project has been forked from Gogs since November of 2016, but a lot has changed.
For online demonstrations, you can visit demo.gitea.com.
For accessing free Gitea service (with a limited number of repositories), you can visit gitea.com.
To quickly deploy your own dedicated Gitea instance on Gitea Cloud, you can start a free trial at cloud.gitea.com.
Documentation
You can find comprehensive documentation on our official documentation website.
It includes installation, administration, usage, development, contributing guides, and more to help you get started and explore all features effectively.
If you have any suggestions or would like to contribute to it, you can visit the documentation repository
Building
From the root of the source tree, run:
TAGS="bindata" make build
or if SQLite support is required:
TAGS="bindata sqlite sqlite_unlock_notify" make build
The build target is split into two sub-targets:
make backendwhich requires Go Stable, the required version is defined in go.mod.make frontendwhich requires Node.js LTS or greater and pnpm.
Internet connectivity is required to download the go and npm modules. When building from the official source tarballs which include pre-built frontend files, the frontend target will not be triggered, making it possible to build without Node.js.
More info: https://docs.gitea.com/installation/install-from-source
Using
After building, a binary file named gitea will be generated in the root of the source tree by default. To run it, use:
./gitea web
Note
If you're interested in using our APIs, we have experimental support with documentation.
Contributing
Expected workflow is: Fork -> Patch -> Push -> Pull Request
Note
- YOU MUST READ THE CONTRIBUTORS GUIDE BEFORE STARTING TO WORK ON A PULL REQUEST.
- If you have found a vulnerability in the project, please write privately to security@gitea.io. Thanks!
Translating
Translations are done through Crowdin. If you want to translate to a new language, ask one of the managers in the Crowdin project to add a new language there.
You can also just create an issue for adding a language or ask on Discord on the #translation channel. If you need context or find some translation issues, you can leave a comment on the string or ask on Discord. For general translation questions there is a section in the docs. Currently a bit empty, but we hope to fill it as questions pop up.
Get more information from documentation.
Official and Third-Party Projects
We provide an official go-sdk, a CLI tool called tea and an action runner for Gitea Action.
We maintain a list of Gitea-related projects at gitea/awesome-gitea, where you can discover more third-party projects, including SDKs, plugins, themes, and more.
Communication
If you have questions that are not covered by the documentation, you can get in contact with us on our Discord server or create a post in the discourse forum.
Authors
Backers
Thank you to all our backers! 🙏 [Become a backer]
Sponsors
Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [Become a sponsor]
FAQ
How do you pronounce Gitea?
Gitea is pronounced /ɡɪ’ti:/ as in "gi-tea" with a hard g.
Why is this not hosted on a Gitea instance?
We're working on it.
Where can I find the security patches?
In the release log or the change log, search for the keyword SECURITY to find the security patches.
License
This project is licensed under the MIT License. See the LICENSE file for the full license text.





























