Skip to content

Commit 9be9323

Browse files
Merge pull request #30 from stackkit/3.x
3.x
2 parents ee58ff9 + ebb288e commit 9be9323

35 files changed

+578
-355
lines changed

.github/workflows/run-tests.yml

+6-15
Original file line numberDiff line numberDiff line change
@@ -63,20 +63,11 @@ jobs:
6363
strategy:
6464
matrix:
6565
payload:
66-
- { laravel: '10.*', php: '8.3', 'testbench': '8.*'}
67-
- { laravel: '10.*', php: '8.2', 'testbench': '8.*'}
68-
- { laravel: '10.*', php: '8.1', 'testbench': '8.*'}
69-
- { laravel: '9.*', php: '8.3', 'testbench': '7.*'}
70-
- { laravel: '9.*', php: '8.2', 'testbench': '7.*'}
71-
- { laravel: '9.*', php: '8.1', 'testbench': '7.*'}
72-
- { laravel: '9.*', php: '8.0', 'testbench': '7.*'}
73-
- { laravel: '8.*', php: '8.1', 'testbench': '6.*'}
74-
- { laravel: '8.*', php: '8.0', 'testbench': '6.*'}
75-
- { laravel: '8.*', php: '7.4', 'testbench': '6.*'}
76-
- { laravel: '7.*', php: '8.0', 'testbench': '5.*' }
77-
- { laravel: '7.*', php: '7.4', 'testbench': '5.*' }
78-
- { laravel: '6.*', php: '8.0', 'testbench': '4.*' }
79-
- { laravel: '6.*', php: '7.4', 'testbench': '4.*' }
66+
- { laravel: '11.*', php: '8.3', 'testbench': '9.*', collision: '8.*'}
67+
- { laravel: '11.*', php: '8.2', 'testbench': '9.*', collision: '8.*'}
68+
- { laravel: '10.*', php: '8.3', 'testbench': '8.*', collision: '7.*'}
69+
- { laravel: '10.*', php: '8.2', 'testbench': '8.*', collision: '7.*'}
70+
- { laravel: '10.*', php: '8.1', 'testbench': '8.*', collision: '7.*'}
8071

8172
name: PHP ${{ matrix.payload.php }} - Laravel ${{ matrix.payload.laravel }}
8273

@@ -95,7 +86,7 @@ jobs:
9586

9687
- name: Install dependencies
9788
run: |
98-
composer require "laravel/framework:${{ matrix.payload.laravel }}" "orchestra/testbench:${{ matrix.payload.testbench }}" --no-interaction --no-update
89+
composer require "laravel/framework:${{ matrix.payload.laravel }}" "orchestra/testbench:${{ matrix.payload.testbench }}" "nunomaduro/collision:${{ matrix.payload.collision }}" --no-interaction --no-update
9990
composer update --prefer-stable --prefer-dist --no-interaction
10091
- name: Execute tests
10192
run: composer test

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ composer.lock
33
.idea/
44
.DS_Store
55
.phpunit.result.cache
6+
.phpunit.cache/

README.md

+153-83
Original file line numberDiff line numberDiff line change
@@ -11,70 +11,96 @@
1111

1212
This package allows you to use Google Cloud Scheduler to schedule Laravel commands.
1313

14-
It only supports Artisan commands at this time due to security concerns.
15-
1614
# How it works
1715

1816
Cloud Scheduler will make HTTP calls to your application. This package adds an endpoint to your application that accepts these HTTP calls with their payload (an Artisan command) and execute them.
1917

20-
#### withoutOverlapping, before, after, onSuccess, thenPing, etc
18+
There are two ways to schedule commands using this package:
2119

22-
All these features are supported. This package scans your console kernel (`app/Console/Kernel.php`) to see if the scheduled command in Cloud Scheduler is also scheduled in the console kernel, If it is, it will respect all configured events/hooks associated with the command. (such as withoutOverlapping)
20+
<details>
21+
<summary>1. Schedule the `schedule:run` command</summary>
2322

24-
# Requirements
23+
This is the easiest way to use this package. You can schedule the `schedule:run` command to run every minute.
24+
</details>
25+
26+
<details>
27+
<summary>2. Schedule commands separately</summary>
28+
29+
If your application does not have commands that should run every minute, you may choose to schedule them individually.
30+
31+
If the command uses `withoutOverlapping`, `before`, `after`, `onSuccess`, `thenPing`, etc, this package will respect those settings, as long as the command is also scheduled in the console kernel.
32+
33+
For example, let's say we have to generate a report every day at 3:00 AM. We can schedule the `reports:generate` command to run at 3:00 AM using Cloud Scheduler. After the report is generated, OhDear should be pinged.
2534

26-
This package requires Laravel 6 or higher.
35+
Firstly, schedule the command in Cloud Tasks:
2736

