diff --git a/app/Http/Controllers/StatsController.php b/app/Http/Controllers/StatsController.php index 49cb92c..f6110b0 100644 --- a/app/Http/Controllers/StatsController.php +++ b/app/Http/Controllers/StatsController.php @@ -22,6 +22,7 @@ class StatsController extends Controller DB::raw('count(distinct site_id) as total') ]) ->selectRaw($case->toRaw().' AS ver') + ->join('versions','versions.id','=','site_versions.version_id') ->groupBy([DB::raw('DATE(site_versions.created_at)'),'ver']) ; diff --git a/app/Http/Controllers/VersionController.php b/app/Http/Controllers/VersionController.php index de8c276..527f836 100644 --- a/app/Http/Controllers/VersionController.php +++ b/app/Http/Controllers/VersionController.php @@ -9,6 +9,7 @@ use Illuminate\Support\Str; use App\Models\Site; use App\Models\SiteVersion; +use App\Models\Version; class VersionController extends Controller { @@ -20,7 +21,7 @@ class VersionController extends Controller private const VERSION_REGEX = '/^v([0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?)-([a-z]{3})-([a-z0-9]{8})$/'; - public function main(Request $request,string $version=NULL) { + public function main(Request $request,?string $version=NULL) { // Our version is in the format of either: // v1.2.3-xxx-abcdef01 Log::info(sprintf('Connection from [%s] reporting version [%s]',$this->getUserIpAddr(),$version)); @@ -31,9 +32,11 @@ class VersionController extends Controller 'ip_address'=>$this->getUserIpAddr() ]); - $vo = new SiteVersion; - $vo->version = $version; - $so->versions()->save($vo); + $vo = Version::firstOrCreate(['version'=>$version]); + + $sv = new SiteVersion; + $sv->version_id = $vo->id; + $so->versions()->save($sv); // If xxx is "dev" we are a development version switch($matches[3]) { @@ -69,30 +72,30 @@ class VersionController extends Controller case 'rel': $current = Cache::remember('rel',self::CACHE_TIME,function() { $client = new Client; - $url = sprintf('%s/%s/tags',self::GH_URL,self::GH_PROJECT); + $url = sprintf('%s/%s/releases/latest',self::GH_URL,self::GH_PROJECT); // Find the tag associated with version $matches[1] and see if there is a more recent version number - $response = $client->request('GET',$url,['form_params'=>['ref_name'=>'master','sort'=>'desc']]); + $response = $client->request('GET',$url); if ($response->getStatusCode() === 200) { $result = collect(json_decode($response->getBody())); - return $result->first(); + return $result; } return NULL; }); if ($current) { - $sha = Str::limit($current->commit->sha,8,NULL); - $repository = sprintf('v%s-rel-%s',$current->name,$sha); + $repository = sprintf('v%s',$current->get('tag_name')); + $sha = $this->get_sha($current->get('tag_name')); // If $matches[1] is smaller, "upgrade available" - if ($matches[1] < $current->name) + if ($matches[1] < $current->get('tag_name')) $response = ['action'=>'upgrade','version'=>$repository]; // If $matches[1] is the same, validate that $matches[4] is current and the same and if not, error - elseif ($matches[1] === $current->name) + elseif ($matches[1] === $current->get('tag_name')) $response = ($matches[4] === $sha) ? ['action'=>'current','version'=>$repository] : ['action'=>'mismatch','version'=>$repository]; // if $matches[1] is higher, abort @@ -105,8 +108,8 @@ class VersionController extends Controller break; } - $vo->response = $response; - $vo->save(); + $sv->response = $response; + $sv->save(); return $response; } @@ -115,6 +118,25 @@ class VersionController extends Controller return ['action'=>'invalid','version'=>'vn.n.n-xxxx-hhhhhhhh']; } + private function get_sha(string $tag): ?string + { + return Cache::remember($tag,self::CACHE_TIME,function() use ($tag){ + $url = sprintf('%s/%s/git/ref/tags/%s',self::GH_URL,self::GH_PROJECT,$tag); + + // Find the tag associated with version $matches[1] and see if there is a more recent version number + $client = new Client; + $response = $client->request('GET',$url); + + if ($response->getStatusCode() === 200) { + $result = collect(json_decode($response->getBody())); + + return substr($result->get('object')->sha,0,8); + } + + return NULL; + }); + } + public function getUserIpAddr(): string { if (isset($_SERVER['HTTP_CLIENT_IP'])) diff --git a/app/Models/Site.php b/app/Models/Site.php index 608d156..ba0f373 100644 --- a/app/Models/Site.php +++ b/app/Models/Site.php @@ -6,6 +6,8 @@ use Illuminate\Database\Eloquent\Model; class Site extends Model { + const UPDATED_AT = NULL; + protected $fillable = ['ip_address']; /* RELATIONS */ diff --git a/app/Models/SiteVersion.php b/app/Models/SiteVersion.php index 01c63ca..08f67a7 100644 --- a/app/Models/SiteVersion.php +++ b/app/Models/SiteVersion.php @@ -7,6 +7,8 @@ use Illuminate\Database\Eloquent\Model; class SiteVersion extends Model { + const UPDATED_AT = NULL; + /* RELATIONS */ public function sites() @@ -14,6 +16,11 @@ class SiteVersion extends Model return $this->belongsTo(Site::class); } + public function versions() + { + return $this->belongsTo(Version::class); + } + /* ATTRIBUTES */ public function getDateAttribute(): int { diff --git a/app/Models/Version.php b/app/Models/Version.php new file mode 100644 index 0000000..9007b69 --- /dev/null +++ b/app/Models/Version.php @@ -0,0 +1,12 @@ +id(); + $table->timestamp('created_at',0)->nullable(); + $table->string('version'); + + $table->index(['version']); + }); + + foreach (DB::table('site_versions')->select(['version',DB::raw('MIN(created_at) AS created_at')])->groupBy('version')->cursor() as $o) { + $oo = new \App\Models\Version; + $oo->created_at = $o->created_at; + $oo->version = $o->version; + $oo->save(); + } + + Schema::table('site_versions', function (Blueprint $table) { + $table->bigInteger('version_id')->nullable(); + $table->foreign('version_id')->references('id')->on('versions'); + $table->dropColumn(['updated_at']); + }); + + foreach (DB::table('versions')->select(['id','version'])->cursor() as $o) { + DB::table('site_versions')->where('version',$o->version)->update(['version_id'=>$o->id]); + } + + Schema::table('site_versions', function (Blueprint $table) { + $table->dropColumn(['version']); + }); + + Schema::table('sites', function (Blueprint $table) { + $table->dropColumn(['updated_at']); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + throw new \Exception('Cant go back'); + } +};