+$public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC4h6SZwJIaaETjb7XIntOfBFJRYaiaHFs43hMJV8y+jYU2hskayp/YxkxrmC02/9t8b8RbykgJHiE25PFzezvudcni69PNnI6rcZe73TxvrTsXgDx2t9tIIhNp2g3ABJyddQUudzIq+A5d6nLriOdROhS798HFtXf/4cjkc7GTeyblU2PSFuZUOM4eg7XYYueTe1Y5xVeFz6lH9LugR7CXOwfOQHmuy2v21R5/jgllSr6ougUXGz5WhsMYNn8ybTEhQoEbrO1OmS9P2VW95L/L/dnkNE3eJTmr1V9aQB1GL0MTFeoFhHnlRI+hq+GY03rI93EdPm1oAPYgH/oCebUp app@5vi98s-novolab-magweb-cvps.nodes.hypernode.io";
+$label = 'Byte: Novolab';
+ 'novolab-redstage-brand',
+ 'novolab-phoenix-navconnect',
+ 'novolab-bluejalappeno-tieredproducts',
+ 'novolab-trmmarketing-popupwidgets',
+ 'novolab-vbw-punchout2go',
+ 'module-aheadworks-searchautocomplete',
+ 'module-aheadworks-advancednewsletter',
+ 'module-amasty-stockstatus',
+ 'module-amasty-groupcat',
+ 'module-amasty-payrestriction',
+ 'module-amasty-shiprestriction',
+ 'module-vladimirpopov_webforms',
+ 'module-mageworx-filedownloads',
+ 'module-mageparts-restrictcustomer',
+ 'module-magebuzz-shoppinglist'
+// Detecting username for API authentication
+ echo "BitBucket Username: ";
+ $handle = fopen ("php://stdin",'');
+ $username = trim(fgets($handle));
+ $username = trim($argv[1]);
+// Detecting password for API authentication
+echo "BitBucket password for '$username': ";
+$handle = fopen ("php://stdin",'');
+$password = trim(fgets($handle));
+$key_pusher = new BitBucketDeploymentKeyPusher($username, $password);
+//var_dump($key_pusher->deployment_key_exists($public_key, 'novolab-redstage-brand'));
+//var_dump($key_pusher->deployment_key_exists('ddd', 'novolab-redstage-brand'));
+$key_pusher->push_key_to_repositories($public_key, $label, $repositories);
+//$key_pusher->delete_key_from_repositories($public_key, $repositories);
+class BitBucketDeploymentKeyPusher {
+ const INDIEGROUP_ACCOUNT = 'indiegroup';
+ private $username = '';
+ private $password = '';
+ public function __construct($username, $password){
+ $this->username = $username;
+ $this->password = $password;
+ public function push_key_to_repositories($public_key, $label, $repositories, $account = self::INDIEGROUP_ACCOUNT){
+ $data = array('key' => $public_key, 'label' => $label);
+ foreach($repositories as $repo) {
+ echo "Adding deployment key '$label' to '$repo'...\n";
+ if(!$this->deployment_key_exists($public_key, $repo, $account)){
+ $deployment_key_api_url = "https://bitbucket.org/api/1.0/repositories/$account/$repo/deploy-keys";
+ $add_deployment_key_context = $this->_get_bb_api_post_context($data);
+ // TODO Interpret result
+ $result = file_get_contents($deployment_key_api_url, false, $add_deployment_key_context);
+ echo "(Skipping this repo: the deployment key already exists!)\n";
+ public function delete_key_from_repositories($public_key, $repositories, $account = self::INDIEGROUP_ACCOUNT){
+ foreach($repositories as $repo) {
+ echo "Removing deployment key from '$repo'...\n";
+ $key_id = $this->get_key_id($public_key, $repo, $account);
+ $deployment_key_api_url = "https://bitbucket.org/api/1.0/repositories/$account/$repo/deploy-keys/$key_id";
+ $delete_deployment_key_context = $this->_get_bb_api_delete_context();
+ // TODO Interpret result
+ $result = file_get_contents($deployment_key_api_url, false, $delete_deployment_key_context);
+ echo "Removed deployment key with id '$key_id'.\n";
+ echo "(Skipping this repo: couldn't find deployment key!)\n";
+ public function deployment_key_exists($public_key, $repo, $account = self::INDIEGROUP_ACCOUNT){
+ $deployment_key_api_url = "https://bitbucket.org/api/1.0/repositories/$account/$repo/deploy-keys";
+ $get_deployment_key_context = $this->_get_bb_api_get_context();
+ $result = file_get_contents($deployment_key_api_url, false, $get_deployment_key_context);
+ $keys = json_decode($result);
+ foreach($keys as $key_data){
+ if($key_data->key == $public_key){
+ public function get_key_id($public_key, $repo, $account = self::INDIEGROUP_ACCOUNT){
+ $deployment_key_api_url = "https://bitbucket.org/api/1.0/repositories/$account/$repo/deploy-keys";
+ $get_deployment_key_context = $this->_get_bb_api_get_context();
+ $result = file_get_contents($deployment_key_api_url, false, $get_deployment_key_context);
+ $keys = json_decode($result);
+ foreach($keys as $key_data){
+ if($key_data->key == $public_key){
+ * @param string $username The BitBucket username.
+ * @param string $password The BitBucket password.
+ * @param array $data A keyed array containing the data for the POST request.
+ private function _get_bb_api_post_context($data){
+ "Content-type: application/x-www-form-urlencoded",
+ "Authorization: Basic " . base64_encode("$this->username:$this->password")
+ // use key 'http' even if you send the request to https://...
+ 'header' => implode("\r\n", $headers),
+ 'content' => http_build_query($data),
+ return stream_context_create($options);
+ * @param string $username The BitBucket username.
+ * @param string $password The BitBucket password.
+ private function _get_bb_api_get_context(){
+ return $this->_get_bb_api_generic_context('GET');
+ * @param string $username The BitBucket username.
+ * @param string $password The BitBucket password.
+ private function _get_bb_api_delete_context(){
+ return $this->_get_bb_api_generic_context('DELETE');
+ * @param string $username The BitBucket username.
+ * @param string $password The BitBucket password.
+ private function _get_bb_api_generic_context($request_type){
+ "Authorization: Basic " . base64_encode("$this->username:$this->password")
+ // use key 'http' even if you send the request to https://...
+ 'header' => implode("\r\n", $headers),
+ 'method' => $request_type,
+ return stream_context_create($options);