diff --git a/README.md b/README.md
index 640dc2f2..27fcedff 100644
--- a/README.md
+++ b/README.md
@@ -26,6 +26,9 @@ It's the nickname for our Special Projects team at Automattic.
Be well, be kind, make things and set them free.
+## Dependencies
+- Composer (instructions below)
+
## Installation
1. Open the Terminal on your Mac and clone this repository by running:
- `git clone git@github.com:Automattic/team51-cli.git`
@@ -59,6 +62,9 @@ If you get the error `./install-osx: line 2: composer: command not found`, you c
### `brew: command not found`
If you don't have [brew](https://brew.sh/) yet, install it by executing this from your Terminal: `/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"` — Tip: you can use brew to install all sort of apps on your Mac. Give it [a try](https://formulae.brew.sh/cask/zoom)
+### `gh: command not found`
+If you're onboarding/offboarding users, you will need access to Github CLI. Please refer to the [installation instructions](https://cli.github.com/), and then follow the instructions on the Terminal for authentication.
+
### `Warning: file_get_contents: failed to open stream`
```
Warning: file_get_contents(/Users/.../team51-cli/config.json): failed to open stream: No such file or directory in /Users/.../team51-cli/src/helpers/config-loader.php on line 5
diff --git a/load-application.php b/load-application.php
index 960c4eb5..76a9d48e 100644
--- a/load-application.php
+++ b/load-application.php
@@ -31,6 +31,7 @@
$application->add( new Team51\Command\Plugin_List() );
$application->add( new Team51\Command\Pressable_Generate_Token() );
$application->add( new Team51\Command\Pressable_Grant_Access() );
-
+$application->add( new Team51\Command\Github_Team_Add_User() );
+$application->add( new Team51\Command\Github_Team_Add_Repos() );
$application->run();
diff --git a/src/commands/create-repository.php b/src/commands/create-repository.php
index 46bd19bd..5ff53112 100644
--- a/src/commands/create-repository.php
+++ b/src/commands/create-repository.php
@@ -3,6 +3,7 @@
namespace Team51\Command;
use Team51\Helper\API_Helper;
+use Team51\Helper\DRY_Helper;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputOption;
@@ -35,6 +36,7 @@ protected function execute( InputInterface $input, OutputInterface $output ) {
$filesystem = new Filesystem();
$api_helper = new API_Helper();
+ $dry_helper = new DRY_Helper();
if ( empty( $input->getOption( 'repo-slug' ) ) ) {
$output->writeln( 'You must pass a repository slug with --repo-slug.' );
@@ -167,6 +169,14 @@ protected function execute( InputInterface $input, OutputInterface $output ) {
//exit;
}
+ // Adding repo to all required teams
+ // TODO: TEST
+ $output->writeln( "Adding '{$slug}' to the corresponding Github Teams." );
+ $repo_names = array( $slug );
+ $dry_helper->populate_team_with_repos( $repo_names, $dry_helper->GH_ACCESS_1['team_slug'], $dry_helper->GH_ACCESS_1['team_permission'] );
+ $dry_helper->populate_team_with_repos( $repo_names, $dry_helper->GH_ACCESS_2['team_slug'], $dry_helper->GH_ACCESS_2['team_permission'] );
+ $dry_helper->populate_team_with_repos( $repo_names, $dry_helper->GH_ACCESS_3['team_slug'], $dry_helper->GH_ACCESS_3['team_permission'] );
+
$ssh_url = $response->ssh_url;
$html_url = $response->html_url;
diff --git a/src/commands/github-repos-to-teams.php b/src/commands/github-repos-to-teams.php
new file mode 100644
index 00000000..44abfd3f
--- /dev/null
+++ b/src/commands/github-repos-to-teams.php
@@ -0,0 +1,61 @@
+setDescription( 'Add all Repositories to all GitHub Teams in the organization, with the respective repo permission.' )
+ ->setHelp( 'Add all repos to our Github teams. Most-likely to be run only once, for the creation of the teams' );
+ }
+
+ protected function execute( InputInterface $input, OutputInterface $output ) {
+ $this->api_helper = new API_Helper();
+ $this->dry_helper = new DRY_Helper();
+ $this->output = $output;
+
+ $output->writeln( "Pulling all repositories from our Github organization." );
+ $repos = array();
+ $repos_page = 1;
+ $more_repos = true;
+
+ while( $more_repos ) {
+ $this->output->writeln( "..." );
+ $tmp_repos = $this->api_helper->call_github_api(
+ sprintf( 'orgs/%s/repos?type=private&per_page=100&page=%s', GITHUB_API_OWNER, $repos_page ),
+ '',
+ 'GET'
+ );
+
+ if ( empty($tmp_repos) ) {
+ $more_repos = false;
+ break;
+ }
+
+ $repos = array_merge($repos, $tmp_repos);
+ $repos_page++;
+ }
+
+ $repo_names = array_column( $repos, 'name' );
+ $total_repos = count($repo_names);
+ $output->writeln( "{$total_repos} repositories will be added to each of our Github Teams." );
+
+ // Populate Teams with Repositories
+ $this->dry_helper->populate_team_with_repos( $repo_names, $this->dry_helper->GH_ACCESS_1['team_slug'], $this->dry_helper->GH_ACCESS_1['team_permission'] );
+ $this->dry_helper->populate_team_with_repos( $repo_names, $this->dry_helper->GH_ACCESS_2['team_slug'], $this->dry_helper->GH_ACCESS_2['team_permission'] );
+ $this->dry_helper->populate_team_with_repos( $repo_names, $this->dry_helper->GH_ACCESS_3['team_slug'], $this->dry_helper->GH_ACCESS_3['team_permission'] );
+
+ $output->writeln( "All done." );
+ }
+}
diff --git a/src/commands/github-team-add-user.php b/src/commands/github-team-add-user.php
new file mode 100644
index 00000000..a4c47860
--- /dev/null
+++ b/src/commands/github-team-add-user.php
@@ -0,0 +1,76 @@
+setDescription( 'Adds collaborator to Github Team and Pressable sites. Collaborator can be either a11n or contractor' )
+ ->setHelp( 'This command allows you to bulk add a collaborator to all Pressable sites and a Github team.' )
+ ->addOption( 'username', null, InputOption::VALUE_REQUIRED, "Collaborator's Github username." )
+ ->addOption( 'team', null, InputOption::VALUE_REQUIRED, sprintf('Github Team can be: %s, %s, or %s.', self::ACCESS_1, self::ACCESS_2, self::ACCESS_3) );
+ }
+
+ protected function execute( InputInterface $input, OutputInterface $output ) {
+ $this->api_helper = new API_Helper();
+ $this->output = $output;
+
+ $github_user = $input->getOption( 'github_username' );
+ if ( empty( $github_user ) ) {
+ $github_user = trim( readline( "Please provide the collaborator's Github username: " ) );
+ if ( empty( $github_user ) ) {
+ $github_user->writeln( "Missing collaborator's Github username (eg: --username=their_username)." );
+ exit;
+ }
+ }
+
+ $github_team = $input->getOption( 'github_team' );
+ if ( empty( $github_team ) || ! in_array($github_team, [self::ACCESS_1, self::ACCESS_2, self::ACCESS_3]) ) {
+ $github_team = trim( readline( sprintf("Please provide the collaborator's Github team. Values can be: %s, %s, or %s: ", self::ACCESS_1, self::ACCESS_2, self::ACCESS_3) ) );
+ if ( empty( $github_team ) || ! in_array($github_team, [self::ACCESS_1, self::ACCESS_2, self::ACCESS_3]) ) {
+ $output->writeln( 'Missing collaborator github_team (eg: --team='.self::ACCESS_1.').' );
+ exit;
+ }
+ }
+
+ // Start process
+ $this->onboard_github( $github_user, $github_team );
+
+ $output->writeln( 'All done!' );
+ }
+
+
+ private function onboard_github( $gh_username, $gh_team ) {
+ $this->output->writeln( "Granting access to our a8cteam51 organization..." );
+
+ // Associate Github username with Github Team
+ $team_put = $this->api_helper->call_github_api(
+ sprintf( 'orgs/%s/teams/%s/memberships/%s', GITHUB_API_OWNER, $gh_team, $gh_username ),
+ array(
+ 'role' => 'member'
+ ),
+ 'PUT'
+ );
+
+ if ( ! empty( $team_put->message ) ) {
+ $this->output->writeln( "Something went wrong. Github says: {$team_put->message}" );
+ } else {
+ $this->output->writeln( "The user '{$gh_username}' has been added to Team '{$gh_team}'!" );
+ }
+ }
+}
diff --git a/src/helpers/dry-helper.php b/src/helpers/dry-helper.php
new file mode 100644
index 00000000..299c8a59
--- /dev/null
+++ b/src/helpers/dry-helper.php
@@ -0,0 +1,42 @@
+ 'triage',
+ 'team_permission' => 'triage',
+ );
+ public $GH_ACCESS_2 = array(
+ 'team_slug' => 'deploy',
+ 'team_permission' => 'push',
+ );
+ public $GH_ACCESS_3 = array(
+ 'team_slug' => 'admin',
+ 'team_permission' => 'admin',
+ );
+
+ function __construct() {
+ $this->api_helper = new API_Helper();
+ }
+
+ public function populate_team_with_repos( $repo_names, $team_slug, $team_permission ) {
+ echo "Adding repos to team '{$team_slug}'. This might take a while...\n";
+ foreach( $repo_names as $repo_name ) {
+ $github_response = $this->api_helper->call_github_api(
+ sprintf( 'orgs/%s/teams/%s/repos/%s/%s', GITHUB_API_OWNER, $team_slug, GITHUB_API_OWNER, $repo_name ),
+ array(
+ 'permission' => $team_permission
+ ),
+ 'PUT'
+ );
+ if ( ! empty($github_response->message) ) {
+ echo "Something went wrong when adding the repo '{$repo_name}' to the team '{$team_slug}'. Message: {$github_response->message}\n";
+ }
+ }
+ }
+
+}