Skip to content

Commit 3116b48

Browse files
committed
Added ability to view the latest deployment log.
1 parent 5ff9ea6 commit 3116b48

File tree

15 files changed

+350
-102
lines changed

15 files changed

+350
-102
lines changed

.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,4 @@ TELEGRAM_BOT_API_KEY=
5252
TELEGRAM_BOT_USERNAME=
5353
TELEGRAM_BOT_WEBHOOK_TOKEN=
5454
TELEGRAM_BOT_DONATE_COMMAND=false
55+
TELEGRAM_INSTANT_VIEW_HASH=

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@
1414
Several years ago I have started to use Laravel Forge for deploying my and my clients' projects.
1515
I found that Laravel Forge couldn't send deployment notifications to Telegram messager but for me, Telegram is the number one messenger.
1616
That time I just wrote a simple bot with hardcoded chat id and webhook URL.
17+
1718
During my work, I realized that I need a more flexible solution and I designed and implemented the first version of this bot.
1819
The first version could only send deployment notifications.
1920
It just generated a webhook URL for you and then you had to add that URL manually to your Laravel Forge's site.
21+
2022
After release, I have started to work with a new client.
2123
This client has had a project where I haven't could to enable "Quick deploy".
2224
Because of that I had to go to the Laravel Forge website and hit the button "Deploy Now" whenever I needed to update the production.
@@ -85,7 +87,9 @@ We use [SemVer](http://semver.org) for versioning. For the versions available, s
8587

8688
## Authors
8789

88-
* [**Ivan Torgov**](https://itorgov.com) - *initial work*
90+
* [**Ivan Torgov**](https://itorgov.com)
91+
92+
See also the list of [contributors](https://github.com/itorgov/laravel-forge-bot/contributors) who participated in this project.
8993

9094
## Thanks
9195

app/Contracts/LaravelForgeContract.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,4 +147,14 @@ public function createWebhook(int $serverId, int $siteId, string $url): void;
147147
* @return void
148148
*/
149149
public function deleteWebhook(int $serverId, int $siteId, int $webhookId): void;
150+
151+
/**
152+
* Get the last deployment log of the site.
153+
*
154+
* @param int $serverId
155+
* @param int $siteId
156+
*
157+
* @return string
158+
*/
159+
public function getDeploymentLog(int $serverId, int $siteId): string;
150160
}

app/DeploymentLog.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
namespace App;
4+
5+
use GoldSpecDigital\LaravelEloquentUUID\Database\Eloquent\Uuid;
6+
use Illuminate\Database\Eloquent\Model;
7+
8+
class DeploymentLog extends Model
9+
{
10+
use Uuid;
11+
12+
/**
13+
* The "type" of the primary key ID.
14+
*
15+
* @var string
16+
*/
17+
protected $keyType = 'string';
18+
19+
/**
20+
* Indicates if the IDs are auto-incrementing.
21+
*
22+
* @var bool
23+
*/
24+
public $incrementing = false;
25+
26+
/**
27+
* The attributes that aren't mass assignable.
28+
*
29+
* @var array
30+
*/
31+
protected $guarded = [];
32+
33+
/**
34+
* Returns an URL to a page with this log using the Instant View feature of Telegram.
35+
*
36+
* @return string
37+
*/
38+
public function getUrlAttribute(): string
39+
{
40+
$query = http_build_query([
41+
'url' => route('deployment-logs.show', [$this]),
42+
'rhash' => config('services.telegram.instant_view.hash'),
43+
]);
44+
45+
return "https://t.me/iv?{$query}";
46+
}
47+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace App\Http\Controllers;
4+
5+
use App\DeploymentLog;
6+
use Illuminate\Contracts\Support\Renderable;
7+
8+
class DeploymentLogsController extends Controller
9+
{
10+
/**
11+
* Page with deployment log.
12+
*
13+
* @param DeploymentLog $deploymentLog
14+
*
15+
* @return Renderable
16+
*/
17+
public function show(DeploymentLog $deploymentLog): Renderable
18+
{
19+
return view('deployment-logs.show', [
20+
'deploymentLog' => $deploymentLog,
21+
]);
22+
}
23+
}

app/Integrations/Laravel/Forge/ThemsaidLaravelForge.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,4 +220,16 @@ public function deleteWebhook(int $serverId, int $siteId, int $webhookId): void
220220
throw new LaravelForgeException($e->getMessage());
221221
}
222222
}
223+
224+
/**
225+
* {@inheritdoc}
226+
*/
227+
public function getDeploymentLog(int $serverId, int $siteId): string
228+
{
229+
try {
230+
return $this->forge->siteDeploymentLog($serverId, $siteId);
231+
} catch (Exception $e) {
232+
throw new LaravelForgeException($e->getMessage());
233+
}
234+
}
223235
}

app/Integrations/Telegram/Menu/MenuManager.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22

33
namespace App\Integrations\Telegram\Menu;
44

5+
use App\DeploymentLog;
56
use App\Facades\LaravelForge;
67
use App\Integrations\Telegram\Dialogs\AskForChatIdDialog;
78
use App\Integrations\Telegram\Entities\CallbackQueryAnswer;
9+
use App\Integrations\Telegram\Entities\OutboundMessage;
810
use App\Integrations\Telegram\Menu\Screens\AddWebhookScreen;
911
use App\Integrations\Telegram\Menu\Screens\ServerScreen;
1012
use App\Integrations\Telegram\Menu\Screens\ServersScreen;
@@ -259,6 +261,24 @@ private function siteScreenAction(string $callbackId, string $callbackData): voi
259261

260262
break;
261263

264+
case SiteScreen::ACTION_DEPLOYMENT_LOG:
265+
$log = LaravelForge::setToken($this->menu->token)->getDeploymentLog($this->menu->server->id, $this->menu->site->id);
266+
267+
$deploymentLog = DeploymentLog::query()->create([
268+
'server_name' => $this->menu->server->name,
269+
'site_name' => $this->menu->site->name,
270+
'content' => $log,
271+
]);
272+
273+
CallbackQueryAnswer::make($callbackId, '↓ Got it! See the last message. ↓')->send();
274+
275+
OutboundMessage::make(
276+
$this->menu->user,
277+
"[Here]({$deploymentLog->url}) is your latest deployment log for {$deploymentLog->site_name} site."
278+
)->parseMode(OutboundMessage::PARSE_MODE_MARKDOWN)->send();
279+
280+
break;
281+
262282
case SiteScreen::ACTION_ADD_WEBHOOK:
263283
// To the "Add webhook" screen.
264284
$this->screens->screen(AddWebhookScreen::NAME)->show();

app/Integrations/Telegram/Menu/Screens/SiteScreen.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ class SiteScreen extends Screen
1313
public const NAME = 'site';
1414

1515
public const ACTION_DEPLOY = 'deploy';
16+
public const ACTION_DEPLOYMENT_LOG = 'deployment-log';
1617
public const ACTION_ADD_WEBHOOK = 'add-webhook';
1718

1819
/**
@@ -44,6 +45,8 @@ public function show(): void
4445
$keyboard = InlineKeyboard::make()
4546
->button(InlineKeyboardButton::make('🧱 Deploy Now')->callbackData($this->generateCallbackData(self::NAME, self::ACTION_DEPLOY)))
4647
->row()
48+
->button(InlineKeyboardButton::make('📝 Get latest deployment log')->callbackData($this->generateCallbackData(self::NAME, self::ACTION_DEPLOYMENT_LOG)))
49+
->row()
4750
->button(InlineKeyboardButton::make('➕ Add Notification Webhook')->callbackData($this->generateCallbackData(self::NAME, self::ACTION_ADD_WEBHOOK)));
4851

4952
$webhooks = LaravelForge::setToken($this->menu->token)->webhooks($this->menu->server->id, $this->menu->site->id);

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"clue/socks-react": "^1.0",
2929
"fideloper/proxy": "^4.2",
3030
"fruitcake/laravel-cors": "^1.0",
31+
"goldspecdigital/laravel-eloquent-uuid": "^7.0",
3132
"guzzlehttp/guzzle": "^6.3",
3233
"hashids/hashids": "^4.0",
3334
"irazasyed/telegram-bot-sdk": "dev-develop#5bacf81",

composer.lock

Lines changed: 60 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)