From 90863e0ab51d1b243f67de266bbeeb7a9031c525 Mon Sep 17 00:00:00 2001
From: Gusted <postmaster@gusted.xyz>
Date: Sat, 5 Aug 2023 14:47:09 +0200
Subject: [PATCH] [GITEA] Allow release creation on commit

- The code and tests are already there to allow releases to be created
on commits.
- This patch modifies the web code to take into account that an commitID
could've been passed as target.
- Added unit test.
- Resolves https://codeberg.org/forgejo/forgejo/issues/1196
---
 routers/web/repo/release.go       |  4 +++-
 tests/integration/release_test.go | 15 ++++++++++++++-
 2 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/routers/web/repo/release.go b/routers/web/repo/release.go
index 957cf56972..93f2158be1 100644
--- a/routers/web/repo/release.go
+++ b/routers/web/repo/release.go
@@ -387,7 +387,9 @@ func NewReleasePost(ctx *context.Context) {
 		return
 	}
 
-	if !ctx.Repo.GitRepo.IsBranchExist(form.Target) {
+	// form.Target can be a branch name or a full commitID.
+	if !ctx.Repo.GitRepo.IsBranchExist(form.Target) &&
+		len(form.Target) == git.SHAFullLength && !ctx.Repo.GitRepo.IsCommitExist(form.Target) {
 		ctx.RenderWithErr(ctx.Tr("form.target_branch_not_exist"), tplReleaseNew, &form)
 		return
 	}
diff --git a/tests/integration/release_test.go b/tests/integration/release_test.go
index 8de761ea6c..1c4be6a927 100644
--- a/tests/integration/release_test.go
+++ b/tests/integration/release_test.go
@@ -21,6 +21,10 @@ import (
 )
 
 func createNewRelease(t *testing.T, session *TestSession, repoURL, tag, title string, preRelease, draft bool) {
+	createNewReleaseTarget(t, session, repoURL, tag, title, "master", preRelease, draft)
+}
+
+func createNewReleaseTarget(t *testing.T, session *TestSession, repoURL, tag, title, target string, preRelease, draft bool) {
 	req := NewRequest(t, "GET", repoURL+"/releases/new")
 	resp := session.MakeRequest(t, req, http.StatusOK)
 	htmlDoc := NewHTMLParser(t, resp.Body)
@@ -31,7 +35,7 @@ func createNewRelease(t *testing.T, session *TestSession, repoURL, tag, title st
 	postData := map[string]string{
 		"_csrf":      htmlDoc.GetCSRF(),
 		"tag_name":   tag,
-		"tag_target": "master",
+		"tag_target": target,
 		"title":      title,
 		"content":    "",
 	}
@@ -239,3 +243,12 @@ func TestViewTagsList(t *testing.T) {
 
 	assert.EqualValues(t, []string{"v1.0", "delete-tag", "v1.1"}, tagNames)
 }
+
+func TestReleaseOnCommit(t *testing.T) {
+	defer tests.PrepareTestEnv(t)()
+
+	session := loginUser(t, "user2")
+	createNewReleaseTarget(t, session, "/user2/repo1", "v0.0.1", "v0.0.1", "65f1bf27bc3bf70f64657658635e66094edbcb4d", false, false)
+
+	checkLatestReleaseAndCount(t, session, "/user2/repo1", "v0.0.1", translation.NewLocale("en-US").Tr("repo.release.stable"), 4)
+}