├── routes
└── web.php
├── src
├── Events
│ └── GitDeployed.php
├── GitDeployServiceProvider.php
├── views
│ └── email.blade.php
└── Http
│ └── GitDeployController.php
├── composer.json
├── LICENSE
├── config
└── gitdeploy.php
└── README.md
/routes/web.php:
--------------------------------------------------------------------------------
1 | commits = $commits;
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "orphans/git-deploy-laravel",
3 | "description": "Helps automate the deployment of projects onto servers by utilising Git web hooks.",
4 | "license": "MIT",
5 | "autoload": {
6 | "psr-4": {
7 | "Orphans\\GitDeploy\\": "src"
8 | }
9 | },
10 | "require": {
11 | "illuminate/support": "^5.5|^6.0|^7.0|^8.0"
12 | },
13 | "extra": {
14 | "laravel": {
15 | "providers": [
16 | "Orphans\\GitDeploy\\GitDeployServiceProvider"
17 | ]
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/GitDeployServiceProvider.php:
--------------------------------------------------------------------------------
1 | publishes([
17 | __dir__ . '/../config/gitdeploy.php' => config_path('gitdeploy.php')
18 | ], 'config');
19 | $this->loadRoutesFrom(__dir__ . '/../routes/web.php');
20 | $this->loadViewsFrom(__dir__ . '/views', 'gitdeploy');
21 |
22 | }
23 |
24 | /**
25 | * Register the application services.
26 | *
27 | * @return void
28 | */
29 | public function register()
30 | {
31 | $this->mergeConfigFrom(__dir__ . '/../config/gitdeploy.php', 'gitdeploy');
32 | $this->app->bind('git_deploy', function ($app) {
33 | return new GitDeploy;
34 | });
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Orphans
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/src/views/email.blade.php:
--------------------------------------------------------------------------------
1 |
2 |
{{ $git['repository']['name'] }} updated
3 |
The Git repository has just been updated by {{ $git['user_name'] }} via the web hook.
4 |
5 |
6 | | System user |
7 | {{ $server['user'] }} |
8 |
9 |
10 | | Command |
11 | {{ $server['cmd'] }} |
12 |
13 |
14 | | Response |
15 | {{ $server['response'] }} |
16 |
17 |
18 |
19 |
20 | | Repository |
21 | {{ $git['repository']['name'] }} {{ $git['repository']['description'] }} |
22 |
23 |
24 | | Ref |
25 | {{ $git['ref'] }} |
26 |
27 |
28 | | Before |
29 | {{ $git['before'] }} |
30 |
31 |
32 | | After |
33 | {{ $git['after'] }} |
34 |
35 |
36 | | URL |
37 | {{ $git['repository']['url'] }} |
38 |
39 |
40 | | Homepage |
41 | {{ $git['repository']['homepage'] }} |
42 |
43 |
44 |
Commit log
45 |
46 |
47 |
48 | | Date |
49 | Subject |
50 | Author |
51 | Commit |
52 |
53 |
54 | @foreach($git['commits'] as $commit)
55 |
56 |
57 | | {{ $commit['human_date'] }} |
58 | {{ $commit['human_subject'] }} |
59 | {{ $commit['author']['name'] }} |
60 | {{ $commit['human_id'] }} |
61 |
62 |
63 | @endforeach
64 |
65 |
66 |
--------------------------------------------------------------------------------
/config/gitdeploy.php:
--------------------------------------------------------------------------------
1 | 'Joe Bloggs', 'address' => 'email@example1.com'],
15 | | ['name' => 'Jane Doe', 'address' => 'email@example2.com'],
16 | | ...
17 | | ]
18 | |
19 | */
20 |
21 | 'email_recipients' => [],
22 |
23 | /*
24 | |--------------------------------------------------------------------------
25 | | Email sender
26 | |--------------------------------------------------------------------------
27 | |
28 | | The email address and name that notification emails will be sent from.
29 | | This will default to the sender in config(mail.from) if left null.
30 | |
31 | */
32 |
33 | 'email_sender' => ['address' => null, 'name' => null],
34 |
35 | /*
36 | |--------------------------------------------------------------------------
37 | | Email template
38 | |--------------------------------------------------------------------------
39 | |
40 | | We have a good email template but if you need to change the view, create your own email template and change it here.
41 | | Default is 'gitdeploy::email'
42 | |
43 | */
44 | 'email_template' => 'gitdeploy::email',
45 | /*
46 | |--------------------------------------------------------------------------
47 | | Repository path
48 | |--------------------------------------------------------------------------
49 | |
50 | | This the root path of the Git repository that will be pulled. If this
51 | | is left empty the script will try to determine the directory itself
52 | | but looking for the project's .env file it's nearby .git directory.
53 | |
54 | | No trailing slash
55 | |
56 | */
57 |
58 | 'repo_path' => '',
59 |
60 | /*
61 | |--------------------------------------------------------------------------
62 | | Allowed sources
63 | |--------------------------------------------------------------------------
64 | |
65 | | A request will be ignored unless it comes from an IP listed in this
66 | | array. Leave the array empty to allow all sources.
67 | |
68 | | This is useful for a little extra security if you run your own Git
69 | | repo server.
70 | |
71 | | Relies on the REMOTE_ADDR of the connecting client matching a value
72 | | in the array below. So if using IPv6 on both the server and the
73 | | notifing git server, then make sure to add it to the array. If your git
74 | | server listens on IPv4 and IPv6 it would be safest to add both.
75 | |
76 | | e.g.
77 | |
78 | | 'allowed_sources' => ['192.160.0.1', '::1'],
79 | |
80 | */
81 |
82 | 'allowed_sources' => [],
83 |
84 | /*
85 | |--------------------------------------------------------------------------
86 | | Remote name
87 | |--------------------------------------------------------------------------
88 | |
89 | | The name of the remote repository to pull the changes from
90 | |
91 | */
92 |
93 | 'remote' => 'origin',
94 |
95 | /*
96 | |--------------------------------------------------------------------------
97 | | Git binary path
98 | |--------------------------------------------------------------------------
99 | |
100 | | The full path to the system git binary. e.g. /usr/bin/git
101 | |
102 | | Leave blank to let the system detect using the current PATH variable
103 | |
104 | */
105 |
106 | 'git_path' => '',
107 |
108 | /*
109 | |--------------------------------------------------------------------------
110 | | Maintenance mode
111 | |--------------------------------------------------------------------------
112 | |
113 | | Allow the git hook to put the site into maintenance mode before doing
114 | | the pull from the remote server.
115 | |
116 | | After a successful pull the site will be switched back to normal
117 | | operations. This does leave a possibility of the site remaining in
118 | | maintenance mode should an error occur during the pull.
119 | |
120 | */
121 |
122 | 'maintenance_mode' => true,
123 |
124 | /*
125 | |--------------------------------------------------------------------------
126 | | Fire Event
127 | |--------------------------------------------------------------------------
128 | |
129 | | Allow the git hook to fire a event "GitDeployed" so that everybody can listen to that event.
130 | | See readme how to create a nice listener on that.
131 | |
132 | */
133 | 'fire_event' => true,
134 |
135 | /*
136 | |--------------------------------------------------------------------------
137 | | Secret signature
138 | |--------------------------------------------------------------------------
139 | |
140 | | Allow webhook requests to be signed with a secret signature.
141 | |
142 | | If 'secret' is set to true, Gitdeploy will deny requests where the
143 | | signature does not match. If set to false it will ignore any signature
144 | | headers it recieves.
145 | |
146 | | For Gitlab servers, you probably want the settings below:
147 | |
148 | | 'secret_type' => 'plain',
149 | | 'secret_header' => 'X-Gitlab-Token',
150 | |
151 | | For Github, use something like the below (untested):
152 | |
153 | | 'secret_type' => 'hmac',
154 | | 'secret_header' => 'X-Hub-Signature',
155 | */
156 |
157 | 'secret' => false,
158 |
159 | /**
160 | * plain|hmac
161 | */
162 | 'secret_type' => 'plain',
163 |
164 | /**
165 | * X-Gitlab-Token|X-Hub-Signature
166 | */
167 | 'secret_header' => 'X-Gitlab-Token',
168 |
169 | /**
170 | * The key you specified in the pushing client
171 | */
172 | 'secret_key' => '',
173 |
174 | ];
175 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Deployment of Laravel projects using Git webhooks
2 |
3 | git-deploy-laravel allows for automated deployment using webhook requests from your repository's server, and automatically pulls project code using the local Git binary.
4 |
5 | This should work out-of-the-box with Laravel 5.x using with webhooks from GitHub and GitLab servers.
6 |
7 | This is an internal tool to help with our common workflow pattern but please feel free to borrow, change and improve.
8 |
9 | ## Installation
10 |
11 |
12 | ### Step 1
13 |
14 | Add the following to your `composer.json` file then update your composer as normal:
15 |
16 | {
17 | "require" : {
18 | "orphans/git-deploy-laravel" : "dev-master"
19 | }
20 | }
21 |
22 | Or run:
23 |
24 | composer require orphans/git-deploy-laravel
25 |
26 | ### Step 2
27 |
28 | Add the _/git-deploy_ route to CSRF exceptions so your repo's host can send messages to your project.
29 |
30 |
31 | In file in `app/Http/Middleware/VerifyCsrfToken.php` add:
32 |
33 | protected $except = [
34 | 'git-deploy',
35 | ];
36 |
37 | ### Step 3 Optional
38 | In case you need additional action after a successful commit, you can add you own Event Listener.
39 | For example you can write your own update script to run migrations etc.
40 |
41 | **1)** Create a Listener to perform action when a git deployment is done.
42 | Open the `App/Listeners` directory (or create it if it doesn't exist). Now create a new file and call it `GitDeployedListener.php`. Paste in this code:
43 |
44 | ```php
45 | [
90 | \App\Listeners\GitDeployedListener::class
91 | ]
92 | ];
93 |
94 | // ...
95 | ```
96 |
97 |
98 | ## Usage
99 |
100 | Add a webhook for http://your.website.url/git-deploy to your project in GitHub/GitLab and this package will take care of the rest. The webhook should fire on push-events.
101 |
102 | Your website will automatically receive POST messages from the repo manager and perform a Git pull.
103 |
104 | ## Configuration
105 |
106 | In most cases the package will find the correct Git repository and Git executable but we advise publishing our config anyway because it will let you enable extra security options and email notifications.
107 |
108 | To add custom configuration run:
109 |
110 | php artisan vendor:publish --provider="Orphans\GitDeploy\GitDeployServiceProvider"
111 |
112 | Then edit `/config/gitdeploy.php` to suit your needs.
113 |
114 | ```php
115 | 'Joe Bloggs', 'address' => 'email@example1.com'],
129 | | ['name' => 'Jane Doe', 'address' => 'email@example2.com'],
130 | | ...
131 | | ]
132 | |
133 | */
134 |
135 | 'email_recipients' => [],
136 |
137 | /*
138 | |--------------------------------------------------------------------------
139 | | Email sender
140 | |--------------------------------------------------------------------------
141 | |
142 | | The email address and name that notification emails will be sent from.
143 | | This will default to the sender in config(mail.from) if left null.
144 | |
145 | */
146 |
147 | 'email_sender' => ['address' => null, 'name' => null],
148 |
149 | /*
150 | |--------------------------------------------------------------------------
151 | | Repository path
152 | |--------------------------------------------------------------------------
153 | |
154 | | This the root path of the Git repository that will be pulled. If this
155 | | is left empty the script will try to determine the directory itself
156 | | but looking for the project's .env file it's nearby .git directory.
157 | |
158 | | No trailing slash
159 | |
160 | */
161 |
162 | 'repo_path' => '',
163 |
164 | /*
165 | |--------------------------------------------------------------------------
166 | | Allowed sources
167 | |--------------------------------------------------------------------------
168 | |
169 | | A request will be ignored unless it comes from an IP listed in this
170 | | array. Leave the array empty to allow all sources.
171 | |
172 | | This is useful for a little extra security if you run your own Git
173 | | repo server.
174 | |
175 | | Relies on the REMOTE_ADDR of the connecting client matching a value
176 | | in the array below. So if using IPv6 on both the server and the
177 | | notifing git server, then make sure to add it to the array. If your git
178 | | server listens on IPv4 and IPv6 it would be safest to add both.
179 | |
180 | | e.g.
181 | |
182 | | 'allowed_sources' => ['192.160.0.1', '::1'],
183 | |
184 | */
185 |
186 | 'allowed_sources' => [],
187 |
188 | /*
189 | |--------------------------------------------------------------------------
190 | | Remote name
191 | |--------------------------------------------------------------------------
192 | |
193 | | The name of the remote repository to pull the changes from
194 | |
195 | */
196 |
197 | 'remote' => 'origin',
198 |
199 | /*
200 | |--------------------------------------------------------------------------
201 | | Git binary path
202 | |--------------------------------------------------------------------------
203 | |
204 | | The full path to the system git binary. e.g. /usr/bin/git
205 | |
206 | | Leave blank to let the system detect using the current PATH variable
207 | |
208 | */
209 |
210 | 'git_path' => '',
211 |
212 | /*
213 | |--------------------------------------------------------------------------
214 | | Maintenance mode
215 | |--------------------------------------------------------------------------
216 | |
217 | | Allow the git hook to put the site into maintenance mode before doing
218 | | the pull from the remote server.
219 | |
220 | | After a successful pull the site will be switched back to normal
221 | | operations. This does leave a possibility of the site remaining in
222 | | maintenance mode should an error occur during the pull.
223 | |
224 | */
225 |
226 | 'maintenance_mode' => true,
227 |
228 | /*
229 | |--------------------------------------------------------------------------
230 | | Fire Event
231 | |--------------------------------------------------------------------------
232 | |
233 | | Allow the git hook to fire a event "GitDeployed" so that everybody can listen to that event.
234 | | See readme how to create a nice listener on that.
235 | |
236 | */
237 | 'fire_event' => true,
238 |
239 | /*
240 | |--------------------------------------------------------------------------
241 | | Secret signature
242 | |--------------------------------------------------------------------------
243 | |
244 | | Allow webhook requests to be signed with a secret signature.
245 | |
246 | | If 'secret' is set to true, Gitdeploy will deny requests where the
247 | | signature does not match. If set to false it will ignore any signature
248 | | headers it recieves.
249 | |
250 | | For Gitlab servers, you probably want the settings below:
251 | |
252 | | 'secret_type' => 'plain',
253 | | 'secret_header' => 'X-Gitlab-Token',
254 | |
255 | | For Github, use something like the below (untested):
256 | |
257 | | 'secret_type' => 'hmac',
258 | | 'secret_header' => 'X-Hub-Signature',
259 | */
260 |
261 | 'secret' => false,
262 |
263 | /**
264 | * plain|hmac
265 | */
266 | 'secret_type' => 'plain',
267 |
268 | /**
269 | * X-Gitlab-Token|X-Hub-Signature
270 | */
271 | 'secret_header' => 'X-Gitlab-Token',
272 |
273 | /**
274 | * The key you specified in the pushing client
275 | */
276 | 'secret_key' => '',
277 |
278 | ];
279 |
280 | ```
281 |
282 | ## Future Plans
283 |
284 | * Email report on code conflicts that prevent a pull
285 | * Support for performing `composer install` after deployment
286 | * Support for restarting laravel queues after deployment with `artisan queue:restart`
287 | * Support for running custom artisan commands after successful pulls
288 |
--------------------------------------------------------------------------------
/src/Http/GitDeployController.php:
--------------------------------------------------------------------------------
1 | pushHandler(new StreamHandler(storage_path('logs/gitdeploy.log'), Logger::WARNING));
26 |
27 | $git_path = !empty(config('gitdeploy.git_path')) ? config('gitdeploy.git_path') : 'git';
28 | $git_remote = !empty(config('gitdeploy.remote')) ? config('gitdeploy.remote') : 'origin';
29 |
30 | // Limit to known servers
31 | if (!empty(config('gitdeploy.allowed_sources'))) {
32 |
33 | $remote_ip = $this->formatIPAddress($_SERVER['REMOTE_ADDR']);
34 | $allowed_sources = array_map([$this, 'formatIPAddress'], config('gitdeploy.allowed_sources'));
35 |
36 | if (!in_array($remote_ip, $allowed_sources)) {
37 | $log->addError('Request must come from an approved IP');
38 | return Response::json([
39 | 'success' => false,
40 | 'message' => 'Request must come from an approved IP',
41 | ], 401);
42 | }
43 | }
44 |
45 | // Collect the posted data
46 | $postdata = json_decode($request->getContent(), TRUE);
47 | if (empty($postdata)) {
48 | $log->addError('Web hook data does not look valid');
49 | return Response::json([
50 | 'success' => false,
51 | 'message' => 'Web hook data does not look valid',
52 | ], 500);
53 | }
54 |
55 | // Check the config's directory
56 | $repo_dir = config('gitdeploy.repo_path');
57 | if (!empty($repo_dir) && !file_exists($repo_dir.'/.git/config')) {
58 | $log->addError('Invalid repo path in config');
59 | return Response::json([
60 | 'success' => false,
61 | 'message' => 'Invalid repo path in config',
62 | ], 500);
63 | }
64 |
65 | // Try to determine Laravel's directory going up paths until we find a .env
66 | if (empty($repo_dir)) {
67 | $checked[] = $repo_dir;
68 | $repo_dir = __DIR__;
69 | do {
70 | $repo_dir = dirname($repo_dir);
71 | } while ($repo_dir !== '/' && !file_exists($repo_dir.'/.env'));
72 | }
73 |
74 | // This is not necessarily the repo's root so go up more paths if necessary
75 | if ($repo_dir !== '/') {
76 | while ($repo_dir !== '/' && !file_exists($repo_dir.'/.git/config')) {
77 | $repo_dir = dirname($repo_dir);
78 | }
79 | }
80 |
81 | // So, do we have something valid?
82 | if ($repo_dir === '/' || !file_exists($repo_dir.'/.git/config')) {
83 | $log->addError('Could not determine the repo path');
84 | return Response::json([
85 | 'success' => false,
86 | 'message' => 'Could not determine the repo path',
87 | ], 500);
88 | }
89 |
90 | // Check signatures
91 | if (!empty(config('gitdeploy.secret'))) {
92 | $header = config('gitdeploy.secret_header');
93 | $header_data = $request->header($header);
94 |
95 | /**
96 | * Check for valid header
97 | */
98 | if (!$header_data) {
99 | $log->addError('Could not find header with name ' . $header);
100 | return Response::json([
101 | 'success' => false,
102 | 'message' => 'Could not find header with name ' . $header,
103 | ], 401);
104 | }
105 |
106 | /**
107 | * Sanity check for key
108 | */
109 | if (empty(config('gitdeploy.secret_key'))) {
110 | $log->addError('Secret was set to true but no secret_key specified in config');
111 | return Response::json([
112 | 'success' => false,
113 | 'message' => 'Secret was set to true but no secret_key specified in config',
114 | ], 500);
115 | }
116 |
117 | /**
118 | * Check plain secrets (Gitlab)
119 | */
120 | if (config('gitdeploy.secret_type') == 'plain') {
121 | if ($header_data !== config('gitdeploy.secret_key')) {
122 | $log->addError('Secret did not match');
123 | return Response::json([
124 | 'success' => false,
125 | 'message' => 'Secret did not match',
126 | ], 401);
127 | }
128 | }
129 |
130 | /**
131 | * Check hmac secrets (Github)
132 | */
133 | else if (config('gitdeploy.secret_type') == 'mac') {
134 | if (!hash_equals('sha1=' . hash_hmac('sha1', $request->getContent(), config('gitdeploy.secret')))){
135 | $log->addError('Secret did not match');
136 | return Response::json([
137 | 'success' => false,
138 | 'message' => 'Secret did not match',
139 | ], 401);
140 | }
141 | }
142 |
143 | /**
144 | * Catch all for anything odd in config
145 | */
146 | else {
147 | $log->addError('Unsupported secret type');
148 | return Response::json([
149 | 'success' => false,
150 | 'message' => 'Unsupported secret type',
151 | ], 500);
152 | }
153 |
154 | // If we get this far then the secret matched, lets go ahead!
155 | }
156 |
157 | // Get current branch this repository is on
158 | $cmd = escapeshellcmd($git_path) . ' --git-dir=' . escapeshellarg($repo_dir . '/.git') . ' --work-tree=' . escapeshellarg($repo_dir) . ' rev-parse --abbrev-ref HEAD';
159 | $current_branch = trim(exec($cmd)); //Alternativly shell_exec
160 |
161 | // Get branch this webhook is for
162 | $pushed_branch = explode('/', $postdata['ref']);
163 | $pushed_branch = trim($pushed_branch[2]);
164 |
165 | // If the refs don't matchthis branch, then no need to do a git pull
166 | if ($current_branch !== $pushed_branch){
167 | $log->addWarning('Pushed refs do not match current branch');
168 | return Response::json([
169 | 'success' => false,
170 | 'message' => 'Pushed refs do not match current branch',
171 | ], 500);
172 | }
173 |
174 | // At this point we're happy everything is OK to pull, lets put Laravel into Maintenance mode.
175 | if (!empty(config('gitdeploy.maintenance_mode'))) {
176 | Log::info('Gitdeploy: putting site into maintenance mode');
177 | Artisan::call('down');
178 | }
179 |
180 | // git pull
181 | Log::info('Gitdeploy: Pulling latest code on to server');
182 | $cmd = escapeshellcmd($git_path) . ' --git-dir=' . escapeshellarg($repo_dir . '/.git') . ' --work-tree=' . escapeshellarg($repo_dir) . ' pull ' . escapeshellarg($git_remote) . ' ' . escapeshellarg($current_branch) . ' > ' . escapeshellarg($repo_dir . '/storage/logs/gitdeploy.log');
183 |
184 | $server_response = [
185 | 'cmd' => $cmd,
186 | 'user' => shell_exec('whoami'),
187 | 'response' => shell_exec($cmd),
188 | ];
189 |
190 | // Put site back up and end maintenance mode
191 | if (!empty(config('gitdeploy.maintenance_mode'))) {
192 | Artisan::call('up');
193 | Log::info('Gitdeploy: taking site out of maintenance mode');
194 | }
195 |
196 | // Fire Event that git were deployed
197 | if (!empty(config('gitdeploy.fire_event'))) {
198 | event(new GitDeployed($postdata['commits']));
199 | Log::debug('Gitdeploy: Event GitDeployed fired');
200 | }
201 |
202 | if (!empty(config('gitdeploy.email_recipients'))) {
203 |
204 | // Humanise the commit log
205 | foreach ($postdata['commits'] as $commit_key => $commit) {
206 |
207 | // Split message into subject + description (Assumes Git's recommended standard where first line is the main summary)
208 | $subject = strtok($commit['message'], "\n");
209 | $description = '';
210 |
211 | // Beautify date
212 | $date = new \DateTime($commit['timestamp']);
213 | $date_str = $date->format('d/m/Y, g:ia');
214 |
215 | $postdata['commits'][$commit_key]['human_id'] = substr($commit['id'], 0, 9);
216 | $postdata['commits'][$commit_key]['human_subject'] = $subject;
217 | $postdata['commits'][$commit_key]['human_description'] = $description;
218 | $postdata['commits'][$commit_key]['human_date'] = $date_str;
219 | }
220 |
221 | // Standardise formats for Gitlab / Github payload differences
222 | if (isset($postdata['pusher']) && !empty($postdata['pusher'])) {
223 | $postdata['user_name'] = $postdata['pusher']['name'];
224 | $postdata['user_email'] = $postdata['pusher']['email'];
225 | }
226 |
227 | // Use package's own sender or the project default?
228 | $addressdata['sender_name'] = config('mail.from.name');
229 | $addressdata['sender_address'] = config('mail.from.address');
230 | if (config('gitdeploy.email_sender.address') !== null) {
231 | $addressdata['sender_name'] = config('gitdeploy.email_sender.name');
232 | $addressdata['sender_address'] = config('gitdeploy.email_sender.address');
233 | }
234 |
235 | // Recipients
236 | $addressdata['recipients'] = config('gitdeploy.email_recipients');
237 |
238 | // Template
239 | $emailTemplate = config('gitdeploy.email_template', 'gitdeploy::email');
240 |
241 | // Todo: Put Mail send into queue to improve performance
242 | \Mail::send($emailTemplate , [ 'server' => $server_response, 'git' => $postdata ], function($message) use ($postdata, $addressdata) {
243 | $message->from($addressdata['sender_address'], $addressdata['sender_name']);
244 | foreach ($addressdata['recipients'] as $recipient) {
245 | $message->to($recipient['address'], $recipient['name']);
246 | }
247 | $message->subject('Repo: ' . $postdata['repository']['name'] . ' updated');
248 | });
249 |
250 | }
251 |
252 | return Response::json(true);
253 | }
254 |
255 |
256 | /**
257 | * Make sure we're comparing like for like IP address formats.
258 | * Since IPv6 can be supplied in short hand or long hand formats.
259 | *
260 | * e.g. ::1 is equalvent to 0000:0000:0000:0000:0000:0000:0000:0001
261 | *
262 | * @param string $ip Input IP address to be formatted
263 | * @return string Formatted IP address
264 | */
265 | private function formatIPAddress(string $ip) {
266 | return inet_ntop(inet_pton($ip));
267 | }
268 |
269 | }
270 |
--------------------------------------------------------------------------------