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
111 changes: 111 additions & 0 deletions .github/workflows/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
name: Github Action for CI4 Settings and Feature Flag Library

on:
pull_request:
branches: [ "main", "develop" ]
# Manual runs from the Actions tab
workflow_dispatch:

Comment on lines +1 to +8

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 | 🟠 Major

Workflow file location will prevent it from running

This workflow is defined as .github/php-ci.yml in the PR, but GitHub Actions only loads workflows from .github/workflows/*.yml. Unless there is a planned move/rename, this file will not be picked up by GitHub, and the CI will never run. Consider moving it to .github/workflows/php-ci.yml (or similar).

🤖 Prompt for AI Agents
.github/php-ci.yml lines 1-10: the workflow file is placed at .github/php-ci.yml
which GitHub Actions does not load since workflows must live in
.github/workflows/*.yml; move/rename this file to .github/workflows/php-ci.yml
(or another name under .github/workflows/) so GitHub will detect and run the
workflow on push, pull_request, and workflow_dispatch events.

jobs:
tests:
name: "PHP ${{ matrix.php }} (deps: ${{ matrix.deps }})"
runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
php: [ "8.2" ]
deps: [ "stable" ]

Comment thread
coderabbitai[bot] marked this conversation as resolved.
env:
# Typical CI4 testing env values
APP_ENV: testing
CI_ENVIRONMENT: testing

steps:
# --- 1. Checkout code ---------------------------------------------------
- name: Checkout repository
uses: actions/checkout@v4

# --- 2. Setup PHP -------------------------------------------------------
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: mbstring, intl, json, pdo_mysql, sqlite3
ini-values: |
memory_limit=512M
coverage: none
tools: composer

# --- 3. Cache Composer dependencies ------------------------------------
- name: Get Composer cache directory
id: composer-cache
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT

- name: Cache Composer dependencies
uses: actions/cache@v4
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-php-${{ matrix.php }}-${{ matrix.deps }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: |
${{ runner.os }}-php-${{ matrix.php }}-${{ matrix.deps }}-composer-

# --- 4. Install dependencies -------------------------------------------
- name: Install Composer dependencies
run: |
if [ "${{ matrix.deps }}" = "lowest" ]; then
composer update --prefer-lowest --no-interaction --no-progress
else
composer install --no-interaction --no-progress --prefer-dist
fi

# --- 5. Prepare .env for CodeIgniter 4----------------------
# name it `.env.github-ci`
- name: Prepare .env
run: |
if [ -f .env.github-ci ]; then
cp .env.github-ci .env
elif [ -f env ]; then
cp env .env
fi

# --- 6. Basic PHP syntax check -----------------------------------------
- name: PHP syntax check (lint)
run: |
find src tests app -type f -name "*.php" 2>/dev/null \
| xargs -r -n 1 php -l

# --- 7. Run unit tests (PHPUnit) ---------------------------------------
- name: Run PHPUnit tests
run: |
if [ -f vendor/bin/phpunit ]; then
vendor/bin/phpunit --testdox
else
echo "PHPUnit not found. Did you require it as a dev dependency?" >&2
exit 1
fi

# --- 8. Static analysis (PHPStan) - optional ---------------------------
- name: Run PHPStan (if configured)
if: ${{ hashFiles('phpstan.neon*') != '' }}
run: |
if [ -f vendor/bin/phpstan ]; then
vendor/bin/phpstan analyse src tests --no-progress
fi

# --- 9. Coding standards (PHPCS) - optional ----------------------------
- name: Run PHPCS (if configured)
if: ${{ hashFiles('phpcs.xml*') != '' }}
run: |
if [ -f vendor/bin/phpcs ]; then
vendor/bin/phpcs
fi

# --- 10. PHP-CBF (dry-run) - optional -----------------------------
- name: Run PHP-CBF (dry-run, if configured)
if: ${{ hashFiles('.php-cs-fixer.dist.php', '.php-cs-fixer.php') != '' }}
run: |
if [ -f vendor/bin/phpcbf ]; then
vendor/bin/phpcbf
fi
Comment on lines +106 to +111

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

Mismatch between tool command and config files.

The step checks for .php-cs-fixer.dist.php (php-cs-fixer configuration), but line 112 executes vendor/bin/phpcbf, which is the executable for squizlabs/php_codesniffer—a different tool with incompatible configuration formats. The php-cs-fixer tool uses the command vendor/bin/php-cs-fixer fix --dry-run --diff. This mismatch will cause the step to fail or behave unexpectedly.

Apply this diff to use the correct command:

      - name: Run PHP-CBF (dry-run, if configured)
        if: ${{ hashFiles('.php-cs-fixer.dist.php', '.php-cs-fixer.php') != '' }}
        run: |
          if [ -f vendor/bin/php-cs-fixer ]; then
-           vendor/bin/phpcbf fix --dry-run --diff
+           vendor/bin/php-cs-fixer fix --dry-run --diff
          fi
📝 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
- name: Run PHP-CBF (dry-run, if configured)
if: ${{ hashFiles('.php-cs-fixer.dist.php', '.php-cs-fixer.php') != '' }}
run: |
if [ -f vendor/bin/phpcbf ]; then
vendor/bin/phpcbf fix --dry-run --diff
fi
- name: Run PHP-CBF (dry-run, if configured)
if: ${{ hashFiles('.php-cs-fixer.dist.php', '.php-cs-fixer.php') != '' }}
run: |
if [ -f vendor/bin/php-cs-fixer ]; then
vendor/bin/php-cs-fixer fix --dry-run --diff
fi
🤖 Prompt for AI Agents
.github/workflows/action.yml around lines 108 to 113: the step guarding on
php-cs-fixer config files mistakenly runs vendor/bin/phpcbf (phpcs-fixer vs
phpcbf mismatch); change the executed binary to vendor/bin/php-cs-fixer and keep
the same flags (fix --dry-run --diff) so the command matches the checked config
files and the intended tool.

9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,10 @@
.idea/
vendor/
var/
*.cache
composer.lock
.DS_Store
.vscode/
phpunit
build/
phpunit*.xml
30 changes: 30 additions & 0 deletions .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

use PhpCsFixer\Config;
use PhpCsFixer\Finder;
use PhpCsFixer\Runner\Parallel\ParallelConfigFactory;

return (new Config())
->setParallelConfig(ParallelConfigFactory::detect()) // @TODO 4.0 no need to call this manually
->setRiskyAllowed(false)
->setRules([
'@auto' => true
])
// 💡 by default, Fixer looks for `*.php` files excluding `./vendor/` - here, you can groom this config
->setFinder(
(new Finder())
// 💡 root folder to check
->in(__DIR__)
// 💡 additional files, eg bin entry file
// ->append([__DIR__.'/bin-entry-file'])
// 💡 folders to exclude, if any
// ->exclude([/* ... */])
// 💡 path patterns to exclude, if any
// ->notPath([/* ... */])
// 💡 extra configs
// ->ignoreDotFiles(false) // true by default in v3, false in v4 or future mode
// ->ignoreVCSIgnored(true) // true by default
)
;
38 changes: 35 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,40 @@
"Jide\\Settings\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Jide\\Settings\\Tests\\": "tests/"
}
},
"require": {
"php": "^8.0",
"codeigniter4/framework": "^4.0"
}
"php": "^8.2"
},
Comment on lines 16 to +18

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 | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

