Skip to content

Instantly share code, notes, and snippets.

@AndreasStokholm
Forked from aronwoost/README.md
Created September 24, 2012 21:00
Show Gist options
  • Star 23 You must be signed in to star a gist
  • Fork 10 You must be signed in to fork a gist
  • Save AndreasStokholm/3778351 to your computer and use it in GitHub Desktop.
Save AndreasStokholm/3778351 to your computer and use it in GitHub Desktop.
Auto-deploy with php and github on an Ubuntu Amazon EC2 box

##Auto-deploy with php and github on an Ubuntu Amazon EC2 box

Fork from other gist Build auto-deploy with php and git(hub) on an EC2 AMAZON AMI instance - Covers a basic Ubuntu isntall

When ever it says www-data below, it's the user Apache runs under. So if your apache user is called something else, change it to that.

##Install git

sudo aptitude install git-core

##Create ssh directory since it doesn't exists by default on the Amazon EC2

sudo mkdir /var/www/.ssh
sudo chown -R www-data:www-data /var/www/.ssh/

##Generate key for apache user

sudo -Hu www-data ssh-keygen -t rsa  # chose "no passphrase"
sudo cat /var/www/.ssh/id_rsa.pub
# Add the key as a "deploy key" at https://github.com/you/myapp/admin

##Get the repo

cd /var/www/
sudo chown -R www-data:www-data site_dir
sudo -Hu www-data git clone git@github.com:yourUsername/yourApp.git html

##Setup the update script

sudo -Hu www-data nano html/deploy.php

Throw your deploy.php file up in the public accessible directory of your website, and send postmark.php with it there. - Remember to change the "settings" in deploy.php.