28-
Please check the table below for supported Laravel and PHP versions:
37+
<img src="/schedule-command-example.png">
38+
39+
Then, schedule the command in the console kernel:
40+
41+
```php
42+
public function schedule(Schedule $schedule)
43+
{
44+
$schedule->command('report:generate')
45+
->thenPing('https://ohdear.app/ping');
46+
}
47+
```
2948

30-
|Laravel Version| PHP Version |
31-
|---|---|
32-
| 6.x | 7.4 or 8.0
33-
| 7.x | 7.4 or 8.0
34-
| 8.x | 7.4 or 8.0
35-
| 9.x | 8.0 or 8.1 or 8.2 or 8.3
36-
| 10.x | 8.1 or 8.2 or 8.3
49+
The package will pick up on the scheduled settings and ping OhDear after the command has run.
50+
</details>
51+
52+
# Requirements
53+
54+
This package requires Laravel 10 or 11.
3755

3856
# Installation
3957

40-
(1) Require the package using Composer
58+
1 - Require the package using Composer
4159

4260
```bash
4361
composer require stackkit/laravel-google-cloud-scheduler
4462
```
4563

46-
(2) Define the `STACKKIT_CLOUD_SCHEDULER_APP_URL` environment variable. This should be the URL defined in the `URL` field of your Cloud Scheduler job.
64+
2 - Define environment variables
4765

48-
```
49-
STACKKIT_CLOUD_SCHEDULER_APP_URL=https://yourdomainname.com/cloud-scheduler-job
66+
`CLOUD_SCHEDULER_APP_URL` - This should be the URL defined in the `URL` field of your Cloud Scheduler job.
67+
68+
`CLOUD_SCHEDULER_SERVICE_ACCOUNT` - The e-mail address of the service account invocating the task.
69+
70+
Optionally, you may publish the configuration file:
71+
72+
```bash
73+
php artisan vendor:publish --tag-cloud-scheduler-config
5074
```
5175

52-
(3) Optional: whitelist route for maintenance mode
76+
3 - Ensure PHP executable is in open_basedir. This is required for the package to run Artisan commands.
5377

54-
This step is optional, but highly recommended. To allow jobs to keep running if the application is down (`php artisan down`) you must modify the `PreventRequestsDuringMaintenance` middleware:
78+
How to find the executable:
5579

56-
```diff
57-
<?php
80+
```php
81+
php artisan tinker --execute="(new Symfony\\Component\\Process\\PhpExecutableFinder())->find()"
82+
```
5883

59-
namespace App\Http\Middleware;
84+
4 - Optional, but highly recommended: server configuration
6085

61-
use Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance as Middleware;
86+
Since Artisan commands are now invoked via an HTTP request, you might encounter issues with timeouts. Here's how to adjust them:
6287

63-
class PreventRequestsDuringMaintenance extends Middleware
64-
{
65-
/**
66-
* The URIs that should be reachable while maintenance mode is enabled.
67-
*
68-
* @var array
69-
*/
70-
protected $except = [
71-
+ '/cloud-scheduler-job',
72-
];
88+
```nginx
89+
server {
90+
# other server configuration ...
91+
92+
location /cloud-scheduler-job {
93+
proxy_connect_timeout 600s;
94+
proxy_read_timeout 600s;
95+
fastcgi_read_timeout 600s;
96+
}
97+
98+
# other locations and server configuration ...
7399
}
74100
75101
```
76102

77-
(4) Optional: set application `RUNNING_IN_CONSOLE` (highly recommended)
103+
5 - Optional, but highly recommended: set application `RUNNING_IN_CONSOLE`
78104

79105
Some Laravel service providers only register their commands if the application is being accessed through the command line (Artisan). Because we are calling Laravel scheduler from a HTTP call, that means some commands may never register, such as the Laravel Scout command:
80106

@@ -101,73 +127,117 @@ public function boot()
101127
}
102128
```
103129

104-
To circumvent this, please add the following to `public/index.php`
130+
To circumvent this, please add the following to `bootstrap/app.php`
105131

106-
```diff
107-
/*
108-
|--------------------------------------------------------------------------
109-
| Check If Application Is Under Maintenance
110-
|--------------------------------------------------------------------------
111-
|
112-
| If the application is maintenance / demo mode via the "down" command we
113-
| will require this file so that any prerendered template can be shown
114-
| instead of starting the framework, which could cause an exception.
115-
|
116-
*/
132+
<details>
133+
<summary>Laravel 11</summary>
134+
135+
```php
136+
<?php
137+
138+
use Illuminate\Foundation\Application;
139+
use Illuminate\Foundation\Configuration\Exceptions;
140+
use Illuminate\Foundation\Configuration\Middleware;
117141

118-
if (file_exists(__DIR__.'/../storage/framework/maintenance.php')) {
119-
require __DIR__.'/../storage/framework/maintenance.php';
120-
}
121-
+
122-
+ /*
123-
+ |--------------------------------------------------------------------------
124-
+ | Manually Set Running In Console for Google Cloud Scheduler
125-
+ |--------------------------------------------------------------------------
126-
+ |
127-
+ | Some service providers only register their commands if the application
128-
+ | is running from the console. Since we are calling Cloud Scheduler
129-
+ | from the browser we must manually trick the application into
130-
+ | thinking that it is being run from the command line.
131-
+ |
132-
+ */
133-
+
134142
+ if (($_SERVER['REQUEST_URI'] ?? '') === '/cloud-scheduler-job') {
135143
+ $_ENV['APP_RUNNING_IN_CONSOLE'] = true;
136144
+ }
137-
+
138-
/*
139-
|--------------------------------------------------------------------------
140-
| Register The Auto Loader
141-
|--------------------------------------------------------------------------
142-
|
143-
| Composer provides a convenient, automatically generated class loader for
144-
| this application. We just need to utilize it! We'll simply require it
145-
| into the script here so we don't need to manually load our classes.
146-
|
147-
*/
148145

149-
require __DIR__.'/../vendor/autoload.php';
146+
return Application::configure(basePath: dirname(__DIR__))
147+
->withRouting(
148+
web: __DIR__.'/../routes/web.php',
149+
commands: __DIR__.'/../routes/console.php',
150+
health: '/up',
151+
)
152+
->withMiddleware(function (Middleware $middleware) {
153+
//
154+
})
155+
->withExceptions(function (Exceptions $exceptions) {
156+
//
157+
})->create();
158+
150159
```
160+
</details>
151161

