addProjectIamBinding method
Add an IAM binding (gcloud projects add-iam-policy-binding) granting
role to member on projectId. Idempotent: re-running on a project
where the binding already exists is a no-op (gcloud reports success).
member must be a fully qualified principal such as
serviceAccount:foo@bar.iam.gserviceaccount.com or
user:alice@example.com. The call runs without _authEnvironment
so that a credentialed human account can grant roles. When account is
provided, the command passes --account=<email> rather than switching
the user's global active gcloud account.
Returns (success, errorMessage). The error message is a stripped
stderr useful for direct display in the wizard's prompt.
Implementation
Future<({bool success, String error})> addProjectIamBinding({
required String projectId,
required String member,
required String role,
String? account,
}) async {
final ProcessResult r = await _runner.run('gcloud', <String>[
'projects',
'add-iam-policy-binding',
projectId,
'--member=$member',
'--role=$role',
'--condition=None',
'--quiet',
if (account != null && account.trim().isNotEmpty)
'--account=${account.trim()}',
]);
if (r.success) {
return (success: true, error: '');
}
final String stderr = _stripAnsi(r.stderr).trim();
final String stdout = _stripAnsi(r.stdout).trim();
return (
success: false,
error: stderr.isNotEmpty
? stderr
: (stdout.isNotEmpty
? stdout
: 'gcloud add-iam-policy-binding exited ${r.exitCode}'),
);
}