CodeIgniter 4 official PHP version support requirements latest release

💡 Result:

Short answer

  • CodeIgniter 4 (latest stable v4.6.3) requires PHP 8.1 or newer. [1][2]

Compatibility notes

  • PHP 8.1: minimum for CI4. [1]
  • PHP 8.2 requires CI 4.2.11 or later. [1]
  • PHP 8.3 requires CI 4.4.4 or later. [1]
  • PHP 8.4 requires CI 4.6.0 or later. [1]

Sources

  1. CodeIgniter 4 — Server requirements (official User Guide). [1]
  2. CodeIgniter download page (shows latest v4.6.3 and PHP 8.1+). [2]

Confirm intentional drop of PHP 8.1 support

Raising the requirement to "php": "^8.2" drops support for PHP 8.1, which is the minimum version officially supported by CodeIgniter 4. Your CI matrix (8.2 and 8.3) aligns with CodeIgniter 4's supported versions—note that CodeIgniter 4 v4.4.4+ supports PHP 8.3. Consider whether you intentionally want to require PHP 8.2+ rather than CodeIgniter 4's minimum of 8.1.

🤖 Prompt for AI Agents
In composer.json around lines 16-18 the PHP requirement was raised to "php":
"^8.2", which removes PHP 8.1 support; if that was not intentional, change the
constraint back to "php": "^8.1" to maintain CodeIgniter 4 compatibility, update
the CI matrix and README to reflect supported PHP versions, or if you do intend
to drop 8.1, add a short justification in the PR description and project docs
stating the intentional minimum of PHP 8.2 and the reason (e.g., using 8.2-only
features).

