From 97893b362c2fd26a4f54b6a94f6b20ed46abf109 Mon Sep 17 00:00:00 2001 From: JakobDev Date: Mon, 26 Sep 2022 14:42:50 +0200 Subject: [PATCH 1/7] Add API endpoint to get latest release --- routers/api/v1/api.go | 1 + routers/api/v1/repo/release.go | 41 ++++++++++++++++++++++++++++++++++ templates/swagger/v1_json.tmpl | 36 +++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 6a98121b73a51..88583f27a35c7 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -964,6 +964,7 @@ func Routes(ctx gocontext.Context) *web.Route { m.Group("/releases", func() { m.Combo("").Get(repo.ListReleases). Post(reqToken(), reqRepoWriter(unit.TypeReleases), context.ReferencesGitRepo(), bind(api.CreateReleaseOption{}), repo.CreateRelease) + m.Combo("/latest").Get(repo.GetLatestRelease) m.Group("/{id}", func() { m.Combo("").Get(repo.GetRelease). Patch(reqToken(), reqRepoWriter(unit.TypeReleases), context.ReferencesGitRepo(), bind(api.EditReleaseOption{}), repo.EditRelease). diff --git a/routers/api/v1/repo/release.go b/routers/api/v1/repo/release.go index acc9696e1bef1..5dc0b8e5aadb7 100644 --- a/routers/api/v1/repo/release.go +++ b/routers/api/v1/repo/release.go @@ -68,6 +68,47 @@ func GetRelease(ctx *context.APIContext) { ctx.JSON(http.StatusOK, convert.ToRelease(release)) } +// GetLatestRelease gets the latest stable release of a repository +func GetLatestRelease(ctx *context.APIContext) { + // swagger:operation GET /repos/{owner}/{repo}/releases/latest repository repoGetLatestRelease + // --- + // summary: Gets the latest stable release + // produces: + // - application/json + // parameters: + // - name: owner + // in: path + // description: owner of the repo + // type: string + // required: true + // - name: repo + // in: path + // description: name of the repo + // type: string + // required: true + // responses: + // "200": + // "$ref": "#/responses/Release" + // "404": + // "$ref": "#/responses/notFound" + release, err := repo_model.GetLatestReleaseByRepoID(ctx.Repo.Repository.ID) + if err != nil && !repo_model.IsErrReleaseNotExist(err) { + ctx.Error(http.StatusInternalServerError, "GetLatestRelease", err) + return + } + if err != nil && repo_model.IsErrReleaseNotExist(err) || + release.IsTag || release.RepoID != ctx.Repo.Repository.ID { + ctx.NotFound() + return + } + + if err := release.LoadAttributes(); err != nil { + ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) + return + } + ctx.JSON(http.StatusOK, convert.ToRelease(release)) +} + // ListReleases list a repository's releases func ListReleases(ctx *context.APIContext) { // swagger:operation GET /repos/{owner}/{repo}/releases repository repoListReleases diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 15f71c244a0e4..a4f43d80cd1d3 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -9162,6 +9162,42 @@ } } }, + "/repos/{owner}/{repo}/releases/latest": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "repository" + ], + "summary": "Gets the latest stable release of a repository", + "operationId": "repoGetLatestRelease", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/Release" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, "/repos/{owner}/{repo}/releases/tags/{tag}": { "get": { "produces": [ From 26597f1d7f1aa5e4a2914ca656c7ce4a5f883537 Mon Sep 17 00:00:00 2001 From: JakobDev Date: Tue, 18 Oct 2022 14:02:52 +0200 Subject: [PATCH 2/7] Add tests --- tests/integration/release_test.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/integration/release_test.go b/tests/integration/release_test.go index 2a52a5cde21c1..c2c2d9dc89e82 100644 --- a/tests/integration/release_test.go +++ b/tests/integration/release_test.go @@ -81,6 +81,21 @@ func TestViewReleasesNoLogin(t *testing.T) { MakeRequest(t, req, http.StatusOK) } +func TestViewLatestRelease(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + session := loginUser(t, "user2") + req := NewRequest(t, "GET", "/user2/repo1/releases/latest") + session.MakeRequest(t, req, http.StatusOK) +} + +func TestViewLatestReleaseNoLogin(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + req := NewRequest(t, "GET", "/user2/repo1/releases/latest") + MakeRequest(t, req, http.StatusOK) +} + func TestCreateRelease(t *testing.T) { defer tests.PrepareTestEnv(t)() From f7eebee51df1eb881ba2f66780916c392ee192e5 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 8 Dec 2022 21:13:16 +0800 Subject: [PATCH 3/7] Update routers/api/v1/repo/release.go Co-authored-by: delvh --- routers/api/v1/repo/release.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routers/api/v1/repo/release.go b/routers/api/v1/repo/release.go index 5dc0b8e5aadb7..037b1bef8fd31 100644 --- a/routers/api/v1/repo/release.go +++ b/routers/api/v1/repo/release.go @@ -68,7 +68,7 @@ func GetRelease(ctx *context.APIContext) { ctx.JSON(http.StatusOK, convert.ToRelease(release)) } -// GetLatestRelease gets the latest stable release of a repository +// GetLatestRelease gets the latest stable release of a repository func GetLatestRelease(ctx *context.APIContext) { // swagger:operation GET /repos/{owner}/{repo}/releases/latest repository repoGetLatestRelease // --- From 2973361e00ffe57b40a409e2703f0738a0a2d4d8 Mon Sep 17 00:00:00 2001 From: JakobDev Date: Mon, 23 Jan 2023 18:00:40 +0100 Subject: [PATCH 4/7] Update comments --- routers/api/v1/repo/release.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/routers/api/v1/repo/release.go b/routers/api/v1/repo/release.go index 037b1bef8fd31..a9017e51f312a 100644 --- a/routers/api/v1/repo/release.go +++ b/routers/api/v1/repo/release.go @@ -68,11 +68,11 @@ func GetRelease(ctx *context.APIContext) { ctx.JSON(http.StatusOK, convert.ToRelease(release)) } -// GetLatestRelease gets the latest stable release of a repository +// GetLatestRelease gets the most recent non-prerelease, non-draft release of a repository, sorted by created_at func GetLatestRelease(ctx *context.APIContext) { // swagger:operation GET /repos/{owner}/{repo}/releases/latest repository repoGetLatestRelease // --- - // summary: Gets the latest stable release + // summary: Gets the most recent non-prerelease, non-draft release of a repository, sorted by created_at // produces: // - application/json // parameters: From abaef2b171276633fb94a6ea3e2dfb608ee7eadb Mon Sep 17 00:00:00 2001 From: JakobDev Date: Mon, 23 Jan 2023 18:19:20 +0100 Subject: [PATCH 5/7] Fix build --- routers/api/v1/api.go | 3 +-- routers/api/v1/repo/release.go | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 28bf7520add47..21bc2e2de4d6d 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -1010,9 +1010,8 @@ func Routes(ctx gocontext.Context) *web.Route { }) m.Group("/releases", func() { m.Combo("").Get(repo.ListReleases). - Post(reqToken(), reqRepoWriter(unit.TypeReleases), context.ReferencesGitRepo(), bind(api.CreateReleaseOption{}), repo.CreateRelease) - m.Combo("/latest").Get(repo.GetLatestRelease) Post(reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeReleases), context.ReferencesGitRepo(), bind(api.CreateReleaseOption{}), repo.CreateRelease) + m.Combo("/latest").Get(repo.GetLatestRelease) m.Group("/{id}", func() { m.Combo("").Get(repo.GetRelease). Patch(reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeReleases), context.ReferencesGitRepo(), bind(api.EditReleaseOption{}), repo.EditRelease). diff --git a/routers/api/v1/repo/release.go b/routers/api/v1/repo/release.go index d805063631025..c01e66150fe33 100644 --- a/routers/api/v1/repo/release.go +++ b/routers/api/v1/repo/release.go @@ -101,7 +101,7 @@ func GetLatestRelease(ctx *context.APIContext) { return } - if err := release.LoadAttributes(); err != nil { + if err := release.LoadAttributes(ctx); err != nil { ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) return } From b88b2e65932bb056c9735740c6f925580392b6ce Mon Sep 17 00:00:00 2001 From: JakobDev Date: Mon, 23 Jan 2023 18:29:12 +0100 Subject: [PATCH 6/7] Run make generate-swagger --- templates/swagger/v1_json.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 7adc750f6dab9..cd64b7070ffab 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -9784,7 +9784,7 @@ "tags": [ "repository" ], - "summary": "Gets the latest stable release of a repository", + "summary": "Gets the most recent non-prerelease, non-draft release of a repository, sorted by created_at", "operationId": "repoGetLatestRelease", "parameters": [ { From 155a3626b65ef356f9d039830769c70edc9f5f1a Mon Sep 17 00:00:00 2001 From: JakobDev Date: Tue, 24 Jan 2023 09:52:46 +0100 Subject: [PATCH 7/7] Try to fix tests --- tests/integration/api_releases_test.go | 18 ++++++++++++++++++ tests/integration/release_test.go | 15 --------------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/tests/integration/api_releases_test.go b/tests/integration/api_releases_test.go index d7f2a1b8b1b43..aa5816ad02944 100644 --- a/tests/integration/api_releases_test.go +++ b/tests/integration/api_releases_test.go @@ -176,6 +176,24 @@ func TestAPICreateReleaseToDefaultBranchOnExistingTag(t *testing.T) { createNewReleaseUsingAPI(t, session, token, owner, repo, "v0.0.1", "", "v0.0.1", "test") } +func TestAPIGetLatestRelease(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) + + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/releases/latest", + owner.Name, repo.Name) + + req := NewRequestf(t, "GET", urlStr) + resp := MakeRequest(t, req, http.StatusOK) + + var release *api.Release + DecodeJSON(t, resp, &release) + + assert.Equal(t, "testing-release", release.Title) +} + func TestAPIGetReleaseByTag(t *testing.T) { defer tests.PrepareTestEnv(t)() diff --git a/tests/integration/release_test.go b/tests/integration/release_test.go index 2691692ca2f21..3fcd4a5b5e8e8 100644 --- a/tests/integration/release_test.go +++ b/tests/integration/release_test.go @@ -80,21 +80,6 @@ func TestViewReleasesNoLogin(t *testing.T) { MakeRequest(t, req, http.StatusOK) } -func TestViewLatestRelease(t *testing.T) { - defer tests.PrepareTestEnv(t)() - - session := loginUser(t, "user2") - req := NewRequest(t, "GET", "/user2/repo1/releases/latest") - session.MakeRequest(t, req, http.StatusOK) -} - -func TestViewLatestReleaseNoLogin(t *testing.T) { - defer tests.PrepareTestEnv(t)() - - req := NewRequest(t, "GET", "/user2/repo1/releases/latest") - MakeRequest(t, req, http.StatusOK) -} - func TestCreateRelease(t *testing.T) { defer tests.PrepareTestEnv(t)()