Files
Jonathan Miller 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
fix: PHPStan level 3 → 4 — remove dead code, baseline 41 items
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>
2026-05-25 22:31:25 -05:00

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;
}