"require-dev": {
"codeigniter4/framework": "^4.0",
"phpunit/phpunit": "^10.0",
"phpstan/phpstan": "^1.11",
"phpstan/phpstan-phpunit": "^1.4",
"squizlabs/php_codesniffer": "^3.9",
"friendsofphp/php-cs-fixer": "^3.0",
"systemsdk/phpcpd": "^7.0.1"
},
"scripts": {
"test": "phpunit --testdox",
"analyse": "phpstan analyse src tests",
"deduplicate": "phpcpd src/ tests/",
"cs": "phpcs",
"cs-fix": "phpcbf",
"style": "@cs-fix",
"ci": [
"@cs",
"@deduplicate",
"@analyse",
"@test"
]
},
Comment on lines +19 to +41

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 | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

squizlabs php_codesniffer command-line executables phpcs phpcbf

💡 Result:

Summary — phpcs and phpcbf (squizlabs/php_codesniffer)

  • What they are:

    • phpcs — PHP_CodeSniffer command-line tool that tokenizes files and reports coding-standard violations. [1]
    • phpcbf — "PHP Code Beautifier and Fixer" that attempts to automatically fix violations reported by phpcs. [1][2]
  • How to run them:

    • PHAR downloads:
      • curl/wget phpcs.phar and phpcbf.phar, then run with PHP: php phpcs.phar and php phpcbf.phar . [1][2]
    • Composer (recommended):
      • Project local: composer require --dev squizlabs/php_codesniffer → run ./vendor/bin/phpcs and ./vendor/bin/phpcbf. [1][2]
      • Global: composer global require squizlabs/php_codesniffer → add Composer global bin dir (e.g. ~/.composer/vendor/bin or composer global config bin-dir --absolute) to PATH so phpcs/phpcbf are available system-wide (Windows installs include .bat wrappers). [1][2][3]
    • Git clone / source: php bin/phpcs and php bin/phpcbf from the cloned repo. [1][2]
  • Typical executable locations:

    • ./vendor/bin/phpcs, ./vendor/bin/phpcbf (project). [1][2]
    • ~/.composer/vendor/bin/ (or Composer bin-dir) for global installs; Windows may use .bat files in that bin dir. [1][2][7]
  • Quick examples:

    • Check code: phpcs --standard=PSR12 path/to/code. [1]
    • Auto-fix: phpcbf --standard=PSR12 path/to/code. [1][6]

Sources:
[1] squizlabs/PHP_CodeSniffer (README/installation).
[2] PHPCSStandards/PHP_CodeSniffer (GitHub docs & PHAR instructions).
[3] VS Code extension docs / community guides on locating phpcs/phpcbf.
[4] Additional install/usage docs (examples for Composer/Phive/PEAR).


🌐 Web query:

friendsofphp php-cs-fixer command-line executable php-cs-fixer

💡 Result:

Short answer — php-cs-fixer is a CLI PHAR/composer package. Common ways to get the php-cs-fixer executable and how to run it:

  • Per-project (recommended):

    • Install: composer require --dev friendsofphp/php-cs-fixer
    • Run: ./vendor/bin/php-cs-fixer fix . [1][3]
  • Global Composer install:

    • composer global require friendsofphp/php-cs-fixer
    • Make sure Composer's global vendor bin (e.g. $HOME/.composer/vendor/bin or $HOME/.config/composer/vendor/bin) is in your PATH, then run php-cs-fixer. [1][8]
  • PHAR / manual executable:

    • Download PHAR (example): curl -L https://cs.symfony.com/download/php-cs-fixer-v3.phar -o php-cs-fixer
    • Make executable and move to a bin dir: chmod a+x php-cs-fixer && sudo mv php-cs-fixer /usr/local/bin/php-cs-fixer
    • Run: php-cs-fixer fix (or just php-cs-fixer if moved into PATH). [1][3][5]
  • Other options: Homebrew, Docker, or phive; project docs list available installation methods. [1][3]

Docs/references: [1] Symfony docs (php-cs-fixer installation). [2] PHP-CS-Fixer GitHub. [3] Older install/PHAR instructions and examples.


🏁 Script executed:

# Check the current state of composer.json to verify the claims
cat -n composer.json | head -50

Repository: olajideolamide/ci4-settings

Length of output: 1443


🏁 Script executed:

# Look for the CI file mentioned (.github/php-ci.yml)
find . -name "*ci*.yml" -o -name "*ci*.yaml" | head -20

Repository: olajideolamide/ci4-settings

Length of output: 91


🏁 Script executed:

# Check the CI file contents
cat -n ./.github/php-ci.yml