152-
Copy the code here:
162+
<details>
163+
<summary>Laravel 10</summary>
153164

154165
```php
166+
<?php
167+
155168
/*
156169
|--------------------------------------------------------------------------
157-
| Manually Set Running In Console for Google Cloud Scheduler
170+
| Create The Application
158171
|--------------------------------------------------------------------------
159172
|
160-
| Some service providers only register their commands if the application
161-
| is running from the console. Since we are calling Cloud Scheduler
162-
| from the browser we must manually trick the application into
163-
| thinking that it is being run from the command line.
173+
| The first thing we will do is create a new Laravel application instance
174+
| which serves as the "glue" for all the components of Laravel, and is
175+
| the IoC container for the system binding all of the various parts.
164176
|
165177
*/
166178

167-
if (($_SERVER['REQUEST_URI'] ?? '') === '/cloud-scheduler-job') {
168-
$_ENV['APP_RUNNING_IN_CONSOLE'] = true;
179+
$app = new Illuminate\Foundation\Application(
180+
$_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
181+
);
182+
183+
+ if (($_SERVER['REQUEST_URI'] ?? '') === '/cloud-scheduler-job') {
184+
+ $_ENV['APP_RUNNING_IN_CONSOLE'] = true;
185+
+ }
186+
```
187+
</details>
188+
189+
6 - Optional: whitelist route for maintenance mode
190+
191+
If you want to allow jobs to keep running if the application is down (`php artisan down`), update the following:
192+
193+
<details>
194+
<summary>Laravel 11</summary>
195+
196+
```php
197+
return Application::configure(basePath: dirname(__DIR__))
198+
->withRouting(
199+
web: __DIR__ . '/../routes/web.php',
200+
commands: __DIR__ . '/../routes/console.php',
201+
health: '/up',
202+
)
203+
->withMiddleware(function (Middleware $middleware) {
204+
$middleware->preventRequestsDuringMaintenance(
205+
except: [
206+
'/cloud-scheduler-job',
207+
],
208+
);
209+
})
210+
->withExceptions(function (Exceptions $exceptions) {
211+
//
212+
})->create();
213+
214+
215+
```
216+
</details>
217+
<details>
218+
<summary>Laravel 10</summary>
219+
220+
```php
221+
<?php
222+
223+
namespace App\Http\Middleware;
224+
225+
use Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance as Middleware;
226+
227+
class PreventRequestsDuringMaintenance extends Middleware
228+
{
229+
/**
230+
* The URIs that should be reachable while maintenance mode is enabled.
231+
*
232+
* @var array
233+
*/
234+
protected $except = [
235+
+ '/cloud-scheduler-job',
236+
];
169237
}
238+
170239
```
240+
</details>
171241

172242
# Cloud Scheduler Example
173243

UPGRADING.md

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# From 2.x to 3.x
2+
3+
Support for Laravel 6, 7, 8, and 9 has been dropped. The minimum supported version is now Laravel 10.
4+
5+
## Environment changes (Impact: high)
6+
7+
Publish the new configuration file:
8+
9+
```bash
10+
php artisan vendor:publish --tag=cloud-scheduler-config
11+
```
12+
13+
Change the environment variables names:
14+
15+
- `STACKKIT_CLOUD_SCHEDULER_APP_URL` -> `CLOUD_SCHEDULER_APP_URL`
16+
17+
Add the following environment variable:
18+
19+
- `CLOUD_SCHEDULER_SERVICE_ACCOUNT` - The e-mail address of the service account invocating the task.

0 commit comments

Comments
 (0)