VOOZH about

URL: https://deepwiki.com/pcescato/ajc-bridge/4.1-github-api-client

⇱ GitHub API Client | pcescato/ajc-bridge | DeepWiki


Loading...
Menu

GitHub API Client

This page documents the Git_API class, which is the sole interface between AJC Bridge and the GitHub REST API. It covers construction, authentication, all public and private methods, and the multi-step atomic commit flow.

For how Git_API is invoked during a post sync, see the Sync Pipeline (2.2) and Media Processor (3.5). For the Dev.to equivalent, see 4.2


Overview

Git_API is defined in core/class-git-api.php under the AjcBridge\Core namespace. It wraps the GitHub REST API and Git Data API entirely via WordPress's wp_remote_* HTTP functions — no shell commands or Git CLI are used.

The class is designed as a stateful object: credentials and repository settings are resolved once at construction time from the ajc_bridge_settings WordPress option. All public methods return either a typed success value or a \WP_Error instance on failure.

Class diagram: Git_API in context


Sources: core/class-git-api.php26-50


Construction and Configuration

The constructor reads all settings from the ajc_bridge_settings WordPress option and resolves three configuration values:

PropertyOption keyDefault
$tokengithub_token (encrypted)null
$repogithub_reponull
$branchgithub_branch'main'
$api_baseapi_base_url (optional)'https://api.github.com'

The api_base_url override allows future multi-provider support (e.g., GitHub Enterprise).

Sources: core/class-git-api.php62-104


Token Decryption

GitHub Personal Access Tokens are stored encrypted in the database. The decrypt_token() private method uses AES-256-CBC to reverse the encryption applied by the Settings page (see 5.1).

Encryption parameters:

ParameterSource
MethodAES-256-CBC
Keyhash('sha256', wp_salt('auth'), true)
IVFirst 16 bytes of hash('sha256', wp_salt('nonce'), true)
Encodingbase64_encode / base64_decode

If base64_decode fails, the token is assumed to be plain text and a warning is logged. If decryption succeeds, $this->token holds the raw token string; the encrypted form is never stored in memory beyond this point.

Security note: The class explicitly avoids logging token values at any point, even partial previews. See the comment at core/class-git-api.php77

Sources: core/class-git-api.php170-185 core/class-git-api.php62-95


Repository Format Parsing

The private parse_repo() method validates and splits the owner/repo string stored in $this->repo. It returns a two-element array [$owner, $repo] or a \WP_Error if:

  • $this->repo is null or empty → repo_not_configured
  • $this->repo is not a string → repo_invalid_type
  • No / character present → repo_invalid_format
  • Either part is empty after splitting → repo_invalid_format

parse_repo() is called at the start of every Git Data API method (get_branch_ref, create_blob, create_tree, create_commit, update_ref) to fail fast before making any HTTP request.

Sources: core/class-git-api.php113-161


Request Headers

The private get_headers() method returns the standard header set used for all authenticated requests:

HeaderValue
AuthorizationBearer {token}
Acceptapplication/vnd.github+json
Content-Typeapplication/json
User-AgentWP-Jamstack-Sync/{AJC_BRIDGE_VERSION}

Some older methods (e.g., test_connection, get_branch_sha) inline their headers directly rather than calling get_headers(). The delete_file and list_directory methods do use get_headers().

Sources: core/class-git-api.php192-199


Public Methods

test_connection()

core/class-git-api.php211-424

Makes a GET /repos/{owner}/{repo} request. Validates token presence, repo format, and HTTP response. Returns true on HTTP 200. Returns a \WP_Error for:

HTTP StatusError CodeMeaning
401invalid_tokenBad credentials
403 (rate limit)rate_limit_exceededIncludes reset time from x-ratelimit-reset header
403 (other)access_forbiddenToken lacks permission
404repo_not_foundRepository doesn't exist or is inaccessible
otherapi_errorGeneric HTTP error

On HTTP 200, additionally checks permissions.push in the response body and returns no_push_permission if the token cannot write to the repository.


get_branch_sha()

core/class-git-api.php431-465

Makes a GET /repos/{repo}/git/ref/heads/{branch} request. Returns the commit SHA string at data['object']['sha']. Used externally to check the current branch HEAD before operations.


create_or_update_file()

core/class-git-api.php477-538

Makes a PUT /repos/{repo}/contents/{path} request. Content is base64-encoded before transmission. If $sha is null, GitHub creates a new file; if $sha is provided, GitHub updates the existing file. Returns the raw decoded JSON body on HTTP 200 or 201. Timeout is set to 60 seconds.