Repository: olajideolamide/ci4-settings

Length of output: 4700


🌐 Web query:

phpcbf command-line options syntax dry-run diff squizlabs php_codesniffer

💡 Result:

Short answer: phpcbf itself does not provide a standard --dry-run/--diff switch to preview changes; use phpcs' diff report or safe phpcbf modes (suffix, STDIN, VCS) to preview changes before applying.

Key points + examples

  • Basic phpcbf usage:

    • phpcbf [options] <file|dir> ... . Options include --standard, --extensions, --tab-width, --encoding, --processes, --suffix, --basepath, filters, severity, etc. [1][2]
  • Preview changes (recommended)

    1. Generate a unified diff with phpcs and review it (no files changed):
      • phpcs --report=diff /path/to/code > changes.diff
      • Review changes.diff or apply with patch if desired. (phpcs prints diffs that show what phpcbf would change). [1]
    2. Use phpcbf but avoid overwriting originals:
      • phpcbf --suffix=".orig" /path/to/code # writes modified files with the given suffix so originals remain. (phpcbf supports --suffix). [1][3]
    3. Use version control (git): run phpcbf and then inspect git diff / stage/undo as needed — safest in CI or local dev workflow.
  • Why there’s no simple --dry-run flag on phpcbf

    • The docs/wiki describe generating diffs via phpcs' --report=diff and note phpcbf will automatically apply fixes; phpcbf’s CLI options focus on how fixes are applied (suffix, processes, severity, filters), not a dedicated dry-run flag. Use phpcs --report=diff to preview. [1][3]

References

  1. PHPCS "Fixing Errors Automatically" / phpcbf usage (wiki). [squizlabs / PHP_CodeSniffer]. [1]
  2. Official repository / README and usage (squizlabs / PHPCS and successor PHPCSStandards). [2]
  3. phpcbf manpage / Debian packaging options (lists --suffix, filter, processes, etc.). [3]

If you want, I can give exact commands for your repo (git-aware preview, a one-liner producing diffs, or a small script that runs phpcs -> phpcbf safely).


Align code style tools between require-dev, composer scripts, and CI

You require both squizlabs/php_codesniffer and friendsofphp/php-cs-fixer, but they serve overlapping purposes:

  • scripts.cs runs phpcs (CodeSniffer checker)
  • scripts.cs-fix runs phpcbf (CodeSniffer's fixer)
  • .github/php-ci.yml step 10 is labeled "Run PHP-CS-Fixer (dry-run, if configured)" but calls vendor/bin/phpcbf fix --dry-run --diff — which is invalid syntax for phpcbf (it has no fix subcommand or --dry-run flag)

This makes friendsofphp/php-cs-fixer effectively unused and creates a broken CI step. Consider one of:

  1. Use PHP-CS-Fixer as the primary style tool

    Update composer scripts to call php-cs-fixer and fix the CI step:

    "scripts": {
  • "cs": "phpcs",
  • "cs-fix": "phpcbf",
  • "cs": "php-cs-fixer fix --dry-run --diff",
  • "cs-fix": "php-cs-fixer fix",
    "style": "@cs-fix",
    }

Update CI step 10 to correctly call `vendor/bin/php-cs-fixer fix --dry-run --diff`, and remove `squizlabs/php_codesniffer`.

2. **Use PHPCS/PHPCBF only**

- Remove `friendsofphp/php-cs-fixer` and any `.php-cs-fixer.*` config files.
- Fix CI step 10 to use `vendor/bin/phpcs` for checking (similar to step 9) or remove the step entirely.

Picking one approach will simplify maintenance and make the CI step functional.



> Committable suggestion skipped: line range outside the PR's diff.

<details>
<summary>🤖 Prompt for AI Agents</summary>

In composer.json at lines 19-41, the repo mixes PHPCS (phpcs/phpcbf) and
PHP-CS-Fixer and the CI step 10 is calling an invalid phpcbf command; fix by
choosing one tool: either (A) make PHP-CS-Fixer the canonical style tool —
remove squizlabs/php_codesniffer from require-dev, update scripts.cs and
scripts.cs-fix to invoke vendor/bin/php-cs-fixer (e.g., "php-cs-fixer" and a fix
command), and change .github/php-ci.yml step 10 to call vendor/bin/php-cs-fixer
fix --dry-run --diff; or (B) keep PHPCS/PHPCBF only — remove
friendsofphp/php-cs-fixer and any php-cs-fixer config, and update CI step 10 to
use vendor/bin/phpcs (or remove that step) so no invalid phpcbf flags are used;
apply the chosen change consistently across composer scripts and CI.


</details>

<!-- fingerprinting:phantom:poseidon:olive -->

<!-- This is an auto-generated comment by CodeRabbit -->

"config": {
"sort-packages": true
},
"minimum-stability": "stable",
"prefer-stable": true
}
38 changes: 38 additions & 0 deletions phpcs.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?xml version="1.0"?>
<ruleset name="CodeIgniter 4 Settings Library Standard">
<description>
Coding standard for the CI4 Settings / Feature Flag library.
Applies PSR-12 to src/ and tests/ while ignoring vendor and build artifacts.
</description>
Comment on lines +3 to +6

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 | 🟡 Minor

