e8da1a30ff
Platform: moko-platform CI / CI Summary (push) Blocked by required conditions
Generic: Repo Health / Site Health (push) Has been skipped
Generic: Repo Health / Access control (push) Successful in 2s
Generic: Repo Health / Release configuration (push) Successful in 10s
Generic: Repo Health / Scripts governance (push) Successful in 9s
Generic: Repo Health / Repository health (push) Successful in 17s
Platform: moko-platform CI / CI Summary (pull_request) Blocked by required conditions
Universal: PR Check / Branch Policy (pull_request) Successful in 2s
Generic: Repo Health / Access control (pull_request) Successful in 2s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Universal: Secret Scanning / Gitleaks Secret Scan (pull_request) Successful in 8s
Universal: PR Check / Validate PR (pull_request) Successful in 8s
Generic: Repo Health / Release configuration (pull_request) Successful in 6s
Generic: Repo Health / Scripts governance (pull_request) Successful in 8s
Universal: PR Check / Build RC Package (pull_request) Successful in 5s
Generic: Repo Health / Repository health (pull_request) Successful in 19s
Platform: moko-platform CI / Gate 1: Code Quality (push) Successful in 1m16s
Platform: moko-platform CI / Gate 1: Code Quality (pull_request) Successful in 1m29s
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (push) Successful in 41s
Platform: moko-platform CI / Gate 5: Template Integrity (push) Failing after 6s
Platform: moko-platform CI / Gate 4: Governance (push) Successful in 1m38s
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (push) Successful in 1m40s
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (push) Successful in 1m41s
Platform: moko-platform CI / Gate 3: Self-Health Check (push) Failing after 1m40s
Platform: moko-platform CI / Gate 4: Governance (pull_request) Successful in 1m20s
Platform: moko-platform CI / Gate 2: Unit Tests (8.2) (pull_request) Successful in 1m24s
Platform: moko-platform CI / Gate 3: Self-Health Check (pull_request) Failing after 1m24s
Platform: moko-platform CI / Gate 2: Unit Tests (8.1) (pull_request) Successful in 1m26s
Platform: moko-platform CI / Gate 2: Unit Tests (8.3) (pull_request) Successful in 1m30s
Platform: moko-platform CI / Gate 5: Template Integrity (pull_request) Failing after 12s
Removed 13 write-only properties and unused code. Remaining 41 baselined items are defensive patterns (null coalesce on API responses, boolean safety checks) that are intentional. PHPStan level 4: 0 errors with baseline. Authored-by: Moko Consulting Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
482 lines
18 KiB
PHP
482 lines
18 KiB
PHP
<?php
|
|
|
|
/* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
|
*
|
|
* This file is part of a Moko Consulting project.
|
|
*
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
*
|
|
* FILE INFORMATION
|
|
* DEFGROUP: MokoStandards.Enterprise.Platform
|
|
* INGROUP: MokoStandards.Enterprise
|
|
* REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform
|
|
* PATH: /lib/Enterprise/GitPlatformAdapter.php
|
|
* BRIEF: Interface defining all git platform operations for GitHub/Gitea abstraction
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace MokoEnterprise;
|
|
|
|
/**
|
|
* Git Platform Adapter Interface
|
|
*
|
|
* Defines all platform operations required by MokoStandards automation.
|
|
* Implementations exist for GitHub (GitHubAdapter) and Gitea (MokoGiteaAdapter),
|
|
* allowing scripts to work against either platform transparently.
|
|
*
|
|
* @package MokoStandards\Enterprise
|
|
* @version 04.06.10
|
|
*/
|
|
interface GitPlatformAdapter
|
|
{
|
|
// ──────────────────────────────────────────────
|
|
// Identity
|
|
// ──────────────────────────────────────────────
|
|
|
|
/**
|
|
* Get the platform name identifier.
|
|
*
|
|
* @return string 'github' or 'gitea'
|
|
*/
|
|
public function getPlatformName(): string;
|
|
|
|
/**
|
|
* Get the API base URL.
|
|
*
|
|
* @return string e.g. 'https://api.github.com' or 'https://git.mokoconsulting.tech/api/v1'
|
|
*/
|
|
public function getBaseUrl(): string;
|
|
|
|
/**
|
|
* Get the workflow directory name for this platform.
|
|
*
|
|
* @return string '.github/workflows' or '.mokogitea/workflows'
|
|
*/
|
|
public function getWorkflowDir(): string;
|
|
|
|
/**
|
|
* Get the platform-specific metadata directory.
|
|
*
|
|
* @return string '.github' or '.mokogitea'
|
|
*/
|
|
public function getMetadataDir(): string;
|
|
|
|
/**
|
|
* Get the web URL for a repository (for use in markdown links, not API calls).
|
|
*
|
|
* @param string $org Organization name
|
|
* @param string $repo Repository name
|
|
* @return string e.g. 'https://github.com/org/repo' or 'https://git.mokoconsulting.tech/org/repo'
|
|
*/
|
|
public function getRepoWebUrl(string $org, string $repo): string;
|
|
|
|
/**
|
|
* Get the web URL for a pull request.
|
|
*
|
|
* @param string $org Organization name
|
|
* @param string $repo Repository name
|
|
* @param int $number PR number
|
|
* @return string e.g. 'https://github.com/org/repo/pull/1' or 'https://git.example.com/org/repo/pulls/1'
|
|
*/
|
|
public function getPullRequestWebUrl(string $org, string $repo, int $number): string;
|
|
|
|
/**
|
|
* Get the web URL for an issue.
|
|
*
|
|
* @param string $org Organization name
|
|
* @param string $repo Repository name
|
|
* @param int $number Issue number
|
|
* @return string
|
|
*/
|
|
public function getIssueWebUrl(string $org, string $repo, int $number): string;
|
|
|
|
/**
|
|
* Get the web URL for a branch.
|
|
*
|
|
* @param string $org Organization name
|
|
* @param string $repo Repository name
|
|
* @param string $branch Branch name
|
|
* @return string e.g. 'https://github.com/org/repo/tree/branch' or 'https://git.example.com/org/repo/src/branch/branch'
|
|
*/
|
|
public function getBranchWebUrl(string $org, string $repo, string $branch): string;
|
|
|
|
/**
|
|
* Get the environment variable name for step summary output (CI-specific).
|
|
*
|
|
* @return string 'GITHUB_STEP_SUMMARY' or 'GITEA_STEP_SUMMARY'
|
|
*/
|
|
public function getStepSummaryEnvVar(): string;
|
|
|
|
// ──────────────────────────────────────────────
|
|
// Repository CRUD
|
|
// ──────────────────────────────────────────────
|
|
|
|
/**
|
|
* List all repositories for an organization.
|
|
*
|
|
* @param string $org Organization name
|
|
* @param bool $skipArchived Whether to exclude archived repos
|
|
* @return array<int, array{name: string, full_name: string, archived: bool, private: bool}> Repository list
|
|
*/
|
|
public function listOrgRepos(string $org, bool $skipArchived = false): array;
|
|
|
|
/**
|
|
* Get a single repository's information.
|
|
*
|
|
* @param string $org Organization name
|
|
* @param string $repo Repository name
|
|
* @return array<string, mixed> Repository data from API
|
|
*/
|
|
public function getRepo(string $org, string $repo): array;
|
|
|
|
/**
|
|
* Create a new repository in an organization.
|
|
*
|
|
* @param string $org Organization name
|
|
* @param string $name Repository name
|
|
* @param array<string, mixed> $options Repository options (description, private, auto_init, etc.)
|
|
* @return array<string, mixed> Created repository data
|
|
*/
|
|
public function createOrgRepo(string $org, string $name, array $options = []): array;
|
|
|
|
/**
|
|
* Archive a repository (set to read-only).
|
|
*
|
|
* @param string $org Organization name
|
|
* @param string $repo Repository name
|
|
* @return array<string, mixed> Updated repository data
|
|
*/
|
|
public function archiveRepo(string $org, string $repo): array;
|
|
|
|
/**
|
|
* Set repository topics/tags.
|
|
*
|
|
* @param string $org Organization name
|
|
* @param string $repo Repository name
|
|
* @param array<string> $topics List of topic strings
|
|
* @return void
|
|
*/
|
|
public function setRepoTopics(string $org, string $repo, array $topics): void;
|
|
|
|
/**
|
|
* Get repository topics/tags.
|
|
*
|
|
* @param string $org Organization name
|
|
* @param string $repo Repository name
|
|
* @return array<string> List of topic strings
|
|
*/
|
|
public function getRepoTopics(string $org, string $repo): array;
|
|
|
|
// ──────────────────────────────────────────────
|
|
// Branches and Cloning
|
|
// ──────────────────────────────────────────────
|
|
|
|
/**
|
|
* List all branches in a repository.
|
|
*
|
|
* @return array<mixed>
|
|
*/
|
|
public function listBranches(string $org, string $repo): array;
|
|
|
|
/**
|
|
* Get the clone URL for a repository.
|
|
*/
|
|
public function getCloneUrl(string $repo): string;
|
|
|
|
/**
|
|
* Clone a repository to a local path.
|
|
*
|
|
* @param array<string, mixed> $options
|
|
*/
|
|
public function cloneRepo(string $repo, string $path, array $options = []): bool;
|
|
|
|
// ──────────────────────────────────────────────
|
|
// File Contents
|
|
// ──────────────────────────────────────────────
|
|
|
|
/**
|
|
* Get file contents from a repository.
|
|
*
|
|
* @param string $org Organization name
|
|
* @param string $repo Repository name
|
|
* @param string $path File path within the repository
|
|
* @param string|null $ref Branch/tag/SHA reference (null = default branch)
|
|
* @return array<string, mixed> File data (content is base64-encoded)
|
|
*/
|
|
public function getFileContents(string $org, string $repo, string $path, ?string $ref = null): array;
|
|
|
|
/**
|
|
* Create or update a file in a repository.
|
|
*
|
|
* @param string $org Organization name
|
|
* @param string $repo Repository name
|
|
* @param string $path File path
|
|
* @param string $content Raw file content (will be base64-encoded internally)
|
|
* @param string $message Commit message
|
|
* @param string|null $sha SHA of existing file (null = create new, string = update existing)
|
|
* @param string|null $branch Target branch (null = default branch)
|
|
* @return array<string, mixed> API response
|
|
*/
|
|
public function createOrUpdateFile(
|
|
string $org,
|
|
string $repo,
|
|
string $path,
|
|
string $content,
|
|
string $message,
|
|
?string $sha = null,
|
|
?string $branch = null
|
|
): array;
|
|
|
|
/**
|
|
* Delete a file from a repository.
|
|
*
|
|
* @param string $org Organization name
|
|
* @param string $repo Repository name
|
|
* @param string $path File path
|
|
* @param string $sha SHA of the file to delete
|
|
* @param string $message Commit message
|
|
* @param string|null $branch Target branch (null = default branch)
|
|
* @return array<string, mixed> API response
|
|
*/
|
|
public function deleteFile(
|
|
string $org,
|
|
string $repo,
|
|
string $path,
|
|
string $sha,
|
|
string $message,
|
|
?string $branch = null
|
|
): array;
|
|
|
|
// ──────────────────────────────────────────────
|
|
// Pull Requests
|
|
// ──────────────────────────────────────────────
|
|
|
|
/**
|
|
* List pull requests for a repository.
|
|
*
|
|
* @param string $org Organization name
|
|
* @param string $repo Repository name
|
|
* @param array<string, mixed> $filters Filters (state, head, base, sort, direction)
|
|
* @return array<mixed> Pull request list
|
|
*/
|
|
public function listPullRequests(string $org, string $repo, array $filters = []): array;
|
|
|
|
/**
|
|
* Create a pull request.
|
|
*
|
|
* @param string $org Organization name
|
|
* @param string $repo Repository name
|
|
* @param string $title PR title
|
|
* @param string $head Source branch
|
|
* @param string $base Target branch
|
|
* @param string $body PR description
|
|
* @param array<string, mixed> $options Additional options (labels, assignees, etc.)
|
|
* @return array<string, mixed> Created PR data
|
|
*/
|
|
public function createPullRequest(
|
|
string $org,
|
|
string $repo,
|
|
string $title,
|
|
string $head,
|
|
string $base,
|
|
string $body = '',
|
|
array $options = []
|
|
): array;
|
|
|
|
/**
|
|
* Update a pull request.
|
|
*
|
|
* @param string $org Organization name
|
|
* @param string $repo Repository name
|
|
* @param int $number PR number
|
|
* @param array<string, mixed> $data Fields to update (title, body, state, etc.)
|
|
* @return array<string, mixed> Updated PR data
|
|
*/
|
|
public function updatePullRequest(string $org, string $repo, int $number, array $data): array;
|
|
|
|
// ──────────────────────────────────────────────
|
|
// Issues
|
|
// ──────────────────────────────────────────────
|
|
|
|
/**
|
|
* List issues for a repository.
|
|
*
|
|
* @param string $org Organization name
|
|
* @param string $repo Repository name
|
|
* @param array<string, mixed> $filters Filters (state, labels, assignee, etc.)
|
|
* @return array<mixed> Issue list
|
|
*/
|
|
public function listIssues(string $org, string $repo, array $filters = []): array;
|
|
|
|
/**
|
|
* Create an issue.
|
|
*
|
|
* @param string $org Organization name
|
|
* @param string $repo Repository name
|
|
* @param string $title Issue title
|
|
* @param string $body Issue body
|
|
* @param array<string, mixed> $options Additional options (labels, assignees, milestone)
|
|
* @return array<string, mixed> Created issue data
|
|
*/
|
|
public function createIssue(
|
|
string $org,
|
|
string $repo,
|
|
string $title,
|
|
string $body = '',
|
|
array $options = []
|
|
): array;
|
|
|
|
/**
|
|
* Add a comment to an issue or PR.
|
|
*
|
|
* @param string $org Organization name
|
|
* @param string $repo Repository name
|
|
* @param int $number Issue/PR number
|
|
* @param string $body Comment body
|
|
* @return array<string, mixed> Created comment data
|
|
*/
|
|
public function addIssueComment(string $org, string $repo, int $number, string $body): array;
|
|
|
|
/**
|
|
* Close an issue.
|
|
*
|
|
* @param string $org Organization name
|
|
* @param string $repo Repository name
|
|
* @param int $number Issue number
|
|
* @return array<string, mixed> Updated issue data
|
|
*/
|
|
public function closeIssue(string $org, string $repo, int $number): array;
|
|
|
|
// ──────────────────────────────────────────────
|
|
// Labels
|
|
// ──────────────────────────────────────────────
|
|
|
|
/**
|
|
* List labels for a repository.
|
|
*
|
|
* @param string $org Organization name
|
|
* @param string $repo Repository name
|
|
* @return array<mixed> Label list
|
|
*/
|
|
public function listLabels(string $org, string $repo): array;
|
|
|
|
/**
|
|
* Create a label.
|
|
*
|
|
* @param string $org Organization name
|
|
* @param string $repo Repository name
|
|
* @param string $name Label name
|
|
* @param string $color Hex color (without #)
|
|
* @param string $description Label description
|
|
* @return array<string, mixed> Created label data
|
|
*/
|
|
public function createLabel(string $org, string $repo, string $name, string $color, string $description = ''): array;
|
|
|
|
/**
|
|
* Add labels to an issue or PR.
|
|
*
|
|
* @param string $org Organization name
|
|
* @param string $repo Repository name
|
|
* @param int $number Issue/PR number
|
|
* @param array<string> $labels Label names (GitHub) or label IDs (Gitea)
|
|
* @return array<string, mixed> API response
|
|
*/
|
|
public function addIssueLabels(string $org, string $repo, int $number, array $labels): array;
|
|
|
|
// ──────────────────────────────────────────────
|
|
// Branch Protection
|
|
// ──────────────────────────────────────────────
|
|
|
|
/**
|
|
* Set branch protection rules.
|
|
*
|
|
* On GitHub this maps to rulesets; on Gitea to branch_protections.
|
|
*
|
|
* @param string $org Organization name
|
|
* @param string $repo Repository name
|
|
* @param string $branch Branch name or pattern
|
|
* @param array<string, mixed> $rules Protection rules (required_reviews, dismiss_stale, etc.)
|
|
* @return array<string, mixed> Created/updated protection data
|
|
*/
|
|
public function setBranchProtection(string $org, string $repo, string $branch, array $rules): array;
|
|
|
|
/**
|
|
* List branch protection rules.
|
|
*
|
|
* @param string $org Organization name
|
|
* @param string $repo Repository name
|
|
* @return array<mixed> Protection rules
|
|
*/
|
|
public function listBranchProtections(string $org, string $repo): array;
|
|
|
|
// ──────────────────────────────────────────────
|
|
// Git Refs
|
|
// ──────────────────────────────────────────────
|
|
|
|
/**
|
|
* Resolve a tag or branch name to a commit SHA.
|
|
*
|
|
* @param string $org Organization name
|
|
* @param string $repo Repository name
|
|
* @param string $ref Tag or branch name (e.g. 'v1.0.0', 'main')
|
|
* @return string Full commit SHA
|
|
*/
|
|
public function resolveRef(string $org, string $repo, string $ref): string;
|
|
|
|
/**
|
|
* Get the repository tree (recursive file listing).
|
|
*
|
|
* @param string $org Organization name
|
|
* @param string $repo Repository name
|
|
* @param string $ref Tree SHA or branch (e.g. 'HEAD', 'main')
|
|
* @param bool $recursive Whether to recurse into subdirectories
|
|
* @return array<int, array{path: string, type: string, sha: string}> Tree entries
|
|
*/
|
|
public function getTree(string $org, string $repo, string $ref = 'HEAD', bool $recursive = true): array;
|
|
|
|
// ──────────────────────────────────────────────
|
|
// Pagination
|
|
// ──────────────────────────────────────────────
|
|
|
|
/**
|
|
* Paginate through all pages of a list endpoint.
|
|
*
|
|
* @param string $endpoint API endpoint path
|
|
* @param array<string, mixed> $params Query parameters
|
|
* @param int $perPage Items per page (platform default if 0)
|
|
* @return array<mixed> All items across all pages
|
|
*/
|
|
public function paginateAll(string $endpoint, array $params = [], int $perPage = 100): array;
|
|
|
|
// ──────────────────────────────────────────────
|
|
// Migration (Gitea-specific, no-op on GitHub)
|
|
// ──────────────────────────────────────────────
|
|
|
|
/**
|
|
* Migrate a repository from an external service.
|
|
*
|
|
* On Gitea, this calls POST /api/v1/repos/migrate.
|
|
* On GitHub, this is a no-op (throws UnsupportedOperationException).
|
|
*
|
|
* @param array<string, mixed> $options Migration options (clone_addr, service, auth_token, etc.)
|
|
* @return array<string, mixed> Migrated repository data
|
|
* @throws \RuntimeException If the platform does not support migration
|
|
*/
|
|
public function migrateRepository(array $options): array;
|
|
|
|
// ──────────────────────────────────────────────
|
|
// Low-level API access
|
|
// ──────────────────────────────────────────────
|
|
|
|
/**
|
|
* Get the underlying ApiClient instance.
|
|
*
|
|
* Escape hatch for operations not covered by this interface.
|
|
* Prefer adding new interface methods over using this directly.
|
|
*
|
|
* @return ApiClient The wrapped API client
|
|
*/
|
|
public function getApiClient(): ApiClient;
|
|
}
|