##Set up service hook in github

  1. Go to Repository Administration for your repo (http://github.com/username/repository/admin)
  2. Click Service Hooks, and you'll see a list of available services. Select Post-Receive URL.
  3. Enter the URL for your update script (e.g. http://yoursite.com/update.php) and click Update Settings.

##Sources

<?php
// Reject anyone who's not GitHub
if (!in_array($_SERVER['REMOTE_ADDR'], array('207.97.227.253', '50.57.128.197', '108.171.174.178'))) {
exit('Go away!');
}
require_once 'Class/postmark.php';
$postmark = new Postmark('postmark-app-key');
$postmark->setFrom('From you <you@domain.com>');
$postmark->addTo('to@you.com');
$postmark->addTo('to@somebody.else.com');
$postmark->setTag('Deployment');
$project_name = 'Project X';
$payload = json_decode($_POST['payload']);
$changes = $payload->commits;
$git_result = `git pull`;
if (strlen($git_result) == 20 || strstr($git_result, 'Updating')) {
$postmark->setSubject($project_name.' successfully deployed');
$htmlBody = '
<h1>'.$project_name.' successfully deployed</h1><br />
Date: '.date('d-m-Y H:i:s').'<br /><br />
The following changes was made:<br /><br />
<ul>
';
foreach ($changes as $change) {
$htmlBody .= '<li>'.$change->message.' ('.$change->committer->name.')
';
}
$htmlBody .= '</ul>';
$textBody = strip_tags($htmlBody);
$postmark->setBody($htmlBody, $textBody);
} else {
$postmark->setSubject($project_name.' failed to deploy');
$htmlBody = '
<h1>Git failed with the following response</h1><br /><br />
'.$git_result;
$textBody = strip_tags($htmlBody);
$postmark->setBody($htmlBody, $textBody);
}
$result = $postmark->send();
/**
* Copyright (c) 2012 Andreas Stokholm
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
<?php
/**
* File for Postmark class
*
* @author Andreas Stokholm
*
* See license in bottom of file.
*/
/**
* Class for handling interaction with Postmarkapp.com
*
* @author Andreas Stokholm
* @version v0.0.1
*/
class Postmark {
private $key;
private $mail = array(
'From' => '',
'To' => '',
'Cc' => '',
'Bcc' => '',
'Subject' => '',
'Tag' => '',
'HtmlBody' => '',
'TextBody' => '',
'ReplyTo' => '',
'Headers' => array(),
'Attachments' => array()
);
private $test_file = 'testmail.html'; // Default: 'testmail.html'
/**
* Constructor
*
* @param $postmark_key string
*
* @author Andreas Stokholm
* @since v0.0.1
*/
public function __construct($postmark_key) {
$this->key = $postmark_key;
}
/**
* Set sender mail
*
* This mail should be the one you set up in the Postmark interface.
*
* @param $from string
*
* @author Andreas Stokholm
* @since v0.0.1
*/
public function setFrom($from) {
$this->mail['From'] = $from;
if ($this->mail['ReplyTo'] == '') {
$this->mail['ReplyTo'] = $from;
}
}
/**
* Add delivery address
*
* Call this method as many times as you want to add recipients.
* Bear in mind that Postmark restricts mails to 20 recipients total.
*
* This method takes any kind of recipient form. It defaults to the "To" field,
* but can also add to "Cc" and "Bcc".
*
* Usage: $this->addTo('andreas@stokholm.me');
* Or: $this->addTo('andreas@stokholm.me', 'bcc');
*
* @param $to string
* @param $type string
*
* @author Andreas Stokholm
* @since v0.0.1
*/
public function addTo($email, $type = 'to') {
$kind = 'To';
if ($type == 'bcc') {
$kind = 'Bcc';
} elseif ($type == 'cc') {
$kind = 'Cc';
}
if ($this->mail[$kind] == '') {
$this->mail[$kind] = $email;
} else {
$this->mail[$kind] .= ', '.$email;
}
}
/**
* Set subject
*
* Sets the subject of the mail
*
* @param $subject string
*
* @author Andreas Stokholm
* @since v0.0.1
*/
public function setSubject($subject) {
$this->mail['Subject'] = $subject;
}
/**
* Set tag of mail
*
* @param $tag string
*
* @author Andreas Stokholm
* @since v0.0.1
*/
public function setTag($tag) {
$this->mail['Tag'] = $tag;
}
/**
* Sets body of mail
*
* @param $html string
* @param $text string
*
* @author Andreas Stokholm
* @since v0.0.1
*/
public function setBody($html = '', $text = '') {
if ($html != '') {
$this->mail['HtmlBody'] = utf8_encode($html);
}
if ($text != '') {
$this->mail['TextBody'] = utf8_encode($text);
}
}
/**
* Add header
*
* Adds a header to the mail. Call this method as many times as
* you have headers to add.
*
* @param $header string
* @param $value string
*
* @author Andreas Stokholm
* @since v0.0.1
*/
public function addHeader($header, $value) {
$this->mail['Headers'][] = array('Name' => $header, 'Value' => $value);
}
/**
* Attach a file to the mail
*
* This method can attach as many files as you want to the message.
* Keep in mind that Postmark restricts attachments to 10 MB total.
* If you attach 5 files, the total size can't be more than 10 MB.
*
* Make sure the $file_path is readable by PHP. Also, this can be
* a big request. You should only use this method on mails sent via
* background jobs.
*
* @param $file_name string
* @param $file_path string
*
* @return boolean
*
* @author Andreas Stokholm
* @since v0.0.1
*/
public function attachFile($file_name, $file_path) {
if ($file_contents = file_get_contents($file_path)) {
if ($attachment = base64_encode($file_contents)) {
$this->mail['Attachments'][] = array(
'Name' => $file_name,
'Content' => $attachment,
'ContentType' => 'application/octet-stream' // Always use octet-stream
);
return true;
}
return false;
}
return false;
}
/**
* Send email using Postmark
*
* This method actually sends the email. If the parameter $test is
* set to true, it will write to a file instead of sending with
* Postmark. It will still call Postmark, to verify the JSON.
*
* @param $test boolean
*
* @return JSON string
*
* @author Andreas Stokholm
* @since v0.0.1
*/
public function send($test = false) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.postmarkapp.com/email');
if ($test) {
$api_token = 'X-Postmark-Server-Token: POSTMARK_API_TEST';
} else {
$api_token = 'X-Postmark-Server-Token: '.$this->key;
}
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json', 'Content-Type: application/json', $api_token));
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($this->mail));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
if ($test) {
if ($test_output = fopen($this->test_file, 'w')) {
if (!fwrite($test_output, $this->mail['HtmlBody'])) {
return json_encode(array('Failed to write to test file. Is file writable?'));
}
fclose($test_output);
} else {
return json_encode(array('Failed to open test file. Is directory writable?'));
}
}
return $result;
}
}
/**
* Copyright (c) 2012 Andreas Stokholm
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
?>
@izazueta
Copy link

Hello, in the array of Github IP´s also add this: 50.57.231.61

Useful script, thanks.

@AndreasStokholm
Copy link
Author

I would not recommend adding the above IP to the script. According to GitHub, whitelisting IP's should be in the range 192.30.252.0/22.

Actually this script is going against GitHubs recommendations on how to do this. Please read Serivce Hook IP adresses for more information.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment