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
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace He4rt\IntegrationGithub\Database\Factories;

use He4rt\Identity\Tenant\Models\Tenant;
use He4rt\IntegrationGithub\Enums\PurposeType;
use He4rt\IntegrationGithub\Models\GithubRepository;
use Illuminate\Database\Eloquent\Factories\Factory;

Expand All @@ -25,6 +26,7 @@ public function definition(): array
'full_name' => 'he4rt/'.fake()->unique()->slug(2),
'enabled' => true,
'last_backfilled_at' => null,
'purpose' => PurposeType::Contributions->value,
];
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
public function up(): void
{
Schema::table('github_repositories', static function (Blueprint $table): void {
$table->string('purpose')->nullable();
});

DB::table('github_repositories')->update(['purpose' => 'contributions']);
}
Comment on lines +12 to +19

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Following the idea of implementing an enum for this value, I would use a nullable string rather than a default value. Then, I would add an extra step to fill it with the default values.

Note

Do not use enums in migrations.
This could be impacted by a change in the future.
It will not be implemented if migration has already occurred; it will only be implemented on new databases.

Suggested change
public function up(): void
{
Schema::table('github_repositories', static function (Blueprint $table): void {
$table->string('purpose')->default('contributions');
});
}
public function up(): void
{
Schema::table('github_repositories', static function (Blueprint $table): void {
$table->string('purpose')->nullable();
});
DB::table('github_repositories')
->update(['purpose' => 'contributions']);
}

Before applying/implementing this suggestion, I would like to hear from @danielhe4rt and @Clintonrocha98. Default values aren't a problem, but they could be in the future.

};
11 changes: 11 additions & 0 deletions app-modules/integration-github/src/Enums/PurposeType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

declare(strict_types=1);

namespace He4rt\IntegrationGithub\Enums;

enum PurposeType: string
{
case Contributions = 'contributions';
case Challenge = 'challenge';
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Carbon\CarbonInterface;
use He4rt\Identity\Tenant\Models\Tenant;
use He4rt\IntegrationGithub\Database\Factories\GithubRepositoryFactory;
use He4rt\IntegrationGithub\Enums\PurposeType;
use Illuminate\Database\Eloquent\Attributes\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Casts\Attribute;
Expand All @@ -21,6 +22,7 @@
* @property string $tenant_id
* @property string $full_name
* @property bool $enabled
* @property PurposeType $purpose

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PHPDoc already declares @property PurposeType $purpose, but casts() has no matching cast. At runtime $repo->purpose still returns a string, so the PHPDoc doesn't reflect the actual type. To align it, following @gvieira18's idea of keeping it as an enum:

protected function casts(): array
{
    return [
        'enabled' => 'boolean',
        'last_backfilled_at' => 'datetime',
        'purpose' => PurposeType::class,
    ];
}

This makes the attribute strongly typed and keeps the PHPDoc honest about the real behavior.

* @property CarbonInterface|null $last_backfilled_at
* @property CarbonInterface|null $created_at
* @property CarbonInterface|null $updated_at
Expand Down Expand Up @@ -75,6 +77,7 @@ protected function casts(): array
return [
'enabled' => 'boolean',
'last_backfilled_at' => 'datetime',
'purpose' => PurposeType::class,
];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use He4rt\IntegrationGithub\Contributions\DTOs\NewContributionDTO;
use He4rt\IntegrationGithub\Contributions\RecordContribution;
use He4rt\IntegrationGithub\Enums\ContributionType;
use He4rt\IntegrationGithub\Enums\PurposeType;
use He4rt\IntegrationGithub\Models\GithubRepository;
use Illuminate\Support\Str;

Expand Down Expand Up @@ -56,6 +57,7 @@ private function tenantsTracking(string $repo): array
return array_values(GithubRepository::query()
->enabled()
->where('full_name', $repo)
->where('purpose', PurposeType::Contributions)
->pluck('tenant_id')
->map(static fn (mixed $tenantId): string => (string) $tenantId)
->all());
Expand Down
39 changes: 39 additions & 0 deletions app-modules/integration-github/tests/Feature/GithubWebhookTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
declare(strict_types=1);

use He4rt\IntegrationGithub\Enums\ContributionType;
use He4rt\IntegrationGithub\Enums\PurposeType;
use He4rt\IntegrationGithub\Events\GithubContributionRecorded;
use He4rt\IntegrationGithub\Models\GithubContribution;
use He4rt\IntegrationGithub\Models\GithubEventLog;
Expand Down Expand Up @@ -159,3 +160,41 @@ function prWebhookPayload(string $repo = 'he4rt/heartdevs.com', int $number = 1,
expect(GithubContribution::query()->where('external_ref', 'issue:10')->exists())->toBeTrue()
->and(GithubContribution::query()->where('external_ref', 'commit:sha1')->exists())->toBeTrue();
});

it('grava no lake mas NÃO projeta contribuição para repo de challenge', function (): void {
Event::fake([GithubContributionRecorded::class]);

GithubRepository::factory()->create([
'full_name' => 'he4rt/heartdevs.com',
'purpose' => PurposeType::Challenge,
]);

postGithubWebhook('pull_request', prWebhookPayload())->assertSuccessful();

expect(GithubEventLog::query()->count())->toBe(1)
->and(GithubContribution::query()->count())->toBe(0);

Event::assertNotDispatched(GithubContributionRecorded::class);
});

it('grava no lake e projeta a contribuição para repo de contributions, emitindo o evento', function (): void {
Event::fake([GithubContributionRecorded::class]);

$repo = GithubRepository::factory()->create([
'full_name' => 'he4rt/heartdevs.com',
'purpose' => PurposeType::Contributions,
]);

postGithubWebhook('pull_request', prWebhookPayload())->assertSuccessful();

expect(GithubEventLog::query()->count())->toBe(1);

$contribution = GithubContribution::query()->where('external_ref', 'pr:1')->sole();

expect($contribution->type)->toBe(ContributionType::Pr)
->and($contribution->tenant_id)->toBe($repo->tenant_id)
->and($contribution->actor_login)->toBe('maria')
->and($contribution->metadata['additions'])->toBe(5);

Event::assertDispatched(GithubContributionRecorded::class);
});