Clarify the library description.

The description mentions "CI4 Settings / Feature Flag library", but the PR title and context suggest this is primarily a settings library. If feature flags are a core part of this library, this is fine; otherwise, consider simplifying to "CI4 Settings Library".

🤖 Prompt for AI Agents
phpcs.xml around lines 3 to 6: the <description> currently reads "Coding
standard for the CI4 Settings / Feature Flag library" which may misrepresent
scope; update the description to accurately reflect the repository (e.g.,
"Coding standard for the CI4 Settings Library") or, if feature flags are indeed
core, make that explicit (e.g., "CI4 Settings and Feature Flags Library");
change only the text inside the <description> element to this clarified wording
and ensure it matches the PR title/context.


<!-- Directories to scan -->
<file>src</file>
<file>tests</file>

<!-- Exclusions -->
<exclude-pattern>vendor/*</exclude-pattern>
<exclude-pattern>var/*</exclude-pattern>
<exclude-pattern>build/*</exclude-pattern>
<exclude-pattern>.phpunit.cache/*</exclude-pattern>
<exclude-pattern>.phpstan/*</exclude-pattern>

<!-- Global options -->
<arg name="colors"/>
<arg name="encoding" value="utf-8"/>
<arg name="extensions" value="php"/>
<arg name="parallel" value="4"/>

<!-- Base standard -->
<rule ref="PSR12">
<!-- Optional relaxations: -->

<!-- Ignore long lines (useful for long arrays, SQL, etc.) -->
<exclude name="Generic.Files.LineLength.TooLong"/>

<!-- Allow tabs in indentation -->
<!-- <exclude name="Generic.WhiteSpace.DisallowTabIndent.TabsUsed"/> -->
</rule>

<!-- Extra generic rules (optional) -->
<rule ref="Generic.Commenting.Todo"/>
</ruleset>
32 changes: 32 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
includes:
# Extra rules for PHPUnit test classes (optional but nice)
- vendor/phpstan/phpstan-phpunit/extension.neon

parameters:
level: 5

paths:
- src
- tests

tmpDir: var/phpstan

# Ensure Composer autoload is loaded so all classes are known
bootstrapFiles:
- vendor/autoload.php
- vendor/codeigniter4/framework/system/Test/bootstrap.php

# Some stricter checks that are very useful
checkMissingIterableValueType: true
checkGenericClassInNonGenericObjectType: true
checkMissingVarTagTypehint: true
reportUnmatchedIgnoredErrors: true

# Option to relax PHPDoc certainty
treatPhpDocTypesAsCertain: false

# Prevents CodeIgniter dynamic properties/magic,
# from causing PHPStan to scream too much
#ignoreErrors:
#- '#^Call to an undefined method CodeIgniter\\.*#'
#- '#^Access to an undefined property CodeIgniter\\.*#'
46 changes: 46 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd"
bootstrap="vendor/autoload.php"
cacheDirectory=".phpunit.cache"
colors="true"
executionOrder="depends,defects"
beStrictAboutChangesToGlobalState="true"
displayDetailsOnTestsThatTriggerWarnings="true"
failOnWarning="false"
>
<testsuites>
<testsuite name="Unit">
<directory suffix="Test.php">tests</directory>
</testsuite>
</testsuites>

<source>
<include>
<directory suffix=".php">src</directory>
</include>
<exclude>
<directory>vendor</directory>
<directory>tests</directory>
</exclude>
</source>

<!-- PHP + CI4-related env -->
<php>


<!-- common CI4 testing env flags -->
<env name="APP_ENV" value="testing"/>
<env name="CI_ENVIRONMENT" value="testing"/>

<!-- useful if anything -->
<env name="app.baseURL" value="http://localhost/"/>

<!-- testDB:
<env name="database.default.DBDriver" value="SQLite3"/>
<env name="database.default.database" value=":memory:"/>
-->
</php>

</phpunit>
Loading