Parameters:

ParameterTypePurpose
$pathstringRepository-relative file path
$contentstringRaw file content (text or binary)
$messagestringGit commit message
$shastring|nullExisting file SHA, or null for creation

get_file()

core/class-git-api.php547-635

Makes a GET /repos/{repo}/contents/{path} request. Returns null on 404 (not found) or network error rather than \WP_Error, making it safe to use as an existence check. On success, the content field in the returned array is base64-decoded to raw bytes.


delete_file()

core/class-git-api.php648-771

Two-step operation:

  1. Calls get_file($path) to retrieve the current SHA.
  2. Issues DELETE /repos/{repo}/contents/{path} with the SHA and commit message.

If the file is not found in step 1 (null returned), the method returns true silently — absence is treated as success. This handles cases where files were manually deleted from the repository. HTTP 404 during the DELETE itself is also treated as success.


get_rate_limit()

core/class-git-api.php778-808

Makes a GET /rate_limit request. Returns the full decoded JSON body, which includes core, search, and graphql rate limit buckets. Useful for diagnostics.


list_directory()

core/class-git-api.php820-873

Makes a GET /repos/{repo}/contents/{path}?ref={branch} request. Returns an array of file/directory objects. A 404 response returns an empty array rather than an error, as a missing directory is a normal condition (e.g., no images have been uploaded yet).


create_atomic_commit()

core/class-git-api.php886-990

The most complex public method. Uses the GitHub Git Data API to commit multiple files (content files and images) in a single atomic commit. This avoids multiple sequential commits per post sync.

Input: An associative array of path => content pairs and a commit message string.

Output: On success, an array containing commit_sha, tree_sha, files (array of paths), and message.


Atomic Commit Flow

The create_atomic_commit() method orchestrates six sequential steps, each delegated to a private helper. Failure at any step short-circuits with a \WP_Error.

Atomic commit step sequence


Sources: core/class-git-api.php886-990 core/class-git-api.php997-1424


Private Helper Methods for Atomic Commit

These methods are only used internally by create_atomic_commit(). Each calls parse_repo() first.

MethodHTTP MethodEndpointReturns
get_branch_ref()GET/repos/{owner}/{repo}/git/refs/heads/{branch}ref data array
get_commit_data($sha)GET/repos/{owner}/{repo}/git/commits/{sha}commit data array
create_blob($content)POST/repos/{owner}/{repo}/git/blobsblob SHA string
create_tree($items, $base)POST/repos/{owner}/{repo}/git/treestree SHA string
create_commit($msg, $tree, $parent)POST/repos/{owner}/{repo}/git/commitscommit SHA string
update_ref($commit_sha)PATCH/repos/{owner}/{repo}/git/refs/heads/{branch}ref data array

All blob content is base64-encoded before sending, allowing binary files (images) to be committed alongside text files (Markdown). Tree items use mode 100644 (regular file).

update_ref() sends "force": false, preventing force pushes.

Sources: core/class-git-api.php997-1424


Error Handling

Every public method follows the same pattern:

  1. Pre-flight check: Validate $this->token and $this->repo are set; return \WP_Error('missing_config', ...) immediately if not.
  2. Network check: If wp_remote_* returns a \WP_Error, pass it through directly or wrap it.
  3. HTTP status check: Evaluate the response code and return a specific \WP_Error with a meaningful code string and translatable message.
  4. Success: Return the typed success value (decoded JSON array, string SHA, or true).

Error handling flow


Sources: core/class-git-api.php265-423 core/class-git-api.php509-534 core/class-git-api.php580-615 core/class-git-api.php714-770


HTTP Timeouts

Timeouts vary by operation sensitivity:

OperationTimeout
test_connection15 s
get_branch_sha15 s
get_file15 s
get_rate_limit10 s
list_directory15 s
create_or_update_file60 s
delete_file (DELETE request)60 s
create_blob60 s
create_tree60 s
create_commit60 s
update_ref60 s
get_branch_ref30 s
get_commit_data30 s

Write operations use 60-second timeouts to accommodate slow networks when transferring binary image data.

Sources: core/class-git-api.php253-263 core/class-git-api.php493-507 core/class-git-api.php568-578 core/class-git-api.php784-795 core/class-git-api.php833-839 core/class-git-api.php1107-1114 core/class-git-api.php1193-1200 core/class-git-api.php1282-1289 core/class-git-api.php1367-1374