Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ on:
release:
types: [published]
workflow_dispatch:
inputs:
force_full:
description: 'Force full deploy (rebuild and upload vendor + assets)'
type: boolean
default: false

jobs:
deploy:
Expand All @@ -20,26 +25,70 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Determine what changed since last release
id: changes
run: |
set -euo pipefail

if [[ "${{ github.event.inputs.force_full }}" == "true" ]]; then
echo "Force full deploy requested via workflow_dispatch."
echo "composer_changed=true" >> "$GITHUB_OUTPUT"
echo "assets_changed=true" >> "$GITHUB_OUTPUT"
exit 0
fi

# Baseline = previous release tag (skip current HEAD if it IS a tag).
# Falls back to HEAD^ if there's no prior tag in history.
BASE=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || git rev-parse HEAD^)
echo "Diff baseline: $BASE"

CHANGED=$(git diff --name-only "$BASE" HEAD)
echo "Changed files since $BASE:"
echo "$CHANGED"

# Vendor needs rebuild + upload only when composer dependencies change.
if echo "$CHANGED" | grep -qE '^composer\.(json|lock)$'; then
echo "composer_changed=true" >> "$GITHUB_OUTPUT"
else
echo "composer_changed=false" >> "$GITHUB_OUTPUT"
fi

# Compiled assets need rebuild + upload when their source or build
# config changes. public/build/ filenames are content-hashed by Vite,
# so leaving stale ones on the server is harmless.
if echo "$CHANGED" | grep -qE '^(package(-lock)?\.json|vite\.config\.js|resources/(css|js)/)'; then
echo "assets_changed=true" >> "$GITHUB_OUTPUT"
else
echo "assets_changed=false" >> "$GITHUB_OUTPUT"
fi

- name: Setup PHP
if: steps.changes.outputs.composer_changed == 'true'
uses: shivammathur/setup-php@v2
with:
php-version: 8.3
extensions: mbstring, xml, ctype, json

- name: Install production dependencies
if: steps.changes.outputs.composer_changed == 'true'
run: composer install --no-dev --optimize-autoloader --no-interaction

- name: Setup Node.js
if: steps.changes.outputs.assets_changed == 'true'
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'

- name: Install npm dependencies
if: steps.changes.outputs.assets_changed == 'true'
run: npm ci

- name: Build assets
if: steps.changes.outputs.assets_changed == 'true'
run: npm run build

- name: Prepare production files
Expand Down
33 changes: 0 additions & 33 deletions app/Http/Controllers/ToolController.php
Original file line number Diff line number Diff line change
Expand Up @@ -153,12 +153,6 @@ public function index(): View
'route' => 'tools.sort-lines',
'icon' => 'sort',
],
[
'name' => 'Visitor Tracker',
'description' => 'Server-side visitor analytics for Laravel applications',
'route' => 'tools.visitor-tracker',
'icon' => 'chart',
],
];

return view('home', compact('tools'));
Expand Down Expand Up @@ -283,31 +277,4 @@ public function sortLines(): View
{
return view('tools.sort-lines');
}

public function visitorTracker(): View
{
$stats = app(\Ghdj\VisitorTracker\Services\StatisticsService::class);
$parser = new \Ghdj\VisitorTracker\Services\UserAgentParser();
$botDetector = new \Ghdj\VisitorTracker\Services\BotDetector();

$userAgent = request()->userAgent();
$parsedUA = $parser->parse($userAgent);
$isBot = $botDetector->isBot($userAgent);
$botName = $isBot ? $botDetector->getBotName($userAgent) : null;
$botCategory = $isBot ? $botDetector->getBotCategory($userAgent) : null;

return view('tools.visitor-tracker', [
'summary' => $stats->summary(),
'browsers' => $stats->browserStats(5),
'platforms' => $stats->platformStats(5),
'devices' => $stats->deviceStats(),
'topPages' => $stats->mostVisitedPages(5),
'userAgent' => $userAgent,
'parsedUA' => $parsedUA,
'isBot' => $isBot,
'botName' => $botName,
'botCategory' => $botCategory,
'visitorIp' => request()->ip(),
]);
}
}
Loading