diff --git a/integrations/api_issue_milestone_test.go b/integrations/api_issue_milestone_test.go index 4cc574b9e..b9942d9a3 100644 --- a/integrations/api_issue_milestone_test.go +++ b/integrations/api_issue_milestone_test.go @@ -61,6 +61,11 @@ func TestAPIIssuesMilestone(t *testing.T) { DecodeJSON(t, resp, &apiMilestones) 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)) resp = session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiMilestones) diff --git a/routers/api/v1/repo/milestone.go b/routers/api/v1/repo/milestone.go index f6f6b2946..5a250dbd8 100644 --- a/routers/api/v1/repo/milestone.go +++ b/routers/api/v1/repo/milestone.go @@ -7,6 +7,7 @@ package repo import ( "net/http" + "strconv" "time" "code.gitea.io/gitea/models" @@ -73,7 +74,7 @@ func ListMilestones(ctx *context.APIContext) { 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) { // swagger:operation GET /repos/{owner}/{repo}/milestones/{id} issue issueGetMilestone // --- @@ -93,23 +94,18 @@ func GetMilestone(ctx *context.APIContext) { // required: true // - name: id // in: path - // description: id of the milestone - // type: integer - // format: int64 + // description: the milestone to get, identified by ID and if not available by name + // type: string // required: true // responses: // "200": // "$ref": "#/responses/Milestone" - milestone, err := models.GetMilestoneByRepoID(ctx.Repo.Repository.ID, ctx.ParamsInt64(":id")) - if err != nil { - if models.IsErrMilestoneNotExist(err) { - ctx.NotFound() - } else { - ctx.Error(http.StatusInternalServerError, "GetMilestoneByRepoID", err) - } + milestone := getMilestoneByIDOrName(ctx) + if ctx.Written() { return } + 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)) } -// 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) { // swagger:operation PATCH /repos/{owner}/{repo}/milestones/{id} issue issueEditMilestone // --- @@ -187,9 +183,8 @@ func EditMilestone(ctx *context.APIContext, form api.EditMilestoneOption) { // required: true // - name: id // in: path - // description: id of the milestone - // type: integer - // format: int64 + // description: the milestone to edit, identified by ID and if not available by name + // type: string // required: true // - name: body // in: body @@ -199,13 +194,8 @@ func EditMilestone(ctx *context.APIContext, form api.EditMilestoneOption) { // "200": // "$ref": "#/responses/Milestone" - milestone, err := models.GetMilestoneByRepoID(ctx.Repo.Repository.ID, ctx.ParamsInt64(":id")) - if err != nil { - if models.IsErrMilestoneNotExist(err) { - ctx.NotFound() - } else { - ctx.Error(http.StatusInternalServerError, "GetMilestoneByRepoID", err) - } + milestone := getMilestoneByIDOrName(ctx) + if ctx.Written() { return } @@ -231,7 +221,7 @@ func EditMilestone(ctx *context.APIContext, form api.EditMilestoneOption) { 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) { // swagger:operation DELETE /repos/{owner}/{repo}/milestones/{id} issue issueDeleteMilestone // --- @@ -249,17 +239,49 @@ func DeleteMilestone(ctx *context.APIContext) { // required: true // - name: id // in: path - // description: id of the milestone to delete - // type: integer - // format: int64 + // description: the milestone to delete, identified by ID and if not available by name + // type: string // required: true // responses: // "204": // "$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) return } 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 +} diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index a5840f2ba..4b78b40dd 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -6353,9 +6353,8 @@ "required": true }, { - "type": "integer", - "format": "int64", - "description": "id of the milestone", + "type": "string", + "description": "the milestone to get, identified by ID and if not available by name", "name": "id", "in": "path", "required": true @@ -6389,9 +6388,8 @@ "required": true }, { - "type": "integer", - "format": "int64", - "description": "id of the milestone to delete", + "type": "string", + "description": "the milestone to delete, identified by ID and if not available by name", "name": "id", "in": "path", "required": true @@ -6431,9 +6429,8 @@ "required": true }, { - "type": "integer", - "format": "int64", - "description": "id of the milestone", + "type": "string", + "description": "the milestone to edit, identified by ID and if not available by name", "name": "id", "in": "path", "required": true