Skip to content

feat: Add GitHub Releases API support#9

Merged
ralflang merged 1 commit intoFRAMEWORK_6_0from
feat/github-releases
Feb 26, 2026
Merged

feat: Add GitHub Releases API support#9
ralflang merged 1 commit intoFRAMEWORK_6_0from
feat/github-releases

Conversation

@ralflang
Copy link
Member

Summary

Add comprehensive support for the GitHub Releases API, enabling creation, retrieval, updates, and asset uploads for releases.

Features

API Methods (4 new)

  • createRelease() - Create a new release for an existing tag
  • getReleaseByTag() - Retrieve a release by tag name
  • updateRelease() - Update release metadata (name, body, draft/prerelease status)
  • uploadReleaseAsset() - Upload binary assets (zips, tarballs, executables, etc.) to releases

Value Objects

  • GithubRelease - Represents a release with 12 properties including assets array
  • GithubReleaseAsset - Represents uploaded assets with 10 properties (id, name, size, download count, etc.)

DTOs

  • CreateReleaseParams
    • Required: tagName
    • Optional: name, body, draft, prerelease, targetCommitish
  • UpdateReleaseParams
    • All fields optional: tagName, name, body, draft, prerelease
    • Includes isEmpty() helper method

Request Factories

  • CreateReleaseRequestFactory - POST /repos/{owner}/{repo}/releases
  • GetReleaseByTagRequestFactory - GET /repos/{owner}/{repo}/releases/tags/{tag}
  • UpdateReleaseRequestFactory - PATCH /repos/{owner}/{repo}/releases/{id}
  • UploadReleaseAssetRequestFactory - POST to upload_url (handles template URL format)

Implementation Details

  • Follows existing codebase patterns:
    • Request Factory pattern for API endpoints
    • Value Objects with fromApiResponse() static factories
    • DTOs with toArray() for request payloads
  • StreamFactory requirement for write operations (create, update, upload)
  • Proper URL encoding for tag names
  • Handles GitHub's template URLs for asset uploads

Dependencies Added

  • psr/http-client ^1.0 (PSR-18)
  • psr/http-factory ^1.0 (PSR-17)
  • psr/http-message ^2.0 (PSR-7)

Testing

Test Coverage

  • 58 new unit tests covering all release functionality
  • Total: 143 tests, 478 assertions, all passing

Test Categories

  • DTOs: construction, toArray(), validation
  • Value Objects: fromApiResponse() with complete/minimal/edge case data
  • GithubApiClient methods: success cases, error cases (404, 422, 401, 403)
  • StreamFactory requirement validation
  • Multiple assets handling
  • Different content types and states

Example Usage

use Horde\GithubApiClient\GithubApiClient;
use Horde\GithubApiClient\GithubRepository;
use Horde\GithubApiClient\CreateReleaseParams;

// Create a release
$repo = GithubRepository::fromFullName('horde/GithubApiClient');
$params = new CreateReleaseParams(
    tagName: 'v1.0.0',
    name: 'Version 1.0.0',
    body: 'First stable release',
    draft: false,
    prerelease: false
);
$release = $client->createRelease($repo, $params);

// Upload an asset
$asset = $client->uploadReleaseAsset(
    uploadUrl: $release->uploadUrl,
    filename: 'release.zip',
    fileContent: file_get_contents('release.zip'),
    contentType: 'application/zip'
);

// Update release
$updateParams = new UpdateReleaseParams(
    body: 'Updated release notes'
);
$updated = $client->updateRelease($repo, $release->id, $updateParams);

// Get release by tag
$release = $client->getReleaseByTag($repo, 'v1.0.0');

Checklist

  • Implementation follows existing patterns
  • All methods have proper type hints
  • Comprehensive unit tests (100% coverage for new code)
  • All tests passing
  • PSR standards followed (PSR-7, PSR-17, PSR-18)
  • Conventional Commit message format
  • Documentation in code (PHPDoc)

Add comprehensive support for GitHub Releases API with the following features:

- Create releases for existing tags
- Get release by tag name
- Update existing releases
- Upload assets to releases

New value objects:
- GithubRelease: represents a GitHub release with all metadata
- GithubReleaseAsset: represents uploaded release assets

New DTOs:
- CreateReleaseParams: parameters for creating a release (tagName, name, body, draft, prerelease, targetCommitish)
- UpdateReleaseParams: parameters for updating a release (all fields optional)

New request factories:
- CreateReleaseRequestFactory: POST /repos/{owner}/{repo}/releases
- GetReleaseByTagRequestFactory: GET /repos/{owner}/{repo}/releases/tags/{tag}
- UpdateReleaseRequestFactory: PATCH /repos/{owner}/{repo}/releases/{id}
- UploadReleaseAssetRequestFactory: POST to upload_url with file content

Added 4 methods to GithubApiClient:
- createRelease(): create a new release
- getReleaseByTag(): retrieve release by tag name
- updateRelease(): update release metadata
- uploadReleaseAsset(): upload binary assets to a release

Dependencies:
- Added PSR-7 (psr/http-message)
- Added PSR-17 (psr/http-factory)
- Added PSR-18 (psr/http-client)

Tests:
- 58 new unit tests covering all release functionality
- Tests for DTOs, value objects, request factories, and client methods
- Tests for error cases (404, 422, missing StreamFactory)
- All tests passing (143 total tests, 478 assertions)

The implementation follows established patterns from the codebase:
- Request Factory pattern for API endpoints
- Value Objects with fromApiResponse() static factories
- DTOs with toArray() for request payloads
- StreamFactory requirement for write operations
@ralflang ralflang merged commit a32f095 into FRAMEWORK_6_0 Feb 26, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant