guibranco / gstraccini-bot

🤖 :octocat: GStraccini-bot automates repository management, ensuring organization and health by handling pull requests, issues, comments, and commits.
https://bot.straccini.com
MIT License
2 stars 0 forks source link

[FEATURE] Add `copy labels` command #165

Open guibranco opened 7 months ago

guibranco commented 7 months ago

Description

We need a new command that will copy labels from a specified base repository to the current repository. The command should be able to:

Example Command

The command should be structured as follows:

bot name sync-labels <owner/repository>

Where <owner/repository> is the name of the repository from which to copy labels.

Tech Notes

  1. Retrieve Labels from Base Repository:

    • Use the GitHub REST API to fetch all labels from the specified base repository.
  2. Check and Sync Labels in Current Repository:

    • For each label retrieved, check if it exists in the current repository.
    • If the label exists, update its color and description to match the base repository.
    • If the label does not exist, create a new label with the name, color, and description from the base repository.

PHP Example Code

Here’s a PHP example using the GuiBranco\Pancake library to illustrate the implementation:

use GuiBranco\Pancake\Request;

class LabelSyncer
{
    private $githubToken;
    private $githubApiUrl = 'https://api.github.com';

    public function __construct($githubToken)
    {
        $this->githubToken = $githubToken;
    }

    public function syncLabels($baseRepoOwner, $baseRepoName, $currentRepoOwner, $currentRepoName)
    {
        $request = new Request();

        // Get labels from the base repository
        $baseLabels = $this->getLabels($baseRepoOwner, $baseRepoName);

        foreach ($baseLabels as $label) {
            if ($this->labelExists($currentRepoOwner, $currentRepoName, $label['name'])) {
                $this->updateLabel($currentRepoOwner, $currentRepoName, $label);
            } else {
                $this->createLabel($currentRepoOwner, $currentRepoName, $label);
            }
        }
    }

    private function getLabels($repoOwner, $repoName)
    {
        $request = new Request();
        $response = $request->get("{$this->githubApiUrl}/repos/{$repoOwner}/{$repoName}/labels", [
            'headers' => [
                'Authorization' => "Bearer {$this->githubToken}",
                'Accept'        => 'application/vnd.github.v3+json',
            ],
        ]);

        return json_decode($response->getBody(), true);
    }

    private function labelExists($repoOwner, $repoName, $labelName)
    {
        $request = new Request();
        $response = $request->get("{$this->githubApiUrl}/repos/{$repoOwner}/{$repoName}/labels/{$labelName}", [
            'headers' => [
                'Authorization' => "Bearer {$this->githubToken}",
                'Accept'        => 'application/vnd.github.v3+json',
            ],
        ]);

        return $response->getStatusCode() === 200;
    }

    private function updateLabel($repoOwner, $repoName, $label)
    {
        $request = new Request();
        $request->patch("{$this->githubApiUrl}/repos/{$repoOwner}/{$repoName}/labels/{$label['name']}", [
            'headers' => [
                'Authorization' => "Bearer {$this->githubToken}",
                'Accept'        => 'application/vnd.github.v3+json',
            ],
            'json' => [
                'name'        => $label['name'],
                'color'       => $label['color'],
                'description' => $label['description'],
            ],
        ]);
    }

    private function createLabel($repoOwner, $repoName, $label)
    {
        $request = new Request();
        $request->post("{$this->githubApiUrl}/repos/{$repoOwner}/{$repoName}/labels", [
            'headers' => [
                'Authorization' => "Bearer {$this->githubToken}",
                'Accept'        => 'application/vnd.github.v3+json',
            ],
            'json' => [
                'name'        => $label['name'],
                'color'       => $label['color'],
                'description' => $label['description'],
            ],
        ]);
    }
}

// Usage example
$labelSyncer = new LabelSyncer('your-github-token');
$labelSyncer->syncLabels('base-repo-owner', 'base-repo-name', 'current-repo-owner', 'current-repo-name');

Expected Outcome

guibranco commented 1 week ago

@gstraccini copy issue guibranco/gstraccini-bot

gstraccini[bot] commented 1 week ago

Issue copied to guibranco/gstraccini-bot#537