-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Assign Reviewers from Gitlab Code Owners Approvers (#98)
* Update gitlab schema to include approval rule data in context * Require int for an action * Optional string enum as well * Schema for assignees and reviewers should unnest from nodes * Base dry run action * Add schema for assign reviewers action step * Get Code owners interface * Limit reviewers * Skip bot users * Set cant guarantee order * Seed random * Need user ID to update MR reviewers * Pass ID to actor * Parse IDs as ints for create merge request func * Update pkg/scm/gitlab/client_actioner.go Co-authored-by: Christian Winther <[email protected]> * Code review suggestions * Update nilable rule type * Actors types * Also add method * Remove linear mode * Append review ids to update * Fix interface * Cast context to gitlab context and seperate action into new file * Add tests for get code owners * Repackage test * Tests for assign reviewers acton * Example * Should control when reviewers are assigned at action level * Doc ref to ApprovalRuleType * Skip id -1 check * Default to codeowners source * Add test for higher limit * Optional limit * Guard against nil rule type * Set ctx with random source * Make action options optional * Also set enum in json schema --------- Co-authored-by: Christian Winther <[email protected]>
- Loading branch information
Showing
16 changed files
with
644 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
package gitlab | ||
|
||
import ( | ||
"context" | ||
"log/slog" | ||
|
||
"github.com/jippi/scm-engine/pkg/scm" | ||
"github.com/jippi/scm-engine/pkg/state" | ||
slogctx "github.com/veqryn/slog-context" | ||
) | ||
|
||
func (c *Client) AssignReviewers(ctx context.Context, evalContext scm.EvalContext, update *scm.UpdateMergeRequestOptions, step scm.ActionStep) error { | ||
source, err := step.OptionalStringEnum("source", "codeowners", "codeowners") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
desiredLimit, err := step.OptionalInt("limit", 1) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
mode, err := step.OptionalStringEnum("mode", "random", "random") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// prevents misuse and situations where evaluate will assign reviewers endlessly | ||
existingReviewers := evalContext.GetReviewers() | ||
if len(existingReviewers) > 0 { | ||
slogctx.Debug(ctx, "Reviewers already assigned", slog.Any("reviewers", existingReviewers)) | ||
|
||
return nil | ||
} | ||
|
||
var eligibleReviewers []scm.Actor | ||
|
||
switch source { | ||
case "codeowners": | ||
eligibleReviewers = evalContext.GetCodeOwners() | ||
|
||
break | ||
} | ||
|
||
if len(eligibleReviewers) == 0 { | ||
slogctx.Debug(ctx, "No eligible reviewers found") | ||
|
||
return nil | ||
} | ||
|
||
var reviewers scm.Actors | ||
|
||
limit := desiredLimit | ||
if limit > len(eligibleReviewers) { | ||
limit = len(eligibleReviewers) | ||
} | ||
|
||
switch mode { | ||
case "random": | ||
reviewers = make(scm.Actors, limit) | ||
|
||
rand := state.RandomSeed(ctx) | ||
perm := rand.Perm(len(eligibleReviewers)) | ||
|
||
for i := 0; i < limit; i++ { | ||
reviewers[i] = eligibleReviewers[perm[i]] | ||
} | ||
|
||
break | ||
} | ||
|
||
reviewerIDs := make([]int, 0, len(reviewers)) | ||
|
||
for _, reviewer := range reviewers { | ||
id := reviewer.IntID() | ||
|
||
// skip invalid int ids, this should not happen but still safeguard against it | ||
if id == 0 { | ||
slogctx.Warn(ctx, "Invalid reviewer ID", slog.String("id", reviewer.ID)) | ||
|
||
continue | ||
} | ||
|
||
reviewerIDs = append(reviewerIDs, id) | ||
} | ||
|
||
if state.IsDryRun(ctx) { | ||
slogctx.Info(ctx, "(Dry Run) Assigning MR", slog.String("source", source), slog.Int("limit", limit), slog.String("mode", mode), slog.Any("reviewers", reviewers)) | ||
|
||
return nil | ||
} | ||
|
||
update.AppendReviewerIDs(reviewerIDs) | ||
|
||
return nil | ||
} |
Oops, something went wrong.