fix(api): normalize all API due dates to end of day (#38677)

Due dates set through the API were stored inconsistently. The create
endpoints kept the raw timestamp, issue and pull request edits used end
of day in the client's offset, and only the deadline and milestone edit
endpoints normalized to end of day in the server's UI timezone like the
web UI does. All API due dates now go through
`ParseAPIDeadlineToEndOfDay`.

Editing a pull request with `unset_due_date: false` and no `due_date`
dereferenced a nil pointer and returned 500. It now shares the issue
edit logic and returns 400.

Related to https://github.com/go-gitea/gitea/issues/37620, which is
about the web sidebar and isn't fixed here.

---------

Co-authored-by: silverwind <me@silverwind.io>
This commit is contained in:
okxintandsilverwind authored and GitHub committed 2026-10-03 11:59:43 +00:00
1 parent ad38b60983
commit ab1979bcfb
8 files changed
+58 -70

No files matched your search

+2
View File
@@ -126,11 +126,13 @@ func testAPICreateIssue(t *testing.T) {
Body: body,
Title: title,
Assignee: owner.Name,
Deadline: new(time.Date(2026, 5, 11, 12, 0, 0, 0, time.FixedZone("", -10*3600))),
}).AddTokenAuth(token)
resp := MakeRequest(t, req, http.StatusCreated)
apiIssue := DecodeJSON(t, resp, &api.Issue{})
assert.Equal(t, body, apiIssue.Body)
assert.Equal(t, title, apiIssue.Title)
assert.Equal(t, time.Date(2026, 5, 11, 23, 59, 59, 0, setting.DefaultUILocation).Unix(), apiIssue.Deadline.Unix())
unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{
RepoID: repoBefore.ID,
+10 -3
View File
@@ -449,13 +449,15 @@ func TestAPIEditPull(t *testing.T) {
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
title := "create a success pr"
req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls", owner10.Name, repo10.Name), &api.CreatePullRequestOption{
Head: "develop",
Base: "master",
Title: title,
Head: "develop",
Base: "master",
Title: title,
Deadline: new(time.Date(2026, 5, 11, 12, 0, 0, 0, time.FixedZone("", -10*3600))),
}).AddTokenAuth(token)
resp := MakeRequest(t, req, http.StatusCreated)
apiPull := DecodeJSON(t, resp, &api.PullRequest{})
assert.Equal(t, "master", apiPull.Base.Name)
assert.Equal(t, time.Date(2026, 5, 11, 23, 59, 59, 0, setting.DefaultUILocation).Unix(), apiPull.Deadline.Unix())
newTitle := "edit a this pr"
newBody := "edited body"
@@ -480,6 +482,11 @@ func TestAPIEditPull(t *testing.T) {
}).AddTokenAuth(token)
MakeRequest(t, req, http.StatusNotFound)
req = NewRequestWithJSON(t, http.MethodPatch, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d", owner10.Name, repo10.Name, pull.Index), &api.EditPullRequestOption{
RemoveDeadline: new(false),
}).AddTokenAuth(token)
MakeRequest(t, req, http.StatusBadRequest)
t.Run("PullContentVersion", func(t *testing.T) {
testAPIPullContentVersion(t, pull.ID)
})