Skip to content

Add CI workflows for PHPUnit and coding standards#5

Open
koriym wants to merge 4 commits into
masterfrom
ci/add-phpunit-and-cs
Open

Add CI workflows for PHPUnit and coding standards#5
koriym wants to merge 4 commits into
masterfrom
ci/add-phpunit-and-cs

Conversation

@koriym

@koriym koriym commented Jul 19, 2026

Copy link
Copy Markdown
Member

Summary

Add CI following the ~/git/Ray.Aop setup, using the ray-di/.github reusable workflows (@v1).

  • .github/workflows/continuous-integration.yml — PHPUnit on PHP 8.2, 8.3, 8.4 (old stable) and 8.5 (current stable), matching composer.json (php: ^8.2).
  • .github/workflows/coding-standards.ymlphpcs on PHP 8.3.

Notes

  • script input omitted (no demo/run.php equivalent in this repo).
  • Static analysis, mutation testing, and branch coverage are intentionally out of scope for now (とりあえず phpunit + cs).
  • Existing update-copyright-years-in-license-file.yml is left untouched.

Summary by CodeRabbit

  • Chores

    • Added automated “Coding Standards”, “Continuous Integration”, and “Static Analysis” workflows covering multiple supported PHP versions.
    • Updated development tooling and Composer scripts to run PHPUnit, coding standards, and PHPStan consistently; clarified package description; ignored PHP-CS cache artifacts.
    • Replaced the previous formatting configuration with a PSR-12/Doctrine/Slevomat-based PHP-CS ruleset.
  • Refactor

    • Strengthened type hints across graph components (e.g., __toString(): string, : void) and normalized related syntax.
  • Tests

    • Standardized test method naming, signatures, and object construction.

Add continuous-integration.yml and coding-standards.yml calling the
ray-di/.github reusable workflows (@v1), following the Ray.Aop setup.

- PHPUnit: PHP 8.2, 8.3, 8.4 (old stable) and 8.5 (current stable)
- Coding Standards: phpcs on PHP 8.3
@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds PHPCS-based coding standards and reusable CI workflows, removes the PHP-CS-Fixer configuration, and modernizes PHP source signatures, imports, reflection handling, tests, PHPStan configuration, and Composer scripts.

Changes

Standards and source modernization

