@@ -4,7 +4,6 @@ package pulls |
| 4 | | 4 | |
| 5 | import ( | 5 | import ( |
| 6 | "context" | 6 | "context" |
| 7 | - "errors" | | |
| 8 | "fmt" | 7 | "fmt" |
| 9 | "strconv" | 8 | "strconv" |
| 10 | "strings" | 9 | "strings" |
@@ -12,12 +11,13 @@ import ( |
| 12 | | 11 | |
| 13 | "github.com/jackc/pgx/v5/pgtype" | 12 | "github.com/jackc/pgx/v5/pgtype" |
| 14 | | 13 | |
| | 14 | + "github.com/tenseleyFlow/shithub/internal/auth/audit" |
| 15 | "github.com/tenseleyFlow/shithub/internal/checks" | 15 | "github.com/tenseleyFlow/shithub/internal/checks" |
| 16 | - "github.com/tenseleyFlow/shithub/internal/issues" | | |
| 17 | issuesdb "github.com/tenseleyFlow/shithub/internal/issues/sqlc" | 16 | issuesdb "github.com/tenseleyFlow/shithub/internal/issues/sqlc" |
| 18 | "github.com/tenseleyFlow/shithub/internal/pulls/review" | 17 | "github.com/tenseleyFlow/shithub/internal/pulls/review" |
| 19 | pullsdb "github.com/tenseleyFlow/shithub/internal/pulls/sqlc" | 18 | pullsdb "github.com/tenseleyFlow/shithub/internal/pulls/sqlc" |
| 20 | repogit "github.com/tenseleyFlow/shithub/internal/repos/git" | 19 | repogit "github.com/tenseleyFlow/shithub/internal/repos/git" |
| | 20 | + reposdb "github.com/tenseleyFlow/shithub/internal/repos/sqlc" |
| 21 | usersdb "github.com/tenseleyFlow/shithub/internal/users/sqlc" | 21 | usersdb "github.com/tenseleyFlow/shithub/internal/users/sqlc" |
| 22 | ) | 22 | ) |
| 23 | | 23 | |
@@ -163,16 +163,35 @@ func Merge(ctx context.Context, deps Deps, p MergeParams) error { |
| 163 | } | 163 | } |
| 164 | | 164 | |
| 165 | if err := q.SetPullRequestMerged(ctx, tx, pullsdb.SetPullRequestMergedParams{ | 165 | if err := q.SetPullRequestMerged(ctx, tx, pullsdb.SetPullRequestMergedParams{ |
| 166 | - IssueID: p.PRID, | 166 | + IssueID: p.PRID, |
| 167 | - MergedByUserID: pgtype.Int8{Int64: p.ActorUserID, Valid: p.ActorUserID != 0}, | 167 | + MergedByUserID: pgtype.Int8{Int64: p.ActorUserID, Valid: p.ActorUserID != 0}, |
| 168 | - MergeCommitSha: pgtype.Text{String: mergeRes.MergedOID, Valid: true}, | 168 | + MergeCommitSha: pgtype.Text{String: mergeRes.MergedOID, Valid: true}, |
| 169 | - MergeMethod: pullsdb.NullPrMergeMethod{PrMergeMethod: pullsdb.PrMergeMethod(p.Method), Valid: true}, | 169 | + MergeMethod: pullsdb.NullPrMergeMethod{PrMergeMethod: pullsdb.PrMergeMethod(p.Method), Valid: true}, |
| 170 | - BaseOidAtMerge: pgtype.Text{String: pr.BaseOid, Valid: true}, | 170 | + BaseOidAtMerge: pgtype.Text{String: pr.BaseOid, Valid: true}, |
| 171 | - HeadOidAtMerge: pgtype.Text{String: pr.HeadOid, Valid: true}, | 171 | + HeadOidAtMerge: pgtype.Text{String: pr.HeadOid, Valid: true}, |
| 172 | }); err != nil { | 172 | }); err != nil { |
| 173 | return err | 173 | return err |
| 174 | } | 174 | } |
| 175 | | 175 | |
| | 176 | + // PerformMerge moved refs/heads/<base> on disk via update-ref, |
| | 177 | + // bypassing the post-receive hook that would normally maintain |
| | 178 | + // repos.default_branch_oid. When the merged base IS the repo's |
| | 179 | + // default branch, sync the column ourselves so the repo home view |
| | 180 | + // stays accurate. The audit caught this gap (S00-S25, H2). |
| | 181 | + rq := reposdb.New() |
| | 182 | + repo, err := rq.GetRepoByID(ctx, tx, issue.RepoID) |
| | 183 | + if err != nil { |
| | 184 | + return fmt.Errorf("merge: load repo: %w", err) |
| | 185 | + } |
| | 186 | + if repo.DefaultBranch == pr.BaseRef { |
| | 187 | + if err := rq.UpdateRepoDefaultBranchOID(ctx, tx, reposdb.UpdateRepoDefaultBranchOIDParams{ |
| | 188 | + ID: repo.ID, |
| | 189 | + DefaultBranchOid: pgtype.Text{String: mergeRes.MergedOID, Valid: true}, |
| | 190 | + }); err != nil { |
| | 191 | + return fmt.Errorf("merge: update default_branch_oid: %w", err) |
| | 192 | + } |
| | 193 | + } |
| | 194 | + |
| 176 | // Close the issue side with state_reason=completed. | 195 | // Close the issue side with state_reason=completed. |
| 177 | if err := iq.SetIssueState(ctx, tx, issuesdb.SetIssueStateParams{ | 196 | if err := iq.SetIssueState(ctx, tx, issuesdb.SetIssueStateParams{ |
| 178 | ID: p.PRID, | 197 | ID: p.PRID, |
@@ -233,6 +252,11 @@ func Merge(ctx context.Context, deps Deps, p MergeParams) error { |
| 233 | return err | 252 | return err |
| 234 | } | 253 | } |
| 235 | committed = true | 254 | committed = true |
| | 255 | + if deps.Audit != nil { |
| | 256 | + _ = deps.Audit.Record(ctx, deps.Pool, p.ActorUserID, |
| | 257 | + audit.ActionPullMerged, audit.TargetPull, p.PRID, |
| | 258 | + map[string]any{"method": p.Method, "commit": mergeRes.MergedOID}) |
| | 259 | + } |
| 236 | return nil | 260 | return nil |
| 237 | } | 261 | } |
| 238 | | 262 | |
@@ -273,6 +297,3 @@ func fetchCommitsForLinkScan(ctx context.Context, db pullsdb.DBTX, prID int64) [ |
| 273 | return out | 297 | return out |
| 274 | } | 298 | } |
| 275 | | 299 | |
| 276 | -// Compile-time check that issues' typed errors are still in scope so | | |
| 277 | -// EditPR's wrapping continues to work after refactors. | | |
| 278 | -var _ = errors.Is(issues.ErrEmptyTitle, issues.ErrEmptyTitle) | | |