From 4abf9e9db43ce1628631424d3a1ea563061d5c21 Mon Sep 17 00:00:00 2001 From: Squel Date: Wed, 13 Aug 2025 03:29:36 +0200 Subject: [PATCH] feat: show CI status on force-pushes (#8655) If a change is part of a force-push and the commit(s) have a CI status, this will now be shown after the hashes. `interactiveBorder` has been lowered as it was possible to activate the hover state for both commits. It would be unreasonable to test this within Playwright and thus this needs to be manually tested. On a pull request page that contains a force-push you will notice: a) the (de)activation area for force-pushes is now smaller, and; b) it is not possible to activate the hover state/popup for both commits. ExecuteTemplate function from @gusted https://codeberg.org/forgejo/forgejo/pulls/5168 https://codeberg.org/forgejo/forgejo/pulls/2884 Close #4932 Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/8655 Reviewed-by: Otto Reviewed-by: 0ko <0ko@noreply.codeberg.org> Co-authored-by: Squel Co-committed-by: Squel --- models/issues/comment.go | 17 +++++++------- modules/templates/helper.go | 19 ++++++++++++++++ options/locale/locale_en-US.ini | 2 +- .../repo/issue/view_content/comments.tmpl | 8 +++++-- .../integration/actions_commit_status_test.go | 13 +++++++++++ .../commit_status.yml | 22 +++++++++++++++++++ web_src/js/features/repo-commit.js | 1 + 7 files changed, 70 insertions(+), 12 deletions(-) create mode 100644 tests/integration/fixtures/TestForcePushCommitStatus/commit_status.yml diff --git a/models/issues/comment.go b/models/issues/comment.go index 523a6ba9b9..a84bbffd08 100644 --- a/models/issues/comment.go +++ b/models/issues/comment.go @@ -795,17 +795,16 @@ func (c *Comment) LoadPushCommits(ctx context.Context) (err error) { } c.OldCommit = data.CommitIDs[0] c.NewCommit = data.CommitIDs[1] - } else { - gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, c.Issue.Repo) - if err != nil { - return err - } - defer closer.Close() - - c.Commits = git_model.ParseCommitsWithStatus(ctx, gitRepo.GetCommitsFromIDs(data.CommitIDs), c.Issue.Repo) - c.CommitsNum = int64(len(c.Commits)) } + gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, c.Issue.Repo) + if err != nil { + return err + } + defer closer.Close() + c.Commits = git_model.ParseCommitsWithStatus(ctx, gitRepo.GetCommitsFromIDs(data.CommitIDs), c.Issue.Repo) + c.CommitsNum = int64(len(c.Commits)) + return err } diff --git a/modules/templates/helper.go b/modules/templates/helper.go index 42b4bad83c..2e33e51e60 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -6,6 +6,8 @@ package templates import ( + "bytes" + "context" "fmt" "html" "html/template" @@ -29,6 +31,23 @@ func NewFuncMap() template.FuncMap { return map[string]any{ "ctx": func() any { return nil }, // template context function + "ExecuteTemplate": func(ctx context.Context, tmplName string, args any) template.HTML { + h := HTMLRenderer() + tmpl, err := h.TemplateLookup(tmplName, ctx) + if err != nil { + panic("Template not found: " + tmplName) + } + + buf := bytes.Buffer{} + if err := tmpl.Execute(&buf, args); err != nil { + panic("Error while executing template") + } + + // We can safely return this as `template.HTML` as html/template will + // already make sure it's sanitized. + return template.HTML(buf.String()) + }, + "DumpVar": dumpVar, // ----------------------------------------------------------------- diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 2664a59ac9..1dc6d38c8c 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -1804,7 +1804,7 @@ issues.time_spent_from_all_authors = `Total time spent: %s` issues.due_date = Due date issues.push_commit_1 = added %d commit %s issues.push_commits_n = added %d commits %s -issues.force_push_codes = `force-pushed %[1]s from %[2]s to %[4]s %[6]s` +issues.force_push_codes = `force-pushed %[1]s from %[2]s %[8]s to %[4]s %[9]s %[6]s` issues.force_push_compare = Compare issues.due_date_form = yyyy-mm-dd issues.due_date_form_edit = Edit diff --git a/templates/repo/issue/view_content/comments.tmpl b/templates/repo/issue/view_content/comments.tmpl index a212bb871a..3b097aacaf 100644 --- a/templates/repo/issue/view_content/comments.tmpl +++ b/templates/repo/issue/view_content/comments.tmpl @@ -572,8 +572,12 @@ {{if .IsForcePush}} - {{template "shared/user/authorlink" .Poster}} - {{ctx.Locale.Tr "repo.issues.force_push_codes" $.Issue.PullRequest.HeadBranch (ShortSha .OldCommit) ($.Issue.Repo.CommitLink .OldCommit) (ShortSha .NewCommit) ($.Issue.Repo.CommitLink .NewCommit) $createdStr "ui sha"}} + {{ + template "shared/user/authorlink" .Poster}} + {{ctx.Locale.Tr "repo.issues.force_push_codes" $.Issue.PullRequest.HeadBranch (ShortSha .OldCommit) ($.Issue.Repo.CommitLink .OldCommit) (ShortSha .NewCommit) ($.Issue.Repo.CommitLink .NewCommit) $createdStr "ui sha" + (ExecuteTemplate ctx "repo/commit_statuses" (dict "Status" (index .Commits 0).Status "Statuses" (index .Commits 0).Statuses)) + (ExecuteTemplate ctx "repo/commit_statuses" (dict "Status" (index .Commits 1).Status "Statuses" (index .Commits 1).Statuses)) + }} {{if $.Issue.PullRequest.BaseRepo.Name}} {{ctx.Locale.Tr "repo.issues.force_push_compare"}} diff --git a/tests/integration/actions_commit_status_test.go b/tests/integration/actions_commit_status_test.go index a14b427c98..fdc12205fe 100644 --- a/tests/integration/actions_commit_status_test.go +++ b/tests/integration/actions_commit_status_test.go @@ -4,6 +4,7 @@ package integration import ( + "net/http" "net/url" "testing" @@ -17,6 +18,7 @@ import ( "forgejo.org/modules/test" "forgejo.org/services/actions" "forgejo.org/services/automerge" + "forgejo.org/tests" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -48,3 +50,14 @@ func TestActionsAutomerge(t *testing.T) { }, ) } + +func TestForcePushCommitStatus(t *testing.T) { + defer unittest.OverrideFixtures("tests/integration/fixtures/TestForcePushCommitStatus/")() + defer tests.PrepareTestEnv(t)() + + req := NewRequest(t, "GET", "/user2/commitsonpr/pulls/1") + resp := MakeRequest(t, req, http.StatusOK) + htmlDoc := NewHTMLParser(t, resp.Body) + htmlDoc.AssertElement(t, ".forced-push [data-tippy='commit-statuses']:nth-of-type(3) svg.commit-status.octicon-dot-fill", true) + htmlDoc.AssertElement(t, ".forced-push [data-tippy='commit-statuses']:nth-of-type(5) svg.commit-status.octicon-check", true) +} diff --git a/tests/integration/fixtures/TestForcePushCommitStatus/commit_status.yml b/tests/integration/fixtures/TestForcePushCommitStatus/commit_status.yml new file mode 100644 index 0000000000..9673410671 --- /dev/null +++ b/tests/integration/fixtures/TestForcePushCommitStatus/commit_status.yml @@ -0,0 +1,22 @@ +- + id: 1000 + index: 1 + repo_id: 58 + state: "pending" + sha: "1978192d98bb1b65e11c2cf37da854fbf94bffd6" + target_url: https://example.com/builds/ + description: My awesome CI-service + context: ci/awesomeness + context_hash: c65f4d64a3b14a3eced0c9b36799e66e1bd5ced7 + creator_id: 2 +- + id: 1001 + index: 1 + repo_id: 58 + state: "success" + sha: "9b93963cf6de4dc33f915bb67f192d099c301f43" + target_url: https://example.com/builds/ + description: My awesome CI-service + context: ci/awesomeness + context_hash: c65f4d64a3b14a3eced0c9b36799e66e1bd5ced7 + creator_id: 2 \ No newline at end of file diff --git a/web_src/js/features/repo-commit.js b/web_src/js/features/repo-commit.js index 988d57b891..c546cfe0c2 100644 --- a/web_src/js/features/repo-commit.js +++ b/web_src/js/features/repo-commit.js @@ -22,6 +22,7 @@ export function initCommitStatuses() { interactive: true, role: 'dialog', theme: 'box-with-header', + interactiveBorder: element.closest('.forced-push') ? 0 : 20, }); } }