#48 - heroku deployment #70
1
.gitignore
vendored
@@ -15,5 +15,6 @@ Homestead.json
|
|||||||
Homestead.yaml
|
Homestead.yaml
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
yarn-error.log
|
yarn-error.log
|
||||||
|
google-credentials.json
|
||||||
.idea/
|
.idea/
|
||||||
.composer
|
.composer
|
||||||
|
|||||||
3
Procfile
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
web: vendor/bin/heroku-php-nginx -C environment/prod/nginx.conf public/
|
||||||
|
release: php artisan migrate --force && php artisan cache:clear && php artisan config:cache
|
||||||
|
worker: php artisan queue:work
|
||||||
@@ -4,19 +4,19 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Toby\Eloquent\Observers;
|
namespace Toby\Eloquent\Observers;
|
||||||
|
|
||||||
use Toby\Eloquent\Helpers\YearPeriodRetriever;
|
|
||||||
use Toby\Eloquent\Models\User;
|
use Toby\Eloquent\Models\User;
|
||||||
|
use Toby\Eloquent\Models\YearPeriod;
|
||||||
|
|
||||||
class UserObserver
|
class UserObserver
|
||||||
{
|
{
|
||||||
public function __construct(
|
|
||||||
protected YearPeriodRetriever $yearPeriodRetriever,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
public function created(User $user): void
|
public function created(User $user): void
|
||||||
{
|
{
|
||||||
|
$yearPeriods = YearPeriod::all();
|
||||||
|
|
||||||
|
foreach ($yearPeriods as $yearPeriod) {
|
||||||
$user->vacationLimits()->create([
|
$user->vacationLimits()->create([
|
||||||
"year_period_id" => $this->yearPeriodRetriever->current()->id,
|
"year_period_id" => $yearPeriod->id,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ class DashboardController extends Controller
|
|||||||
|
|
||||||
$holidays = Holiday::query()
|
$holidays = Holiday::query()
|
||||||
->whereDate("date", ">=", $now)
|
->whereDate("date", ">=", $now)
|
||||||
->latest()
|
->orderBy("date")
|
||||||
->limit(3)
|
->limit(3)
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
|
|||||||
@@ -9,12 +9,6 @@ use Symfony\Component\HttpFoundation\Request;
|
|||||||
|
|
||||||
class TrustProxies extends Middleware
|
class TrustProxies extends Middleware
|
||||||
{
|
{
|
||||||
protected $proxies;
|
protected $proxies = "*";
|
||||||
|
protected $headers = Request::HEADER_X_FORWARDED_AWS_ELB;
|
||||||
protected $headers =
|
|
||||||
Request::HEADER_X_FORWARDED_FOR |
|
|
||||||
Request::HEADER_X_FORWARDED_HOST |
|
|
||||||
Request::HEADER_X_FORWARDED_PORT |
|
|
||||||
Request::HEADER_X_FORWARDED_PROTO |
|
|
||||||
Request::HEADER_X_FORWARDED_AWS_ELB;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
"require": {
|
"require": {
|
||||||
"php": "^8.1",
|
"php": "^8.1",
|
||||||
"ext-pdo": "*",
|
"ext-pdo": "*",
|
||||||
|
"ext-redis": "*",
|
||||||
|
|
|||||||
"azuyalabs/yasumi": "^2.4",
|
"azuyalabs/yasumi": "^2.4",
|
||||||
"barryvdh/laravel-dompdf": "^1.0",
|
"barryvdh/laravel-dompdf": "^1.0",
|
||||||
"fruitcake/laravel-cors": "^2.0",
|
"fruitcake/laravel-cors": "^2.0",
|
||||||
@@ -24,12 +25,12 @@
|
|||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"blumilksoftware/codestyle": "^0.10.0",
|
"blumilksoftware/codestyle": "^0.10.0",
|
||||||
"spatie/laravel-ignition": "^1.0",
|
"fakerphp/faker": "^1.19",
|
||||||
"fakerphp/faker": "^1.9.1",
|
|
||||||
"laravel/dusk": "^6.21",
|
"laravel/dusk": "^6.21",
|
||||||
"mockery/mockery": "^1.4.4",
|
"mockery/mockery": "^1.4.4",
|
||||||
"nunomaduro/collision": "^6.1",
|
"nunomaduro/collision": "^6.1",
|
||||||
"phpunit/phpunit": "^9.5.10"
|
"phpunit/phpunit": "^9.5.10",
|
||||||
|
"spatie/laravel-ignition": "^1.0"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
|
|||||||
5
composer.lock
generated
@@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "937eef6310bd4bb12f1d0ccb623946d1",
|
"content-hash": "45ec654a060d5985bc58fec1f42d8219",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "asm89/stack-cors",
|
"name": "asm89/stack-cors",
|
||||||
@@ -10983,7 +10983,8 @@
|
|||||||
"prefer-lowest": false,
|
"prefer-lowest": false,
|
||||||
"platform": {
|
"platform": {
|
||||||
"php": "^8.1",
|
"php": "^8.1",
|
||||||
"ext-pdo": "*"
|
"ext-pdo": "*",
|
||||||
|
"ext-redis": "*"
|
||||||
},
|
},
|
||||||
"platform-dev": [],
|
"platform-dev": [],
|
||||||
"plugin-api-version": "2.1.0"
|
"plugin-api-version": "2.1.0"
|
||||||
|
|||||||
@@ -6,14 +6,9 @@ return [
|
|||||||
"default_auth_profile" => env("GOOGLE_CALENDAR_AUTH_PROFILE", "service_account"),
|
"default_auth_profile" => env("GOOGLE_CALENDAR_AUTH_PROFILE", "service_account"),
|
||||||
"auth_profiles" => [
|
"auth_profiles" => [
|
||||||
"service_account" => [
|
"service_account" => [
|
||||||
"credentials_json" => storage_path("app/google-calendar/service-account-credentials.json"),
|
"credentials_json" => base_path("google-credentials.json"),
|
||||||
],
|
|
||||||
"oauth" => [
|
|
||||||
"credentials_json" => storage_path("app/google-calendar/oauth-credentials.json"),
|
|
||||||
"token_json" => storage_path("app/google-calendar/oauth-token.json"),
|
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
|
||||||
"calendar_id" => env("GOOGLE_CALENDAR_ID"),
|
"calendar_id" => env("GOOGLE_CALENDAR_ID"),
|
||||||
"user_to_impersonate" => env("GOOGLE_CALENDAR_IMPERSONATE"),
|
"user_to_impersonate" => env("GOOGLE_CALENDAR_IMPERSONATE"),
|
||||||
];
|
];
|
||||||
|
I would pu it into storage directory. I would pu it into storage directory.
Heroku buildpack creates this file in root directory and we cannot change this location. Heroku buildpack creates this file in root directory and we cannot change this location.
Okok. Okok.
|
|||||||
|
|||||||
@@ -6,7 +6,7 @@ services:
|
|||||||
container_name: toby-web
|
container_name: toby-web
|
||||||
working_dir: /application
|
working_dir: /application
|
||||||
volumes:
|
volumes:
|
||||||
- ./docker/dev/nginx/nginx.conf:/etc/nginx/conf.d/default.conf
|
- ./environment/dev/nginx/nginx.conf:/etc/nginx/conf.d/default.conf
|
||||||
- .:/application
|
- .:/application
|
||||||
networks:
|
networks:
|
||||||
- toby-dev
|
- toby-dev
|
||||||
@@ -19,7 +19,7 @@ services:
|
|||||||
|
|
||||||
php:
|
php:
|
||||||
build:
|
build:
|
||||||
context: docker/dev/php
|
context: environment/dev/php
|
||||||
args:
|
args:
|
||||||
INSTALL_XDEBUG: ${DOCKER_INSTALL_XDEBUG:-false}
|
INSTALL_XDEBUG: ${DOCKER_INSTALL_XDEBUG:-false}
|
||||||
container_name: toby-php
|
container_name: toby-php
|
||||||
@@ -27,7 +27,7 @@ services:
|
|||||||
user: ${CURRENT_UID:-1000}
|
user: ${CURRENT_UID:-1000}
|
||||||
volumes:
|
volumes:
|
||||||
- .:/application
|
- .:/application
|
||||||
- ./docker/dev/php/php.ini:/usr/local/etc/php/conf.d/php.ini
|
- ./environment/dev/php/php.ini:/usr/local/etc/php/conf.d/php.ini
|
||||||
networks:
|
networks:
|
||||||
- toby-dev
|
- toby-dev
|
||||||
extra_hosts:
|
extra_hosts:
|
||||||
|
|||||||
10
environment/prod/nginx.conf
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
if ($http_x_forwarded_proto != 'https') {
|
||||||
|
rewrite ^ https://$host$request_uri? permanent;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri @rewriteapp;
|
||||||
|
}
|
||||||
|
location @rewriteapp {
|
||||||
|
rewrite ^(.*)$ /index.php$1 last;
|
||||||
|
}
|
||||||
45
environment/prod/readme.md
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
# Heroku deployment
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
## Addons
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
* Heroku Postgres
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
* Heroku Redis
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
## Dynos
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
* web (app)
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
* worker (queue worker)
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
## Buildpacks
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
* heroku/php
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
* heroku/nodejs
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
* https://github.com/buyersight/heroku-google-application-credentials-buildpack.git
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
## Config vars
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
* APP_DEBUG=false
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
* APP_ENV=production
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
* APP_KEY=
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
* APP_NAME="Toby HR application"
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
* APP_URL=
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
* ASSET_URL=
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
* BROADCAST_DRIVER=log
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
* CACHE_DRIVER=redis
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
* DATABASE_URL=
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
* DB_CONNECTION=pgsql
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
* DB_DATABASE=
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
* DB_HOST=
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
* DB_PORT=
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
* DB_USER=
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
* FILESYSTEM_DISK=local
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
* GOOGLE_CALENDAR_ID=
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
* GOOGLE_CLIENT_ID=
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
* GOOGLE_CLIENT_SECRET=
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
* GOOGLE_CREDENTIALS=
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
* GOOGLE_REDIRECT=
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
* LOG_CHANNEL=errorlog
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
* LOG_LEVEL=info
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
* MAIL_MAILER=log
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
* QUEUE_CONNECTION=redis
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
* REDIS_URL=
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
* SESSION_DRIVER=redis
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
|
* SESSION_LIFETIME=120
|
||||||
|
Could you provide here some default values if they're not secret ones? Could you provide here some default values if they're not secret ones?
|
|||||||
@@ -9,7 +9,8 @@
|
|||||||
"prod": "npm run production",
|
"prod": "npm run production",
|
||||||
"production": "mix --production",
|
"production": "mix --production",
|
||||||
"lint": "./node_modules/.bin/eslint resources/js --ext .js,.vue",
|
"lint": "./node_modules/.bin/eslint resources/js --ext .js,.vue",
|
||||||
"lintf": "./node_modules/.bin/eslint resources/js --ext .js,.vue --fix"
|
"lintf": "./node_modules/.bin/eslint resources/js --ext .js,.vue --fix",
|
||||||
|
"postinstall": "npm run prod"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@headlessui/vue": "^1.5.0",
|
"@headlessui/vue": "^1.5.0",
|
||||||
|
|||||||
@@ -53,14 +53,14 @@ Directory structure little differs from a standard Laravel tree. We decided to r
|
|||||||
|
|
||||||
dcr node npm run dev
|
dcr node npm run dev
|
||||||
|
|
||||||
- place google credentials here: `/storage/app/google-calendar/service-account-credentials.json` ([how to obtain the credentials](https://github.com/spatie/laravel-google-calendar#how-to-obtain-the-credentials-to-communicate-with-google-calendar))
|
- place google credentials here: `/google-credentials.json` ([how to obtain the credentials](https://github.com/spatie/laravel-google-calendar#how-to-obtain-the-credentials-to-communicate-with-google-calendar))
|
||||||
|
|
||||||
### Available containers (local)
|
### Available containers (local)
|
||||||
|
|
||||||
- **web** - nginx HTTP server
|
- **web** - nginx HTTP server
|
||||||
- **php** - php and composer stuff
|
- **php** - php and composer stuff
|
||||||
- **node** - npm stuff
|
- **node** - npm stuff
|
||||||
- **mysql** - database for local development
|
- **pgsql** - database for local development
|
||||||
- **mailhog** - for emails preview
|
- **mailhog** - for emails preview
|
||||||
|
|
||||||
### Running tests
|
### Running tests
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ const statuses = [
|
|||||||
|
|
||||||
export function useStatusInfo() {
|
export function useStatusInfo() {
|
||||||
const getStatues = () => statuses
|
const getStatues = () => statuses
|
||||||
const findStatus = value => statuses.find(month => month.value === value)
|
const findStatus = value => statuses.find(status => status.value === value)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
getStatues,
|
getStatues,
|
||||||
|
|||||||
@@ -372,7 +372,7 @@ export default {
|
|||||||
setup(props) {
|
setup(props) {
|
||||||
const form = useForm({
|
const form = useForm({
|
||||||
user: props.can.createOnBehalfOfEmployee
|
user: props.can.createOnBehalfOfEmployee
|
||||||
? props.users.data.find(user => user.id === props.auth.user.id)
|
? props.users.data.find(user => user.id === props.auth.user.id) ?? props.users.data[0]
|
||||||
: props.auth.user,
|
: props.auth.user,
|
||||||
from: null,
|
from: null,
|
||||||
to: null,
|
to: null,
|
||||||
|
|||||||
So do we need ext-redis or predis?
ext-redis