Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 17 additions & 8 deletions cli/cmd/user/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ func AddCmd(ch *cmdutil.Helper) *cobra.Command {
var explores []string
var canvases []string
var restrictResources bool
var autoInvite bool

addCmd := &cobra.Command{
Use: "add",
Expand Down Expand Up @@ -132,14 +133,17 @@ func AddCmd(ch *cmdutil.Helper) *cobra.Command {
if !strings.Contains(err.Error(), "user is not a member of the org") {
return err
}
if !ch.Interactive {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I'm missing something, but the previous behavior kind of seems expected to me. What I mean is, adding a user to a group when they are not in the org is arguably a "mistake" – in interactive mode, we try to help the user to fix the mistake, but in non-interactive mode, it's okay to just tell them about the mistake.

To work around it, can't you just do it in two steps? Like:

# Step 1: Add to org
rill user add --email EMAIL --org ORG --interactive=false

# Step 2: Add to group
rill user add --email EMAIL --group GROUP --interactive=false

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I also suggested that as a workaround to Himadri.

But a question to consider, is it okay for commands to diverge in their interactive and non interactive behaviour ?

Copy link
Contributor

@begelundmuller begelundmuller Feb 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it's definitely okay. Consider the example when there's a common user error (like here): in non-interactive mode, we should be strict and return the error, but in interactive mode, we have an opportunity to help the user to fix it.

if !ch.Interactive && !autoInvite {
return err
}
ok, err := cmdutil.ConfirmPrompt(fmt.Sprintf("The user must be a member of %q to join one of its groups. Do you want to invite the user to join %q?", ch.Org, ch.Org), "", false)
if err != nil {
return err
// prompt only if explicit flag not set
if !cmd.Flags().Changed("auto-invite") {
autoInvite, err = cmdutil.ConfirmPrompt(fmt.Sprintf("The user must be a member of %q to join one of its groups. Do you want to invite the user to join %q?", ch.Org, ch.Org), "", false)
if err != nil {
return err
}
}
if !ok {
if !autoInvite {
return fmt.Errorf("aborted: user needs to be part of the organization to be added to the user group")
}

Expand All @@ -150,9 +154,13 @@ func AddCmd(ch *cmdutil.Helper) *cobra.Command {
orgRole = ""
}
if orgRole == "" {
err := cmdutil.SelectPromptIfEmpty(&orgRole, "Select organization role", orgRoles, orgRoles[len(orgRoles)-1])
if err != nil {
return err
if !ch.Interactive {
orgRole = "guest"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not too sure about this.

} else {
err := cmdutil.SelectPromptIfEmpty(&orgRole, "Select organization role", orgRoles, orgRoles[len(orgRoles)-1])
if err != nil {
return err
}
}
}

Expand Down Expand Up @@ -195,6 +203,7 @@ func AddCmd(ch *cmdutil.Helper) *cobra.Command {
addCmd.Flags().StringVar(&ch.Org, "org", ch.Org, "Organization")
addCmd.Flags().StringVar(&projectName, "project", "", "Project")
addCmd.Flags().StringVar(&group, "group", "", "User group")
addCmd.Flags().BoolVar(&autoInvite, "auto-invite", false, "Automatically invite the user to the organization if they are not already a member when adding to a group")
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If required this can be removed as well and the default behaviour in non interactive mode can be to auto invite as well.

addCmd.Flags().StringVar(&email, "email", "", "Email of the user")
addCmd.Flags().StringVar(&role, "role", "", fmt.Sprintf("Role of the user (options: %s)", strings.Join(orgRoles, ", ")))
addCmd.Flags().StringArrayVar(&explores, "explore", nil, "Explore resource to restrict to (repeat for multiple)")
Expand Down
Loading