diff --git a/services/release/release.go b/services/release/release.go
index 3105ce24ae..64d132cd73 100644
--- a/services/release/release.go
+++ b/services/release/release.go
@@ -46,6 +46,7 @@ func createTag(gitRepo *git.Repository, rel *models.Release) error {
 				rel.Publisher, rel.Repo, git.TagPrefix+rel.TagName,
 				git.EmptySHA, commit.ID.String(), repository.NewPushCommits())
 			notification.NotifyCreateRef(rel.Publisher, rel.Repo, "tag", git.TagPrefix+rel.TagName)
+			rel.CreatedUnix = timeutil.TimeStampNow()
 		}
 		commit, err := gitRepo.GetTagCommit(rel.TagName)
 		if err != nil {
@@ -53,7 +54,6 @@ func createTag(gitRepo *git.Repository, rel *models.Release) error {
 		}
 
 		rel.Sha1 = commit.ID.String()
-		rel.CreatedUnix = timeutil.TimeStampNow()
 		rel.NumCommits, err = commit.CommitsCount()
 		if err != nil {
 			return fmt.Errorf("CommitsCount: %v", err)
diff --git a/services/release/release_test.go b/services/release/release_test.go
index effab21251..d5673b73b8 100644
--- a/services/release/release_test.go
+++ b/services/release/release_test.go
@@ -7,6 +7,7 @@ package release
 import (
 	"path/filepath"
 	"testing"
+	"time"
 
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/git"
@@ -101,3 +102,153 @@ func TestRelease_Create(t *testing.T) {
 		IsTag:        true,
 	}, nil))
 }
+
+func TestRelease_Update(t *testing.T) {
+	assert.NoError(t, models.PrepareTestDatabase())
+
+	user := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User)
+	repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository)
+	repoPath := models.RepoPath(user.Name, repo.Name)
+
+	gitRepo, err := git.OpenRepository(repoPath)
+	assert.NoError(t, err)
+	defer gitRepo.Close()
+
+	// Test a changed release
+	assert.NoError(t, CreateRelease(gitRepo, &models.Release{
+		RepoID:       repo.ID,
+		PublisherID:  user.ID,
+		TagName:      "v1.1.1",
+		Target:       "master",
+		Title:        "v1.1.1 is released",
+		Note:         "v1.1.1 is released",
+		IsDraft:      false,
+		IsPrerelease: false,
+		IsTag:        false,
+	}, nil))
+	release, err := models.GetRelease(repo.ID, "v1.1.1")
+	assert.NoError(t, err)
+	releaseCreatedUnix := release.CreatedUnix
+	time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp
+	release.Note = "Changed note"
+	assert.NoError(t, UpdateRelease(user, gitRepo, release, nil))
+	release, err = models.GetReleaseByID(release.ID)
+	assert.NoError(t, err)
+	assert.Equal(t, int64(releaseCreatedUnix), int64(release.CreatedUnix))
+
+	// Test a changed draft
+	assert.NoError(t, CreateRelease(gitRepo, &models.Release{
+		RepoID:       repo.ID,
+		PublisherID:  user.ID,
+		TagName:      "v1.2.1",
+		Target:       "65f1bf2",
+		Title:        "v1.2.1 is draft",
+		Note:         "v1.2.1 is draft",
+		IsDraft:      true,
+		IsPrerelease: false,
+		IsTag:        false,
+	}, nil))
+	release, err = models.GetRelease(repo.ID, "v1.2.1")
+	assert.NoError(t, err)
+	releaseCreatedUnix = release.CreatedUnix
+	time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp
+	release.Title = "Changed title"
+	assert.NoError(t, UpdateRelease(user, gitRepo, release, nil))
+	release, err = models.GetReleaseByID(release.ID)
+	assert.NoError(t, err)
+	assert.Less(t, int64(releaseCreatedUnix), int64(release.CreatedUnix))
+
+	// Test a changed pre-release
+	assert.NoError(t, CreateRelease(gitRepo, &models.Release{
+		RepoID:       repo.ID,
+		PublisherID:  user.ID,
+		TagName:      "v1.3.1",
+		Target:       "65f1bf2",
+		Title:        "v1.3.1 is pre-released",
+		Note:         "v1.3.1 is pre-released",
+		IsDraft:      false,
+		IsPrerelease: true,
+		IsTag:        false,
+	}, nil))
+	release, err = models.GetRelease(repo.ID, "v1.3.1")
+	assert.NoError(t, err)
+	releaseCreatedUnix = release.CreatedUnix
+	time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp
+	release.Title = "Changed title"
+	release.Note = "Changed note"
+	assert.NoError(t, UpdateRelease(user, gitRepo, release, nil))
+	release, err = models.GetReleaseByID(release.ID)
+	assert.NoError(t, err)
+	assert.Equal(t, int64(releaseCreatedUnix), int64(release.CreatedUnix))
+}
+
+func TestRelease_createTag(t *testing.T) {
+	assert.NoError(t, models.PrepareTestDatabase())
+
+	user := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User)
+	repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository)
+	repoPath := models.RepoPath(user.Name, repo.Name)
+
+	gitRepo, err := git.OpenRepository(repoPath)
+	assert.NoError(t, err)
+	defer gitRepo.Close()
+
+	// Test a changed release
+	release := &models.Release{
+		RepoID:       repo.ID,
+		PublisherID:  user.ID,
+		TagName:      "v2.1.1",
+		Target:       "master",
+		Title:        "v2.1.1 is released",
+		Note:         "v2.1.1 is released",
+		IsDraft:      false,
+		IsPrerelease: false,
+		IsTag:        false,
+	}
+	assert.NoError(t, createTag(gitRepo, release))
+	assert.NotEmpty(t, release.CreatedUnix)
+	releaseCreatedUnix := release.CreatedUnix
+	time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp
+	release.Note = "Changed note"
+	assert.NoError(t, createTag(gitRepo, release))
+	assert.Equal(t, int64(releaseCreatedUnix), int64(release.CreatedUnix))
+
+	// Test a changed draft
+	release = &models.Release{
+		RepoID:       repo.ID,
+		PublisherID:  user.ID,
+		TagName:      "v2.2.1",
+		Target:       "65f1bf2",
+		Title:        "v2.2.1 is draft",
+		Note:         "v2.2.1 is draft",
+		IsDraft:      true,
+		IsPrerelease: false,
+		IsTag:        false,
+	}
+	assert.NoError(t, createTag(gitRepo, release))
+	releaseCreatedUnix = release.CreatedUnix
+	time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp
+	release.Title = "Changed title"
+	assert.NoError(t, createTag(gitRepo, release))
+	assert.Less(t, int64(releaseCreatedUnix), int64(release.CreatedUnix))
+
+	// Test a changed pre-release
+	release = &models.Release{
+		RepoID:       repo.ID,
+		PublisherID:  user.ID,
+		TagName:      "v2.3.1",
+		Target:       "65f1bf2",
+		Title:        "v2.3.1 is pre-released",
+		Note:         "v2.3.1 is pre-released",
+		IsDraft:      false,
+		IsPrerelease: true,
+		IsTag:        false,
+	}
+	assert.NoError(t, createTag(gitRepo, release))
+	releaseCreatedUnix = release.CreatedUnix
+	time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp
+	release.Title = "Changed title"
+	release.Note = "Changed note"
+	assert.NoError(t, createTag(gitRepo, release))
+	assert.Equal(t, int64(releaseCreatedUnix), int64(release.CreatedUnix))
+}