├── README.md ├── config └── github_updater.php ├── libraries └── Github_updater.php └── spark.info /README.md: -------------------------------------------------------------------------------- 1 | CodeIgniter GitHub Updater 2 | =============================== 3 | 4 | This library is meant to handle updates to remote CodeIgniter instances. These updates 5 | are tied to a GitHub repository. Any time the repository is updated you can run the 6 | update command of this library to have your CodeIgniter files updated to the current 7 | version of the repository. 8 | 9 | For more information check out my blog. 10 | 11 | http://jimdoescode.blogspot.com/2012/02/keep-your-ci-instances-up-to-date-with.html 12 | 13 | You can also see the test repo I use for performing remote updates. 14 | 15 | https://github.com/jimdoescode/Test-Auto-Updater 16 | 17 | Pay close attention to the welcome controller and the github_updater config file. 18 | 19 | The ideal application would have several separate instances hosted by different parties like a CMS. Using this library you can create an upgrade script that will occasionally check if there is a new version available and perform updates when there is. That way users will never need to FTP updated files to their servers in order to stay up with the current version of your CI app. 20 | 21 | Usage 22 | ------ 23 | Copy the files under your application directory. 24 | 25 | Edit the github_updater.php config file. 26 | 27 | Then load the library like this: 28 | 29 | $this->load->library('github_updater'); 30 | 31 | $success = $this->github_updater->update(); 32 | 33 | License 34 | ------- 35 | This library is licensed under the MIT license. 36 | 37 | -------------------------------------------------------------------------------- /config/github_updater.php: -------------------------------------------------------------------------------- 1 | ci =& get_instance(); 34 | $this->ci->load->config('github_updater'); 35 | } 36 | 37 | /** 38 | * Checks if the current version is up to date 39 | * 40 | * @return bool true if there is an update and false otherwise 41 | */ 42 | public function has_update() 43 | { 44 | $branches = json_decode($this->_connect(self::API_URL.$this->ci->config->item('github_user').'/'.$this->ci->config->item('github_repo').'/branches')); 45 | return $branches[0]->commit->sha !== $this->ci->config->item('current_commit'); 46 | } 47 | 48 | /** 49 | * If there is an update available get an array of all of the 50 | * commit messages between the versions 51 | * 52 | * @return array of the messages or false if no update 53 | */ 54 | public function get_update_comments() 55 | { 56 | $branches = json_decode($this->_connect(self::API_URL.$this->ci->config->item('github_user').'/'.$this->ci->config->item('github_repo').'/branches')); 57 | $hash = $branches[0]->commit->sha; 58 | if($hash !== $this->ci->config->item('current_commit')) 59 | { 60 | $messages = array(); 61 | $response = json_decode($this->_connect(self::API_URL.$this->ci->config->item('github_user').'/'.$this->ci->config->item('github_repo').'/compare/'.$this->ci->config->item('current_commit').'...'.$hash)); 62 | $commits = $response->commits; 63 | foreach($commits as $commit) 64 | $messages[] = $commit->commit->message; 65 | return $messages; 66 | } 67 | return false; 68 | } 69 | 70 | /** 71 | * Performs an update if one is available. 72 | * 73 | * @return bool true on success, false on failure 74 | */ 75 | public function update() 76 | { 77 | $branches = json_decode($this->_connect(self::API_URL.$this->ci->config->item('github_user').'/'.$this->ci->config->item('github_repo').'/branches')); 78 | $hash = $branches[0]->commit->sha; 79 | if($hash !== $this->ci->config->item('current_commit')) 80 | { 81 | $commits = json_decode($this->_connect(self::API_URL.$this->ci->config->item('github_user').'/'.$this->ci->config->item('github_repo').'/compare/'.$this->ci->config->item('current_commit').'...'.$hash)); 82 | $files = $commits->files; 83 | if($dir = $this->_get_and_extract($hash)) 84 | { 85 | //Loop through the list of changed files for this commit 86 | foreach($files as $file) 87 | { 88 | //If the file isn't in the ignored list then perform the update 89 | if(!$this->_is_ignored($file->filename)) 90 | { 91 | //If the status is removed then delete the file 92 | if($file->status === 'removed')unlink($file->filename); 93 | //Otherwise copy the file from the update. 94 | else copy($dir.'/'.$file->filename, $file->filename); 95 | } 96 | } 97 | //Clean up 98 | if($this->ci->config->item('clean_update_files')) 99 | { 100 | shell_exec("rm -rf {$dir}"); 101 | unlink("{$hash}.zip"); 102 | } 103 | //Update the current commit hash 104 | $this->_set_config_hash($hash); 105 | 106 | return true; 107 | } 108 | } 109 | return false; 110 | } 111 | 112 | private function _is_ignored($filename) 113 | { 114 | $ignored = $this->ci->config->item('ignored_files'); 115 | foreach($ignored as $ignore) 116 | if(strpos($filename, $ignore) !== false)return true; 117 | 118 | return false; 119 | } 120 | 121 | private function _set_config_hash($hash) 122 | { 123 | $lines = file(self::CONFIG_FILE, FILE_IGNORE_NEW_LINES); 124 | $count = count($lines); 125 | for($i=0; $i < $count; $i++) 126 | { 127 | $configline = '$config[\'current_commit\']'; 128 | if(strstr($lines[$i], $configline)) 129 | { 130 | $lines[$i] = $configline.' = \''.$hash.'\';'; 131 | $file = implode(PHP_EOL, $lines); 132 | $handle = @fopen(self::CONFIG_FILE, 'w'); 133 | fwrite($handle, $file); 134 | fclose($handle); 135 | return true; 136 | } 137 | } 138 | return false; 139 | } 140 | 141 | private function _get_and_extract($hash) 142 | { 143 | copy(self::GITHUB_URL.$this->ci->config->item('github_user').'/'.$this->ci->config->item('github_repo').'/zipball/'.$this->ci->config->item('github_branch'), "{$hash}.zip"); 144 | shell_exec("unzip {$hash}.zip"); 145 | $files = scandir('.'); 146 | foreach($files as $file) 147 | if(strpos($file, $this->ci->config->item('github_user').'-'.$this->ci->config->item('github_repo')) !== FALSE)return $file; 148 | 149 | return false; 150 | } 151 | 152 | private function _connect($url) 153 | { 154 | $ch = curl_init($url); 155 | curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC ) ; 156 | curl_setopt($ch, CURLOPT_SSLVERSION,3); 157 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 158 | curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); 159 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 160 | curl_setopt($ch, CURLINFO_HEADER_OUT, true); 161 | 162 | $response = curl_exec($ch); 163 | 164 | curl_close($ch); 165 | return $response; 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /spark.info: -------------------------------------------------------------------------------- 1 | name: github_updater 2 | version: 1.0.1 3 | compatibility: 2.0.3 4 | tags: ["github", "update", "remote update", "git"] 5 | --------------------------------------------------------------------------------