Skip to content
This repository was archived by the owner on Oct 16, 2024. It is now read-only.
Open
Show file tree
Hide file tree
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
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion load-application.php
Original file line number Diff line number Diff line change
Expand Up @@ -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();
10 changes: 10 additions & 0 deletions src/commands/create-repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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( '<error>You must pass a repository slug with --repo-slug.</error>' );
Expand Down Expand Up @@ -167,6 +169,14 @@ protected function execute( InputInterface $input, OutputInterface $output ) {
//exit;
}

// Adding repo to all required teams
// TODO: TEST
$output->writeln( "<info>Adding '{$slug}' to the corresponding Github Teams.</info>" );
$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;

Expand Down
61 changes: 61 additions & 0 deletions src/commands/github-repos-to-teams.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

namespace Team51\Command;

use Team51\Helper\API_Helper;
use Team51\Helper\DRY_Helper;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;


class Github_Team_Add_Repos extends Command {
protected static $defaultName = 'github-team-add-repos';
private $api_helper;
private $output;

protected function configure() {
$this
->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( "<comment>Pulling all repositories from our Github organization.</comment>" );
$repos = array();
$repos_page = 1;
$more_repos = true;

while( $more_repos ) {
$this->output->writeln( "<comment>...</comment>" );
$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( "<comment>{$total_repos} repositories will be added to each of our Github Teams.</comment>" );

// 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( "<comment>All done.</comment>" );
}
}
76 changes: 76 additions & 0 deletions src/commands/github-team-add-user.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

namespace Team51\Command;

use Team51\Helper\API_Helper;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class Github_Team_Add_User extends Command {
protected static $defaultName = 'github-team-add-user';
private $api_helper;
private $output;

const ACCESS_1 = 'triage';
const ACCESS_2 = 'deploy';
const ACCESS_3 = 'admin';


protected function configure() {
$this
->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( "<error>Missing collaborator's Github username (eg: --username=their_username).</error>" );
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( '<error>Missing collaborator github_team (eg: --team='.self::ACCESS_1.').</error>' );
exit;
}
}

// Start process
$this->onboard_github( $github_user, $github_team );

$output->writeln( '<info>All done!<info>' );
}


private function onboard_github( $gh_username, $gh_team ) {
$this->output->writeln( "<comment>Granting access to our a8cteam51 organization...</comment>" );

// 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( "<error>Something went wrong. Github says: {$team_put->message}</error>" );
} else {
$this->output->writeln( "<info>The user '{$gh_username}' has been added to Team '{$gh_team}'!</info>" );
}
}
}
42 changes: 42 additions & 0 deletions src/helpers/dry-helper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

namespace Team51\Helper;

class DRY_Helper {
private $api_helper;

// Github Access Levels
public $GH_ACCESS_1 = array(
'team_slug' => '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";
}
}
}

}