Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,24 @@ jobs:

- name: Run tests
run: vendor/bin/pest

coverage:
runs-on: ubuntu-latest
name: Code Coverage

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.3
extensions: dom, curl, libxml, mbstring, zip
coverage: pcov

- name: Install dependencies
run: composer install --prefer-dist --no-interaction --no-progress

- name: Run tests with coverage
run: vendor/bin/pest --coverage --min=100
8 changes: 6 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@
"require-dev": {
"laravel/pint": "^1.0",
"pestphp/pest": "^3.0",
"phpstan/phpstan": "^1.0"
"phpstan/extension-installer": "*",
"phpstan/phpstan": "^1.0",
"phpstan/phpstan-deprecation-rules": "^1.2",
"phpstan/phpstan-strict-rules": "^1.6"
},
"autoload": {
"psr-4": {
Expand All @@ -40,7 +43,8 @@
"preferred-install": "dist",
"optimize-autoloader": true,
"allow-plugins": {
"pestphp/pest-plugin": true
"pestphp/pest-plugin": true,
"phpstan/extension-installer": true
}
},
"extra": {
Expand Down
6 changes: 2 additions & 4 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
parameters:
level: 8
level: 9
paths:
- src
excludePaths:
# Excluded because it depends on Laravel's ServiceProvider which isn't available
# in the non-Laravel test environment. The class is only used in Laravel apps.
- src/PrServiceProvider.php
tmpDir: build/phpstan
ignoreErrors:
-
identifier: missingType.iterableValue
reportUnmatchedIgnoredErrors: true
4 changes: 4 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,9 @@
<include>
<directory>src</directory>
</include>
<exclude>
<file>src/PrServiceProvider.php</file>
<directory>src/Contracts</directory>
</exclude>
Comment on lines +18 to +21
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Examine PrServiceProvider and CI coverage configuration

# Check if the file exists and show its contents
if [ -f "src/PrServiceProvider.php" ]; then
  echo "=== PrServiceProvider.php ==="
  cat -n src/PrServiceProvider.php
else
  echo "File not found: src/PrServiceProvider.php"
fi

# Check for CI configuration files
echo -e "\n=== Checking for CI configuration ==="
for f in .github/workflows/*.yml .github/workflows/*.yaml .gitlab-ci.yml .circleci/config.yml; do
  if [ -f "$f" ]; then
    echo -e "\n--- $f ---"
    grep -A 5 -B 2 "coverage\|100%" "$f" || echo "No coverage threshold found in this file"
  fi
done

# Check phpunit.xml for coverage configuration context
echo -e "\n=== phpunit.xml context ==="
if [ -f "phpunit.xml" ]; then
  cat -n phpunit.xml
fi

Repository: conduit-ui/pr

Length of output: 4502


Remove the exclusion or add tests for src/PrServiceProvider.php to align with the 100% coverage CI requirement.

The CI workflow enforces --min=100 code coverage, but phpunit.xml excludes src/PrServiceProvider.php from coverage analysis. This file contains testable logic in the register() method (singleton bindings with conditional token validation), boot() method (facade configuration), and resolveToken() private method (token resolution from multiple sources). Either remove the exclusion and add corresponding unit tests, or adjust the CI coverage threshold to account for excluded files.

🤖 Prompt for AI Agents
In phpunit.xml around lines 18–20, the file src/PrServiceProvider.php is
excluded from coverage which conflicts with the repository's --min=100 CI rule;
either remove the <exclude> entry so PHPUnit measures that file, or keep it
excluded but update CI coverage threshold to account for exclusions. If you
remove the exclusion, add unit tests that instantiate the app/container and the
PrServiceProvider and exercise register() (verify singleton bindings and
conditional token validation via config/env/request mocks), boot() (verify
facade configuration), and token resolution (exercise resolveToken via
integration-like tests that set headers/env/config/request to cover all
branches). If you choose to lower CI threshold, update the CI workflow config to
a new --min value and document the change.

</source>
</phpunit>
27 changes: 27 additions & 0 deletions src/Contracts/Assignable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace ConduitUI\Pr\Contracts;

/**
* Interface for entities that can have assignees.
*
* Implemented by: Issue, PullRequest
*/
interface Assignable
{
/**
* Assign users to this entity.
*
* @param array<int, string> $assignees Usernames to assign
*/
public function assign(array $assignees): static;

/**
* Remove assignees from this entity.
*
* @param array<int, string> $assignees Usernames to unassign
*/
public function unassign(array $assignees): static;
}
20 changes: 20 additions & 0 deletions src/Contracts/Auditable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace ConduitUI\Pr\Contracts;

/**
* Interface for entities that have an audit trail / timeline.
*
* Implemented by: Issue, PullRequest
*/
interface Auditable
{
/**
* Get the timeline of events for this entity.
*
* @return array<int, mixed>
*/
public function timeline(): array;
}
22 changes: 22 additions & 0 deletions src/Contracts/Checkable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace ConduitUI\Pr\Contracts;

use ConduitUI\Pr\DataTransferObjects\CheckRun;

/**
* Interface for entities that can have CI check runs.
*
* Implemented by: PullRequest (via head commit), Commit
*/
interface Checkable
{
/**
* Get all check runs for this entity.
*
* @return array<int, CheckRun>
*/
public function checks(): array;
}
23 changes: 23 additions & 0 deletions src/Contracts/Closeable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace ConduitUI\Pr\Contracts;

/**
* Interface for entities that can be opened and closed.
*
* Implemented by: Issue, PullRequest
*/
interface Closeable
{
/**
* Close this entity.
*/
public function close(): static;

/**
* Reopen this entity.
*/
public function reopen(): static;
}
27 changes: 27 additions & 0 deletions src/Contracts/Commentable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace ConduitUI\Pr\Contracts;

use ConduitUI\Pr\DataTransferObjects\Comment;

/**
* Interface for entities that can have comments.
*
* Implemented by: Issue, PullRequest, Commit, Review
*/
interface Commentable
{
/**
* Get all comments on this entity.
*
* @return array<int, Comment>
*/
public function comments(): array;

/**
* Add a comment to this entity.
*/
public function comment(string $body): static;
}
27 changes: 27 additions & 0 deletions src/Contracts/Diffable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace ConduitUI\Pr\Contracts;

use ConduitUI\Pr\DataTransferObjects\File;

/**
* Interface for entities that have a diff (changed files).
*
* Implemented by: PullRequest, Commit
*/
interface Diffable
{
/**
* Get the raw diff text.
*/
public function diff(): string;

/**
* Get the list of changed files.
*
* @return array<int, File>
*/
public function files(): array;
}
22 changes: 22 additions & 0 deletions src/Contracts/HasCommits.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace ConduitUI\Pr\Contracts;

use ConduitUI\Pr\DataTransferObjects\Commit;

/**
* Interface for entities that have commits.
*
* Implemented by: PullRequest
*/
interface HasCommits
{
/**
* Get all commits for this entity.
*
* @return array<int, Commit>
*/
public function commits(): array;
}
25 changes: 25 additions & 0 deletions src/Contracts/Labelable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace ConduitUI\Pr\Contracts;

/**
* Interface for entities that can have labels.
*
* Implemented by: Issue, PullRequest
*/
interface Labelable
{
/**
* Add labels to this entity.
*
* @param array<int, string> $labels
*/
public function addLabels(array $labels): static;

/**
* Remove a label from this entity.
*/
public function removeLabel(string $label): static;
}
20 changes: 20 additions & 0 deletions src/Contracts/Mergeable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace ConduitUI\Pr\Contracts;

/**
* Interface for entities that can be merged.
*
* Implemented by: PullRequest
*/
interface Mergeable
{
/**
* Merge this entity.
*
* @param string $method merge, squash, or rebase
*/
public function merge(string $method = 'merge', ?string $title = null, ?string $message = null): static;
}
10 changes: 10 additions & 0 deletions src/Contracts/PrServiceInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,27 @@ interface PrServiceInterface
{
public function find(string $repository, int $number): PullRequest;

/**
* @param array<string, mixed> $attributes
*/
public function create(string $repository, array $attributes): PullRequest;

public function for(string $repository): QueryBuilder;

public function query(): QueryBuilder;

/**
* @param array<string, mixed> $data
*/
public function update(string $repository, int $number, array $data): PullRequest;

public function merge(string $repository, int $number, ?string $commitMessage = null, ?string $mergeMethod = null): bool;

public function close(string $repository, int $number): PullRequest;

/**
* @param array<string, mixed> $filters
* @return array<int, PullRequest>
*/
public function list(string $repository, array $filters = []): array;
}
40 changes: 40 additions & 0 deletions src/Contracts/Reviewable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

declare(strict_types=1);

namespace ConduitUI\Pr\Contracts;

use ConduitUI\Pr\DataTransferObjects\Review;

/**
* Interface for entities that can receive code reviews.
*
* Implemented by: PullRequest
*/
interface Reviewable
{
/**
* Get all reviews for this entity.
*
* @return array<int, Review>
*/
public function reviews(): array;

/**
* Approve this entity.
*/
public function approve(?string $body = null): static;

/**
* Request changes on this entity.
*/
public function requestChanges(string $body): static;

/**
* Submit a review with a specific event type.
*
* @param string $event APPROVE, REQUEST_CHANGES, or COMMENT
* @param array<int, array{path: string, line: int, body: string}> $comments Inline comments
*/
public function submitReview(string $event, ?string $body = null, array $comments = []): static;
}
6 changes: 6 additions & 0 deletions src/DataTransferObjects/Base.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ public function __construct(
public readonly Repository $repo,
) {}

/**
* @param array{ref: string, sha: string, user: array{id: int, login: string, avatar_url: string, html_url: string, type: string}, repo: array{id: int, name: string, full_name: string, html_url: string, private: bool}} $data
*/
public static function fromArray(array $data): self
{
return new self(
Expand All @@ -23,6 +26,9 @@ public static function fromArray(array $data): self
);
}

/**
* @return array<string, mixed>
*/
public function toArray(): array
{
return [
Expand Down
Loading