@@ -17,6 +17,10 @@ const (
1717 // prCommentRowMarkerFmt wraps each app/env's table row for find-and-replace.
1818 // Keyed by app+env so a new deploy replaces the previous row for the same app.
1919 prCommentRowMarkerFmt = "<!-- row:%s:%s -->"
20+
21+ // ghRetryDuration is the max retry duration for GitHub API calls via restate.
22+ // PR comments are best-effort — fail fast rather than block the deploy.
23+ ghRetryDuration = 5 * time .Second
2024)
2125
2226// findResult bundles the comment ID and body for restate.Run serialisation.
@@ -29,17 +33,7 @@ type findResult struct {
2933// app/env combination. Multiple deploy workflows for the same PR each manage
3034// their own row. All GitHub API calls are fire-and-forget.
3135type prCommentReporter struct {
32- github githubclient.GitHubClient
33- installationID int64
34- repo string
35- branch string
36- commitSHA string
37- deploymentID string
38- projectSlug string
39- appSlug string
40- envSlug string
41- logURL string
42- environmentURL string
36+ prCommentReporterConfig
4337
4438 prNumber int
4539 commentID int64
@@ -60,41 +54,39 @@ type prCommentReporterConfig struct {
6054}
6155
6256func newPRCommentReporter (cfg prCommentReporterConfig ) * prCommentReporter {
63- return & prCommentReporter {
64- github : cfg .GitHub ,
65- installationID : cfg .InstallationID ,
66- repo : cfg .Repo ,
67- branch : cfg .Branch ,
68- commitSHA : cfg .CommitSHA ,
69- deploymentID : cfg .DeploymentID ,
70- projectSlug : cfg .ProjectSlug ,
71- appSlug : cfg .AppSlug ,
72- envSlug : cfg .EnvSlug ,
73- logURL : cfg .LogURL ,
74- environmentURL : cfg .EnvironmentURL ,
75- }
57+ return & prCommentReporter {prCommentReporterConfig : cfg }
58+ }
59+
60+ func (r * prCommentReporter ) findComment (ctx restate.ObjectSharedContext , name string ) (findResult , error ) {
61+ return restate .Run (ctx , func (_ restate.RunContext ) (findResult , error ) {
62+ id , body , err := r .GitHub .FindBotComment (r .InstallationID , r .Repo , r .prNumber , prCommentMainMarker )
63+ return findResult {ID : id , Body : body }, err
64+ }, restate .WithName (name ), restate .WithMaxRetryDuration (ghRetryDuration ))
65+ }
66+
67+ func (r * prCommentReporter ) updateComment (ctx restate.ObjectSharedContext , body string , name string ) {
68+ _ = restate .RunVoid (ctx , func (_ restate.RunContext ) error {
69+ return r .GitHub .UpdateIssueComment (r .InstallationID , r .Repo , r .commentID , body )
70+ }, restate .WithName (name ), restate .WithMaxRetryDuration (ghRetryDuration ))
7671}
7772
7873func (r * prCommentReporter ) Create (ctx restate.ObjectSharedContext ) {
79- if r .installationID == 0 || r .repo == "" || r .branch == "" {
74+ if r .InstallationID == 0 || r .Repo == "" || r .Branch == "" {
8075 return
8176 }
8277
8378 prNumber , err := restate .Run (ctx , func (_ restate.RunContext ) (int , error ) {
84- return r .github .FindPullRequestForBranch (r .installationID , r .repo , r .branch )
85- }, restate .WithName ("find PR for branch" ), restate .WithMaxRetryDuration (30 * time . Second ))
79+ return r .GitHub .FindPullRequestForBranch (r .InstallationID , r .Repo , r .Branch )
80+ }, restate .WithName ("find PR for branch" ), restate .WithMaxRetryDuration (ghRetryDuration ))
8681 if err != nil || prNumber == 0 {
8782 if err != nil {
88- logger .Error ("failed to find PR for branch" , "error" , err , "branch" , r .branch )
83+ logger .Error ("failed to find PR for branch" , "error" , err , "branch" , r .Branch )
8984 }
9085 return
9186 }
9287 r .prNumber = prNumber
9388
94- existing , err := restate .Run (ctx , func (_ restate.RunContext ) (findResult , error ) {
95- id , body , findErr := r .github .FindBotComment (r .installationID , r .repo , r .prNumber , prCommentMainMarker )
96- return findResult {ID : id , Body : body }, findErr
97- }, restate .WithName ("find existing deploy comment" ), restate .WithMaxRetryDuration (30 * time .Second ))
89+ existing , err := r .findComment (ctx , "find existing deploy comment" )
9890 if err != nil {
9991 logger .Error ("failed to search for existing deploy comment" , "error" , err )
10092 }
@@ -103,17 +95,14 @@ func (r *prCommentReporter) Create(ctx restate.ObjectSharedContext) {
10395
10496 if existing .ID != 0 {
10597 r .commentID = existing .ID
106- body := r .upsertRow (existing .Body , row )
107- _ = restate .RunVoid (ctx , func (_ restate.RunContext ) error {
108- return r .github .UpdateIssueComment (r .installationID , r .repo , r .commentID , body )
109- }, restate .WithName ("add row to deploy comment" ), restate .WithMaxRetryDuration (30 * time .Second ))
98+ r .updateComment (ctx , r .upsertRow (existing .Body , row ), "add row to deploy comment" )
11099 return
111100 }
112101
113102 body := r .buildFullComment (row )
114103 commentID , createErr := restate .Run (ctx , func (_ restate.RunContext ) (int64 , error ) {
115- return r .github .CreateIssueComment (r .installationID , r .repo , r .prNumber , body )
116- }, restate .WithName ("create deploy comment" ), restate .WithMaxRetryDuration (30 * time . Second ))
104+ return r .GitHub .CreateIssueComment (r .InstallationID , r .Repo , r .prNumber , body )
105+ }, restate .WithName ("create deploy comment" ), restate .WithMaxRetryDuration (ghRetryDuration ))
117106 if createErr != nil {
118107 logger .Error ("failed to create PR comment" , "error" , createErr , "pr" , r .prNumber )
119108 return
@@ -129,38 +118,32 @@ func (r *prCommentReporter) Report(ctx restate.ObjectSharedContext, state string
129118 row := r .buildRow (stateLabel (state ))
130119
131120 // Re-read current body so we don't clobber other apps' rows.
132- current , err := restate .Run (ctx , func (_ restate.RunContext ) (findResult , error ) {
133- id , body , findErr := r .github .FindBotComment (r .installationID , r .repo , r .prNumber , prCommentMainMarker )
134- return findResult {ID : id , Body : body }, findErr
135- }, restate .WithName ("read deploy comment" ), restate .WithMaxRetryDuration (30 * time .Second ))
121+ current , err := r .findComment (ctx , "read deploy comment" )
136122 if err != nil || current .ID == 0 {
137123 return
138124 }
139125
140- body := r .upsertRow (current .Body , row )
141- _ = restate .RunVoid (ctx , func (_ restate.RunContext ) error {
142- return r .github .UpdateIssueComment (r .installationID , r .repo , r .commentID , body )
143- }, restate .WithName (fmt .Sprintf ("update deploy comment: %s" , state )), restate .WithMaxRetryDuration (30 * time .Second ))
126+ r .updateComment (ctx , r .upsertRow (current .Body , row ), fmt .Sprintf ("update deploy comment: %s" , state ))
144127}
145128
146129func (r * prCommentReporter ) rowMarker () string {
147- return fmt .Sprintf (prCommentRowMarkerFmt , r .appSlug , r .envSlug )
130+ return fmt .Sprintf (prCommentRowMarkerFmt , r .AppSlug , r .EnvSlug )
148131}
149132
150133func (r * prCommentReporter ) buildRow (status string ) string {
151- nameLabel := r .projectSlug
152- if r .appSlug != "default" {
153- nameLabel += " / " + r .appSlug
134+ nameLabel := r .ProjectSlug
135+ if r .AppSlug != "default" {
136+ nameLabel += " / " + r .AppSlug
154137 }
155138
156139 preview := "—"
157- if r .environmentURL != "" {
158- preview = fmt .Sprintf ("[Visit Preview](%s)" , r .environmentURL )
140+ if r .EnvironmentURL != "" {
141+ preview = fmt .Sprintf ("[Visit Preview](%s)" , r .EnvironmentURL )
159142 }
160143
161144 return fmt .Sprintf ("| %s **%s** (%s) | %s | %s | [Inspect](%s) | %s |" ,
162- r .rowMarker (), nameLabel , r .envSlug , status ,
163- preview , r .logURL ,
145+ r .rowMarker (), nameLabel , r .EnvSlug , status ,
146+ preview , r .LogURL ,
164147 time .Now ().UTC ().Format ("Jan 2, 2006 3:04pm" ))
165148}
166149
@@ -181,12 +164,10 @@ func (r *prCommentReporter) upsertRow(body string, newRow string) string {
181164 marker := r .rowMarker ()
182165 lines := strings .Split (body , "\n " )
183166
184- if strings .Contains (body , marker ) {
185- for i , line := range lines {
186- if strings .Contains (line , marker ) {
187- lines [i ] = newRow
188- return strings .Join (lines , "\n " )
189- }
167+ for i , line := range lines {
168+ if strings .Contains (line , marker ) {
169+ lines [i ] = newRow
170+ return strings .Join (lines , "\n " )
190171 }
191172 }
192173
@@ -197,6 +178,7 @@ func (r *prCommentReporter) upsertRow(body string, newRow string) string {
197178 lastRowIdx = i
198179 }
199180 }
181+
200182 if lastRowIdx >= 0 {
201183 result := make ([]string , 0 , len (lines )+ 1 )
202184 result = append (result , lines [:lastRowIdx + 1 ]... )
0 commit comments