mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-12-21 12:44:49 -05:00
[API] Milestone endpoints accept names too (#12649)
* API: Milestone endpoints accept names too * add test * rename Co-authored-by: Lauris BH <lauris@nix.lv>
This commit is contained in:
parent
33f606ce4c
commit
00a806de68
3 changed files with 60 additions and 36 deletions
|
@ -61,6 +61,11 @@ func TestAPIIssuesMilestone(t *testing.T) {
|
||||||
DecodeJSON(t, resp, &apiMilestones)
|
DecodeJSON(t, resp, &apiMilestones)
|
||||||
assert.Len(t, apiMilestones, 4)
|
assert.Len(t, apiMilestones, 4)
|
||||||
|
|
||||||
|
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/milestones/%s?token=%s", owner.Name, repo.Name, apiMilestones[2].Title, token))
|
||||||
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
|
DecodeJSON(t, resp, &apiMilestone)
|
||||||
|
assert.EqualValues(t, apiMilestones[2], apiMilestone)
|
||||||
|
|
||||||
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/milestones?state=%s&name=%s&token=%s", owner.Name, repo.Name, "all", "milestone2", token))
|
req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/milestones?state=%s&name=%s&token=%s", owner.Name, repo.Name, "all", "milestone2", token))
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
DecodeJSON(t, resp, &apiMilestones)
|
DecodeJSON(t, resp, &apiMilestones)
|
||||||
|
|
|
@ -7,6 +7,7 @@ package repo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models"
|
"code.gitea.io/gitea/models"
|
||||||
|
@ -73,7 +74,7 @@ func ListMilestones(ctx *context.APIContext) {
|
||||||
ctx.JSON(http.StatusOK, &apiMilestones)
|
ctx.JSON(http.StatusOK, &apiMilestones)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMilestone get a milestone for a repository
|
// GetMilestone get a milestone for a repository by ID and if not available by name
|
||||||
func GetMilestone(ctx *context.APIContext) {
|
func GetMilestone(ctx *context.APIContext) {
|
||||||
// swagger:operation GET /repos/{owner}/{repo}/milestones/{id} issue issueGetMilestone
|
// swagger:operation GET /repos/{owner}/{repo}/milestones/{id} issue issueGetMilestone
|
||||||
// ---
|
// ---
|
||||||
|
@ -93,23 +94,18 @@ func GetMilestone(ctx *context.APIContext) {
|
||||||
// required: true
|
// required: true
|
||||||
// - name: id
|
// - name: id
|
||||||
// in: path
|
// in: path
|
||||||
// description: id of the milestone
|
// description: the milestone to get, identified by ID and if not available by name
|
||||||
// type: integer
|
// type: string
|
||||||
// format: int64
|
|
||||||
// required: true
|
// required: true
|
||||||
// responses:
|
// responses:
|
||||||
// "200":
|
// "200":
|
||||||
// "$ref": "#/responses/Milestone"
|
// "$ref": "#/responses/Milestone"
|
||||||
|
|
||||||
milestone, err := models.GetMilestoneByRepoID(ctx.Repo.Repository.ID, ctx.ParamsInt64(":id"))
|
milestone := getMilestoneByIDOrName(ctx)
|
||||||
if err != nil {
|
if ctx.Written() {
|
||||||
if models.IsErrMilestoneNotExist(err) {
|
|
||||||
ctx.NotFound()
|
|
||||||
} else {
|
|
||||||
ctx.Error(http.StatusInternalServerError, "GetMilestoneByRepoID", err)
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.JSON(http.StatusOK, convert.ToAPIMilestone(milestone))
|
ctx.JSON(http.StatusOK, convert.ToAPIMilestone(milestone))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,7 +161,7 @@ func CreateMilestone(ctx *context.APIContext, form api.CreateMilestoneOption) {
|
||||||
ctx.JSON(http.StatusCreated, convert.ToAPIMilestone(milestone))
|
ctx.JSON(http.StatusCreated, convert.ToAPIMilestone(milestone))
|
||||||
}
|
}
|
||||||
|
|
||||||
// EditMilestone modify a milestone for a repository
|
// EditMilestone modify a milestone for a repository by ID and if not available by name
|
||||||
func EditMilestone(ctx *context.APIContext, form api.EditMilestoneOption) {
|
func EditMilestone(ctx *context.APIContext, form api.EditMilestoneOption) {
|
||||||
// swagger:operation PATCH /repos/{owner}/{repo}/milestones/{id} issue issueEditMilestone
|
// swagger:operation PATCH /repos/{owner}/{repo}/milestones/{id} issue issueEditMilestone
|
||||||
// ---
|
// ---
|
||||||
|
@ -187,9 +183,8 @@ func EditMilestone(ctx *context.APIContext, form api.EditMilestoneOption) {
|
||||||
// required: true
|
// required: true
|
||||||
// - name: id
|
// - name: id
|
||||||
// in: path
|
// in: path
|
||||||
// description: id of the milestone
|
// description: the milestone to edit, identified by ID and if not available by name
|
||||||
// type: integer
|
// type: string
|
||||||
// format: int64
|
|
||||||
// required: true
|
// required: true
|
||||||
// - name: body
|
// - name: body
|
||||||
// in: body
|
// in: body
|
||||||
|
@ -199,13 +194,8 @@ func EditMilestone(ctx *context.APIContext, form api.EditMilestoneOption) {
|
||||||
// "200":
|
// "200":
|
||||||
// "$ref": "#/responses/Milestone"
|
// "$ref": "#/responses/Milestone"
|
||||||
|
|
||||||
milestone, err := models.GetMilestoneByRepoID(ctx.Repo.Repository.ID, ctx.ParamsInt64(":id"))
|
milestone := getMilestoneByIDOrName(ctx)
|
||||||
if err != nil {
|
if ctx.Written() {
|
||||||
if models.IsErrMilestoneNotExist(err) {
|
|
||||||
ctx.NotFound()
|
|
||||||
} else {
|
|
||||||
ctx.Error(http.StatusInternalServerError, "GetMilestoneByRepoID", err)
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,7 +221,7 @@ func EditMilestone(ctx *context.APIContext, form api.EditMilestoneOption) {
|
||||||
ctx.JSON(http.StatusOK, convert.ToAPIMilestone(milestone))
|
ctx.JSON(http.StatusOK, convert.ToAPIMilestone(milestone))
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteMilestone delete a milestone for a repository
|
// DeleteMilestone delete a milestone for a repository by ID and if not available by name
|
||||||
func DeleteMilestone(ctx *context.APIContext) {
|
func DeleteMilestone(ctx *context.APIContext) {
|
||||||
// swagger:operation DELETE /repos/{owner}/{repo}/milestones/{id} issue issueDeleteMilestone
|
// swagger:operation DELETE /repos/{owner}/{repo}/milestones/{id} issue issueDeleteMilestone
|
||||||
// ---
|
// ---
|
||||||
|
@ -249,17 +239,49 @@ func DeleteMilestone(ctx *context.APIContext) {
|
||||||
// required: true
|
// required: true
|
||||||
// - name: id
|
// - name: id
|
||||||
// in: path
|
// in: path
|
||||||
// description: id of the milestone to delete
|
// description: the milestone to delete, identified by ID and if not available by name
|
||||||
// type: integer
|
// type: string
|
||||||
// format: int64
|
|
||||||
// required: true
|
// required: true
|
||||||
// responses:
|
// responses:
|
||||||
// "204":
|
// "204":
|
||||||
// "$ref": "#/responses/empty"
|
// "$ref": "#/responses/empty"
|
||||||
|
|
||||||
if err := models.DeleteMilestoneByRepoID(ctx.Repo.Repository.ID, ctx.ParamsInt64(":id")); err != nil {
|
m := getMilestoneByIDOrName(ctx)
|
||||||
|
if ctx.Written() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := models.DeleteMilestoneByRepoID(ctx.Repo.Repository.ID, m.ID); err != nil {
|
||||||
ctx.Error(http.StatusInternalServerError, "DeleteMilestoneByRepoID", err)
|
ctx.Error(http.StatusInternalServerError, "DeleteMilestoneByRepoID", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx.Status(http.StatusNoContent)
|
ctx.Status(http.StatusNoContent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getMilestoneByIDOrName get milestone by ID and if not available by name
|
||||||
|
func getMilestoneByIDOrName(ctx *context.APIContext) *models.Milestone {
|
||||||
|
mile := ctx.Params(":id")
|
||||||
|
mileID, _ := strconv.ParseInt(mile, 0, 64)
|
||||||
|
|
||||||
|
if mileID != 0 {
|
||||||
|
milestone, err := models.GetMilestoneByRepoID(ctx.Repo.Repository.ID, mileID)
|
||||||
|
if err == nil {
|
||||||
|
return milestone
|
||||||
|
} else if !models.IsErrMilestoneNotExist(err) {
|
||||||
|
ctx.Error(http.StatusInternalServerError, "GetMilestoneByRepoID", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
milestone, err := models.GetMilestoneByRepoIDANDName(ctx.Repo.Repository.ID, mile)
|
||||||
|
if err != nil {
|
||||||
|
if models.IsErrMilestoneNotExist(err) {
|
||||||
|
ctx.NotFound()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
ctx.Error(http.StatusInternalServerError, "GetMilestoneByRepoID", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return milestone
|
||||||
|
}
|
||||||
|
|
|
@ -6353,9 +6353,8 @@
|
||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "integer",
|
"type": "string",
|
||||||
"format": "int64",
|
"description": "the milestone to get, identified by ID and if not available by name",
|
||||||
"description": "id of the milestone",
|
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
|
@ -6389,9 +6388,8 @@
|
||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "integer",
|
"type": "string",
|
||||||
"format": "int64",
|
"description": "the milestone to delete, identified by ID and if not available by name",
|
||||||
"description": "id of the milestone to delete",
|
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
|
@ -6431,9 +6429,8 @@
|
||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "integer",
|
"type": "string",
|
||||||
"format": "int64",
|
"description": "the milestone to edit, identified by ID and if not available by name",
|
||||||
"description": "id of the milestone",
|
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true
|
"required": true
|
||||||
|
|
Loading…
Reference in a new issue