Layer / File(s) Summary
Coding standards and CI tooling
.github/workflows/*, .gitignore, composer.json, phpcs.xml, phpstan.neon
Adds reusable coding-standard, CI, and static-analysis workflows; switches development tooling from PHP-CS-Fixer to PHPCS; configures PHPStan; updates Composer scripts; and ignores PHPCS cache output.
Source type and symbol modernization
src/*.php
Adds explicit string and void return types, imports global functions/constants and reflection classes, updates PHPDoc annotations, and normalizes instantiation syntax.
Graph analysis adjustments and validation
src/ObjectGrapher.php, src/Prop.php, tests/ObjectVisualGrapherTest.php, tests/bin/package.php
Uses an early provider guard, updates reflection construction and exception handling, and aligns graph-generation tests and packaging code with the updated syntax.

Estimated code review effort: 3 (Moderate) | ~25 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.63% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main addition of CI workflows for PHPUnit and coding standards, even though static analysis is also included.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/add-phpunit-and-cs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Jul 19, 2026

Copy link
Copy Markdown

Welcome to Codecov 🎉

Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests.

Thanks for integrating Codecov - We've got you covered ☂️

composer.json:
- Add description, config.sort-packages, scripts-descriptions
- Drop friendsofphp/php-cs-fixer (v2 incompatible with PHP 8.5)
- Bump squizlabs/php_codesniffer to ^4.0, add
  slevomat/coding-standard, doctrine/coding-standard, and
  dealerdirect/phpcodesniffer-composer-installer
- Use bare commands (phpunit, phpcs, phpcbf); cs checks src tests,
  cs-fix runs phpcbf on src tests

phpcs.xml: copied from Ray.Aop, edited for this project (name, schema
path, project-specific excludes and patterns).

cs-fix results:
- phpcbf auto-fixed 181 violations across 16 files
- Added :string return type to all __toString() methods
- Removed empty if block in src/Arrow.php
- Renamed test__invoke* to testInvoke* (PSR1 CamelCaps)

Cleanup: remove orphaned .php_cs.dist, gitignore .phpcs-cache.

Verified: composer cs passes (20 files), composer test passes
(5 tests, 13 assertions).
@koriym
koriym marked this pull request as ready for review July 19, 2026 13:11

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (3)
.github/workflows/coding-standards.yml (1)

1-12: 🔒 Security & Privacy | 🔵 Trivial | 💤 Low value

Restrict default token permissions in GitHub Actions workflows.

Both workflows rely on default token permissions, which can be overly broad. Consider explicitly setting top-level permissions to adhere to the principle of least privilege.

  • .github/workflows/coding-standards.yml#L1-L12: add permissions: contents: read at the top level.
  • .github/workflows/continuous-integration.yml#L1-L13: add permissions: contents: read at the top level.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/coding-standards.yml around lines 1 - 12, Restrict GitHub
Actions token permissions to read-only repository contents by adding top-level
permissions with contents: read in .github/workflows/coding-standards.yml (lines
1-12) and .github/workflows/continuous-integration.yml (lines 1-13), alongside
the workflow name and triggers.

Source: Linters/SAST tools

src/DependencyId.php (1)

12-14: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Fix typo in parameter name.

The parameter name $interace is misspelled. Consider renaming it to $interface for better readability.

💡 Proposed refactor
-    public function __invoke(string $interace, string $name): string
+    public function __invoke(string $interface, string $name): string
     {
-        if (class_exists($interace)) {
-            return (new ClassId())($interace);
+        if (class_exists($interface)) {
+            return (new ClassId())($interface);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/DependencyId.php` around lines 12 - 14, Rename the misspelled $interace
parameter to $interface in __invoke, and update all references within the method
while preserving its behavior.
src/ObjectGrapher.php (1)

132-135: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Reuse the already extracted $arguments variable.

The reflection call on line 134 is redundant because the exact same value was already assigned to $arguments on line 132. You can safely reuse the variable here.

💡 Proposed refactor
         // constructor injection
         $arguments = ($this->prop)($dependency->arguments, 'arguments');
         $port = sprintf('p_%s_construct', ($this->snakeName)($dependency->class));
-        $setters = ($this->prop)($dependency->arguments, 'arguments') === [] ? [] : ['construct' => $port];
+        $setters = $arguments === [] ? [] : ['construct' => $port];
         $this->drawInjectionGraph($arguments, $dependency->classId, $port);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/ObjectGrapher.php` around lines 132 - 135, In the dependency graph setup,
update the `$setters` assignment in `ObjectGrapher` to reuse the already
extracted `$arguments` variable instead of calling `$this->prop` again. Preserve
the existing empty-arguments check and setter behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In @.github/workflows/coding-standards.yml:
- Around line 1-12: Restrict GitHub Actions token permissions to read-only
repository contents by adding top-level permissions with contents: read in
.github/workflows/coding-standards.yml (lines 1-12) and
.github/workflows/continuous-integration.yml (lines 1-13), alongside the
workflow name and triggers.

In `@src/DependencyId.php`:
- Around line 12-14: Rename the misspelled $interace parameter to $interface in
__invoke, and update all references within the method while preserving its
behavior.

In `@src/ObjectGrapher.php`:
- Around line 132-135: In the dependency graph setup, update the `$setters`
assignment in `ObjectGrapher` to reuse the already extracted `$arguments`
variable instead of calling `$this->prop` again. Preserve the existing
empty-arguments check and setter behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 905a67ca-c8ee-4cf8-a48e-3d6362068cc3

📥 Commits

Reviewing files that changed from the base of the PR and between e4ab97d and 47cda87.

📒 Files selected for processing (24)
  • .github/workflows/coding-standards.yml
  • .github/workflows/continuous-integration.yml
  • .gitignore
  • .php_cs.dist
  • composer.json
  • phpcs.xml
  • src/Arrow.php
  • src/ArrowInterface.php
  • src/ClassId.php
  • src/ClassNode.php
  • src/DependencyId.php
  • src/Graph.php
  • src/InstanceNode.php
  • src/InterfaceNode.php
  • src/MyDependency.php
  • src/NodeInterface.php
  • src/ObjectGrapher.php
  • src/Prop.php
  • src/ProviderNode.php
  • src/SnakeName.php
  • src/ToClass.php
  • src/ToProvider.php
  • tests/ObjectVisualGrapherTest.php
  • tests/bin/package.php
💤 Files with no reviewable changes (1)
  • .php_cs.dist

koriym added 2 commits July 19, 2026 22:43
- Upgrade phpstan/phpstan from ^0.12.5 to ^2.0; the 0.12 phar emitted
  PHP 8.5 deprecation noise from its own bundled Symfony console and
  hoa compiler and was effectively unusable on modern PHP.
- Populate phpstan.neon (was empty): level 8, phpVersion 80200,
  paths: [src]. Level 8 chosen over max because Prop::__invoke reads
  Ray.Di internal objects via reflection and returns mixed; the mixed
  assignments flagged at max stem from untyped upstream Ray.Di
  properties, not fixable here without ignoring/casting.
- Remove redundant assert( instanceof Argument) in
  ObjectGrapher::drawInjectionGraph(); the @param array<Argument>
  PHPDoc already narrows the type, flagged by PHPStan 2.x as
  function.alreadyNarrowedType / instanceof.alwaysTrue.
- composer tests: phpstan now reads level/paths from phpstan.neon.
- Add .github/workflows/static-analysis.yml running PHPStan in CI
  (cs2pr-annotated), on PHP 8.3.

Verified: composer cs (20/20), composer test (5 tests), phpstan
(level 8) all pass.
… plugin

CI failed on --prefer-lowest: bear/package ^1.9.6 resolves
bear/query-repository 1.6.0, whose QueryRepositoryModule binds
Doctrine\Common\Cache\Cache, but doctrine/cache is not installed ->
Ray\Di\Exception\NotFound in testInvokeBearPackage.

bear/package cannot be bumped to sidestep this: every bear/package
>= 1.10.10 self-requires ray/object-visual-grapher ^1.0, which is
circular for this repo's own dev install (root is dev-master).
So pin bear/query-repository ^1.13 instead -- 1.13.0 dropped the
Doctrine Cache binding and the doctrine/* requires. Tests pass at
both --prefer-lowest and highest.

Remove dealerdirect/phpcodesniffer-composer-installer from
require-dev (still pulled transitively by doctrine/coding-standard
and slevomat/coding-standard) and disable its plugin execution via
allow-plugins=false; register the external standards via
<config name=installed_paths> in phpcs.xml instead.

Drop the unused doctrine/annotations ^1.8 direct dev dependency.

Verified: composer cs (20/20), phpstan (level 8, no errors),
phpunit (5 tests) pass at both highest and --prefer-lowest.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/static-analysis.yml:
- Around line 8-16: Add read-only repository permissions to the phpstan job and
disable credential persistence in its actions/checkout step. Set the job’s
permissions to contents: read and add persist-credentials: false under the
existing checkout configuration.

In `@phpstan.neon`:
- Around line 4-5: Update the PHPStan paths configuration to include both src
and tests, preserving static analysis coverage for test files while retaining
the existing source analysis scope.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7b99d697-9b27-4d46-9e4d-edc85ff29d2e

📥 Commits

Reviewing files that changed from the base of the PR and between 47cda87 and 51ac398.

📒 Files selected for processing (5)
  • .github/workflows/static-analysis.yml
  • composer.json
  • phpcs.xml
  • phpstan.neon
  • src/ObjectGrapher.php
💤 Files with no reviewable changes (1)
  • src/ObjectGrapher.php
🚧 Files skipped from review as they are similar to previous changes (2)
  • phpcs.xml
  • composer.json

Comment on lines +8 to +16
jobs:
phpstan:
name: PHPStan
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== .github/workflows/static-analysis.yml ==\n'
wc -l .github/workflows/static-analysis.yml
cat -n .github/workflows/static-analysis.yml

printf '\n== workflow file references ==\n'
rg -n "permissions:|persist-credentials|actions/checkout|pull_request|phpstan|composer|dependency" .github/workflows -S

Repository: ray-di/Ray.ObjectGrapher

Length of output: 3014


🌐 Web query:

GitHub Actions default GITHUB_TOKEN permissions pull_request public repository actions/checkout persist-credentials default v4

💡 Result:

For new repositories created in personal accounts, the default permissions for the GITHUB_TOKEN are restricted to read-only access for the contents and packages scopes [1]. For new repositories owned by organizations, the default permissions are inherited from the organization's settings, which, for newly created organizations, default to read-only [1][2]. Users can manually configure these defaults to be more permissive in the repository or organization settings [1]. Regarding the actions/checkout (v4) action: - The persist-credentials input, which determines whether to configure the token or SSH key with the local git configuration, defaults to true [3][4]. - When persist-credentials is true, the action persists the authentication token in the local git config, enabling subsequent steps to run authenticated git commands [5][6]. This token is removed during post-job cleanup [5][6]. For pull requests, the GITHUB_TOKEN is subject to specific constraints: - Pull requests from public forks always receive a read-only token, regardless of the configured repository or workflow permissions [7][8]. - Workflows triggered by pull requests have access to the GITHUB_TOKEN, but you should adhere to the principle of least privilege by explicitly defining the necessary permissions in your workflow using the permissions key [7][9]. Any permissions omitted from the permissions key are set to none [7].

Citations:


Tighten this job’s token access. Add permissions: contents: read and set persist-credentials: false on actions/checkout; checkout persists the token in git config by default, and this job runs repository-controlled tooling.

🧰 Tools
🪛 zizmor (1.26.1)

[warning] 13-16: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/static-analysis.yml around lines 8 - 16, Add read-only
repository permissions to the phpstan job and disable credential persistence in
its actions/checkout step. Set the job’s permissions to contents: read and add
persist-credentials: false under the existing checkout configuration.

Source: Linters/SAST tools

Comment thread phpstan.neon
Comment on lines +4 to +5
paths:
- src No newline at end of file

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
git ls-files | rg '(^|/)(phpstan.*\.neon|\.github/workflows/.*\.ya?ml|composer\.json|package\.json)$' || true

echo
echo "== phpstan references =="
rg -n --hidden --glob '!vendor' --glob '!node_modules' 'phpstan|PHPStan' .

echo
echo "== phpstan.neon =="
if [ -f phpstan.neon ]; then cat -n phpstan.neon; fi

echo
echo "== phpstan-related workflow snippets =="
for f in $(git ls-files '.github/workflows/*' 2>/dev/null); do
  if rg -n 'phpstan|PHPStan' "$f" >/dev/null; then
    echo "--- $f ---"
    rg -n 'phpstan|PHPStan|tests|src' "$f"
  fi
done

Repository: ray-di/Ray.ObjectGrapher

Length of output: 1669


Keep tests in PHPStan’s analysis scope. phpstan.neon:4-5 now limits PHPStan to src, and the static-analysis job relies on that config, so test files are no longer analyzed. Add tests back unless dropping test coverage is intentional.

Proposed fix
     paths:
         - src
+        - tests
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
paths:
- src
paths:
- src
- tests
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@phpstan.neon` around lines 4 - 5, Update the PHPStan paths configuration to
include both src and tests, preserving static analysis coverage for test files
while retaining the existing source analysis scope.

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