Звіт у форматі JSON машиночитний
{
"data": {
"repo": {
"topics": [],
"is_fork": false,
"size_kb": 110,
"has_wiki": false,
"homepage": null,
"languages": {
"PHP": 44230
},
"pushed_at": "2026-07-28T13:17:56Z",
"created_at": "2021-01-07T23:14:42Z",
"owner_type": "Organization",
"updated_at": "2026-07-28T13:21:15Z",
"description": "[READ ONLY] Subtree split of Flarum's backend testing utility library.",
"is_archived": false,
"is_disabled": false,
"license_spdx": "MIT",
"default_branch": "2.x",
"license_spdx_raw": "MIT",
"primary_language": "PHP",
"significant_languages": [
"PHP"
]
},
"owner": {
"blog": "http://flarum.org",
"name": "Flarum",
"type": "Organization",
"login": "flarum",
"company": null,
"location": null,
"followers": 798,
"avatar_url": "https://avatars.githubusercontent.com/u/5549034?v=4",
"created_at": "2013-09-26T11:15:45Z",
"is_verified": null,
"public_repos": 53,
"account_age_days": 4688
},
"license": {
"state": "standard",
"spdx_id": "MIT",
"raw_spdx": "MIT",
"file_present": true,
"scorecard_found": true,
"profile_has_license": true
},
"activity": {
"releases": [
{
"tag": "v2.0.0-rc.5",
"kind": "prerelease",
"published_at": "2026-07-08T15:55:02Z"
},
{
"tag": "v2.0.0-rc.4",
"kind": "prerelease",
"published_at": "2026-06-18T11:59:55Z"
},
{
"tag": "v2.0.0-rc.3",
"kind": "prerelease",
"published_at": "2026-06-09T18:54:15Z"
},
{
"tag": "v2.0.0-rc.2",
"kind": "prerelease",
"published_at": "2026-06-01T18:18:07Z"
},
{
"tag": "v2.0.0-rc.1",
"kind": "prerelease",
"published_at": "2026-04-20T10:16:32Z"
},
{
"tag": "v2.0.0-beta.8.1",
"kind": "prerelease",
"published_at": "2026-04-18T21:10:52Z"
},
{
"tag": "v2.0.0-beta.7",
"kind": "prerelease",
"published_at": "2026-02-22T17:16:17Z"
},
{
"tag": "v2.0.0-beta.6",
"kind": "prerelease",
"published_at": "2026-01-30T09:27:52Z"
},
{
"tag": "v2.0.0-beta.5",
"kind": "prerelease",
"published_at": "2025-12-20T22:45:39Z"
},
{
"tag": "v2.0.0-beta.3",
"kind": "prerelease",
"published_at": "2025-05-02T08:30:51Z"
},
{
"tag": "v2.0.0-beta.2",
"kind": "prerelease",
"published_at": "2025-01-17T09:17:11Z"
},
{
"tag": "v2.0.0-beta.1",
"kind": "prerelease",
"published_at": "2024-12-11T17:10:49Z"
},
{
"tag": "v1.8.0",
"kind": "minor",
"published_at": "2023-05-20T17:52:21Z"
},
{
"tag": "v1.7.0",
"kind": "minor",
"published_at": "2023-03-10T13:44:37Z"
},
{
"tag": "v1.6.0",
"kind": "minor",
"published_at": "2022-11-15T11:50:54Z"
},
{
"tag": "v1.5.0",
"kind": "minor",
"published_at": "2022-09-13T09:35:02Z"
},
{
"tag": "v1.4.1",
"kind": "patch",
"published_at": "2022-08-02T18:05:28Z"
},
{
"tag": "v1.4.0",
"kind": "minor",
"published_at": "2022-07-13T12:34:04Z"
},
{
"tag": "v1.3.0",
"kind": "minor",
"published_at": "2022-05-12T10:35:33Z"
},
{
"tag": "v1.0.1",
"kind": "patch",
"published_at": "2021-06-21T07:44:54Z"
},
{
"tag": "v1.0.0",
"kind": "major",
"published_at": "2021-05-27T08:30:34Z"
},
{
"tag": "v0.1.0-beta.16.1",
"kind": "prerelease",
"published_at": "2021-03-11T18:08:10Z"
}
],
"recent_commits": [
{
"oid": "8b4cf12e5a7dbedd7afbc5dc716c9cbc56248442",
"body": "Binding db.transactions (#4787) means listeners implementing\nShouldHandleEventsAfterCommit are deferred to the surrounding\ntransaction's commit. The integration harness wraps each test in a\ntransaction that is rolled back and never committed, so those callbacks\nwere attached to it and silently disca\n[…]\nat\nreports no applicable pending transactions, so addCallback() runs each\ncallback immediately. db.transactions stays bound and\nConnection::afterCommit() still works, keeping #4787 intact.\n\nRefs #4814",
"is_bot": false,
"headline": "Run after-commit callbacks inline in integration tests (#4833)",
"author_name": "IanM",
"author_login": "imorland",
"committed_at": "2026-07-24T14:13:52Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "d0344b4928a230638f9f3ed64538b0159ffa954a",
"body": "Unblocks composer install on flarum/testing consumers: the PHPUnit 11.x\nline has no fix for GHSA-qrr6-mg7r-m243 (PKSA-5jz8-6tcw-pbk4), so every\n11.x version is filtered by Composer's advisory check.\n\nPHPUnit 12 requires PHP 8.3+, which matches the 2.x floor. Flarum's own\ntest suites already use PHP 8 attributes exclusively; third-party\nextensions still using @test / @dataProvider docblock annotations will\nneed to migrate.\n\nCloses #4584",
"is_bot": false,
"headline": "chore: bump phpunit/phpunit to ^12.5.22 (#4585)",
"author_name": "IanM",
"author_login": "imorland",
"committed_at": "2026-04-18T09:09:56Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6a06f40dbd3d3a1c51b67a6f1c3faf470d67bd30",
"body": "* Added support for pgsql's search_path\n\n* Put schema after database name\n\n* Add schema arguments and order 'ask's\n\n* Fixed errors",
"is_bot": false,
"headline": "feat: Add support for pgsql's search_path (#4241)",
"author_name": "Johann Rodríguez",
"author_login": "johannsa",
"committed_at": "2026-03-22T20:10:12Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3e224bb24a5a3ba5918a3a9bb40b4399ee25d57c",
"body": "…atic analysis (#4450)\n\nIntelephense reports \"Undefined method 'getDriverName'\" (and similar)\nbecause the `database` property and `TestCase::database()` return\n`ConnectionInterface`, which doesn't declare concrete `Connection`\nmethods.\n\nKeep `ConnectionInterface` as the actual PHP type so custom con\n[…]\nt add `@var Connection|null` / `@return Connection` PHPDoc\nannotations so Intelephense and PHPStan resolve the concrete methods.\n\nFixes #4432\n\nCo-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>",
"is_bot": false,
"headline": "fix(testing): narrow database property/method types via PHPDoc for st…",
"author_name": "IanM",
"author_login": "imorland",
"committed_at": "2026-03-15T07:01:52Z",
"body_truncated": true,
"is_coding_agent": true
},
{
"oid": "e4a4ffbfa107737e26c184bead527aec19ac160d",
"body": null,
"is_bot": false,
"headline": "chore(testing): use sqlite by default",
"author_name": "Sami Mazouz",
"author_login": "SychO9",
"committed_at": "2024-12-06T19:23:17Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "afdabe66516ecd9ffc767b1a101d592a594d5825",
"body": "* feat: separate mariadb driver\r\n* chore: add mariadb install dump",
"is_bot": false,
"headline": "feat: separate mariadb driver (#4132)",
"author_name": "Sami Mazouz",
"author_login": "SychO9",
"committed_at": "2024-12-02T09:17:27Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "1755040252d7212536ff812cd2fe63978e77477b",
"body": null,
"is_bot": false,
"headline": "Apply fixes from StyleCI",
"author_name": "StyleCI Bot",
"author_login": "StyleCIBot",
"committed_at": "2024-11-29T12:54:36Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "944da2d402a7a25e9991d8a3c4b1ed5a895bcbdd",
"body": "* chore(testing): run flarum/testing packages tests back again\r\n\r\nThese tests were not run on each framework build, I enabled them again.\r\nTwo of the tests were failing so I disabled them for now, it is more\r\nimportant to have some tests running than none at all.\r\n\r\n* chore(testing): remove flarum/t\n[…]\ng dedicated workflow\r\n\r\nIt is useless now that the tests are run in the framework repo.\r\nAlso this workflow was not working anymore.\r\n\r\n---------\r\n\r\nCo-authored-by: Sami Mazouz <sychocouldy@gmail.com>",
"is_bot": false,
"headline": "test(testing): run `flarum/testing` package tests (#3844)",
"author_name": "Nicolas Peugnet",
"author_login": "n-peugnet",
"committed_at": "2024-11-29T12:54:20Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "06c627f02d552c1feb4973c94b8ba6f98a8e74d9",
"body": "* test: php 8.4\r\n\r\n* fix: php 8.4 deprecations\r\n\r\n* fix: make argument required\r\n\r\n* chore: review changes",
"is_bot": false,
"headline": "test: php 8.4 (#4103)",
"author_name": "Sami Mazouz",
"author_login": "SychO9",
"committed_at": "2024-11-08T16:33:47Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "090079c4ef9fdbdbe5ae789641e280d4ed5462b0",
"body": "* chore: phpunit 10\r\n\r\n* chore: config\r\n\r\n* Apply fixes from StyleCI\r\n\r\n* chore: phpunit 11 (php 8.2 minimum requirement)\r\n\r\n* feat: laravel 11\r\n\r\n* Apply fixes from StyleCI\r\n\r\n* feat: carbon v3\r\n\r\n* fixes",
"is_bot": false,
"headline": "chore: update dependencies (#4012)",
"author_name": "Sami Mazouz",
"author_login": "SychO9",
"committed_at": "2024-08-06T15:50:09Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8ac2d4b6b843a076dd98907520a2d8ec66815b5d",
"body": "* feat: add support for `PgSQL`\r\n* chore: generate dump\r\n* feat: query exception errors db driver hint\r\n* feat: allow defining supported databases\r\n* chore: review comments\r\n* feat: setting for pgsql preferred search config",
"is_bot": false,
"headline": "feat: add support for PgSQL (#3985)",
"author_name": "Sami Mazouz",
"author_login": "SychO9",
"committed_at": "2024-06-22T07:03:56Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "77e2e63aa3371e1e0b34ef6d21778cbc96150bb3",
"body": "* refactor: json:api refactor iteration 1\r\n* chore: delete dead code\r\n* fix: regressions\r\n* chore: move additions/changes to package\r\n* feat: AccessTokenResource\r\n* feat: allow dependency injection in resources\r\n* feat: `ApiResource` extender\r\n* feat: improve\r\n* feat: refactor tags extension\r\n* feat\n[…]\nt\r\n* feat: eager loading\r\n* test: adapt\r\n* test: phpstan\r\n* test: adapt\r\n* fix: typing\r\n* fix: approving content\r\n* tet: adapt frontend tests\r\n* chore: typings\r\n* chore: review\r\n* fix: breaking change",
"is_bot": false,
"headline": "refactor: JSON:API (#3971)",
"author_name": "Sami Mazouz",
"author_login": "SychO9",
"committed_at": "2024-06-21T08:36:32Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "93258af33f1c9232a907bb149409edc6d527960c",
"body": "* feat: add support for sqlite\r\n\r\n* chore: add warning on install\r\n\r\n* fix: ignore constraints before transaction begins\r\n\r\n* chore: update workflow\r\n\r\n* Apply fixes from StyleCI\r\n\r\n* chore: generate sqlite dump and manually add foreign keys\r\n\r\n* chore: fix actions\r\n\r\n* chore: fix actions\r\n\r\n* chore\n[…]\nhore: fix actions\r\n\r\n* chore: fix actions\r\n\r\n* chore: fix actions\r\n\r\n* test: fix\r\n\r\n* Apply fixes from StyleCI\r\n\r\n* fix: sqlite with db prefix\r\n\r\n* Apply fixes from StyleCI\r\n\r\n* fix: statistics sqlite",
"is_bot": false,
"headline": "feat: add support for `SQLite` (#3984)",
"author_name": "Sami Mazouz",
"author_login": "SychO9",
"committed_at": "2024-06-21T06:25:11Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "9ef773e68e13e5db7de907242c4744208844ad47",
"body": "* feat: low maintenance mode (maintenance with admin access) (#3975)\r\n* feat: low maintenance mode (maintenance with admin access)\r\n* Apply fixes from StyleCI\r\n* chore: only required when basic\r\n* chore: more concise code\r\n* chore(review): enum\r\n* feat: enable through settings\r\n* Apply fixes from StyleCI\r\n* core: typing\r\n* feat: safe mode (#3978)\r\n* feat: safe mode\r\n* feat: add extension page warning\r\n* feat: `safe_mode_extensions`\r\n* Apply fixes from StyleCI",
"is_bot": false,
"headline": "feat: advanced maintenance modes (#3977)",
"author_name": "Sami Mazouz",
"author_login": "SychO9",
"committed_at": "2024-05-03T13:05:58Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "949b2d9b6ee015b219c88431c4ed858c4047666a",
"body": null,
"is_bot": false,
"headline": "feat: eloquent factories (primarily for tests) (#3982)",
"author_name": "Sami Mazouz",
"author_login": "SychO9",
"committed_at": "2024-05-03T08:20:27Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "14823131be03781a356b50cf4858432f6953519f",
"body": null,
"is_bot": false,
"headline": "Apply fixes from StyleCI",
"author_name": "StyleCI Bot",
"author_login": "StyleCIBot",
"committed_at": "2024-01-09T15:06:12Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "450ea893c974aefd5f3e9c915d3ed22c0303b822",
"body": null,
"is_bot": false,
"headline": "fix(testing): use cookie for testing authentication (#3924)",
"author_name": "Sami Mazouz",
"author_login": "SychO9",
"committed_at": "2023-11-10T21:35:24Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "40167f9c7a0166c9a71cbd9df2a12616923dcff6",
"body": "…ntract (#3862)\n\n* chore: merge the app with the container & implement the ApplicationContract\r\n\r\nIlluminate components always expect the app to be the container, but also expect the app to be implementing the laravel app contract. This means that very often between minor illuminate updates we get a\n[…]\n: service provider no longer has to change app type\r\n* chore: unimplement `terminat(e/ing)`\r\n* Apply fixes from StyleCI\r\n* chore: recover `container` prop\r\n* chore: return types\r\n* fix: phpstan errors",
"is_bot": false,
"headline": "chore: merge the app with the container & implement the ApplicationCo…",
"author_name": "Sami Mazouz",
"author_login": "SychO9",
"committed_at": "2023-09-15T08:30:24Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "51828db2100eb056b47b5b904cedf0c50ea40944",
"body": "* Do not catch exceptions when testing Console commands\r\n\r\nThis allows to easily test a case where a command should throw using `$this->expectException()`.\r\n\r\n* Rewrite ConsoleTest to use expectException\r\n\r\nNow that the ConsoleApplication is set to not catch exceptions.\r\n\r\n---------\r\n\r\nCo-authored-by: IanM <16573496+imorland@users.noreply.github.com>",
"is_bot": false,
"headline": "Do not catch exceptions when testing Console commands (#3813)",
"author_name": "Nicolas Peugnet",
"author_login": "n-peugnet",
"committed_at": "2023-06-21T07:14:12Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "a93309ca44946351ff13b3f35185b5d8789dda96",
"body": "…es (#3835)",
"is_bot": false,
"headline": "chore(phpstan): upgrade to be compatible with latest dependency updat…",
"author_name": "Sami Mazouz",
"author_login": "SychO9",
"committed_at": "2023-06-15T16:49:39Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6ff80f37855b9007f8a308b0099c3d9dca31e8a7",
"body": "Allows running tests without constantly running `composer install` on each extension.",
"is_bot": false,
"headline": "chore: improve test suite (#3814)",
"author_name": "Sami Mazouz",
"author_login": "SychO9",
"committed_at": "2023-06-15T12:26:39Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "fe7f169672d8b774fff2b930036c359b16b14c5f",
"body": "* wip: laraval and symfony upgrades\r\n\r\n* Apply fixes from StyleCI\r\n\r\n* Apply fixes from StyleCI\r\n\r\n* bump var dumper to 6.3\r\n\r\n* require guzzle 7.7\r\n\r\n* remove docbloc\r\n\r\n* lock symfony/translation-contracts to 2.5\r\n\r\n* fix: require mailgun package\r\n\r\n* remove docblock\r\n\r\n* fix: flysystem tests\r\n\r\n*\n[…]\n fixes from StyleCI\r\n\r\n---------\r\n\r\nCo-authored-by: StyleCI Bot <bot@styleci.io>\r\nCo-authored-by: Daniël Klabbers <luceos@users.noreply.github.com>\r\nCo-authored-by: Sami Mazouz <sychocouldy@gmail.com>",
"is_bot": false,
"headline": "chore: Upgrade dependencies (#3830)",
"author_name": "IanM",
"author_login": "imorland",
"committed_at": "2023-06-14T13:46:15Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "bc34b358ed84147edf2ba4b546bfbf4be51ed1d1",
"body": "Signed-off-by: Sami Mazouz <sychocouldy@gmail.com>",
"is_bot": false,
"headline": "fix(regression): caught errors",
"author_name": "Sami Mazouz",
"author_login": "SychO9",
"committed_at": "2023-05-31T08:50:39Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2aaabd1d54e23eb92a45e0fa4fee6a996f300cef",
"body": "* chore: set minimum php version to 8.1\r\n\r\nSigned-off-by: Sami Mazouz <sychocouldy@gmail.com>\r\n\r\n* chore: update codebase to php8.1\r\n\r\nSigned-off-by: Sami Mazouz <sychocouldy@gmail.com>\r\n\r\n* Apply fixes from StyleCI\r\n\r\n* chore: update workflow php version\r\n\r\nSigned-off-by: Sami Mazouz <sychocouldy@g\n[…]\nail.com>\r\n\r\n* fix: one last error\r\n\r\nSigned-off-by: Sami Mazouz <sychocouldy@gmail.com>\r\n\r\n---------\r\n\r\nSigned-off-by: Sami Mazouz <sychocouldy@gmail.com>\r\nCo-authored-by: StyleCI Bot <bot@styleci.io>",
"is_bot": false,
"headline": "chore: update codebase to php8.1 (#3827)",
"author_name": "Sami Mazouz",
"author_login": "SychO9",
"committed_at": "2023-05-30T10:36:12Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "fd9251f9cf540c7df074bc6e7dfeb35de321efb4",
"body": "This prevent tests from interacting between each other through the cache.",
"is_bot": false,
"headline": "fix(testing): always clear cache in integration test's tearDown (#3818)",
"author_name": "Nicolas Peugnet",
"author_login": "n-peugnet",
"committed_at": "2023-05-02T18:24:14Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0c31cd504db6d395ba1da91178d36677ad761660",
"body": null,
"is_bot": false,
"headline": "feat(testing): add a trait to flush the formatter cache in tests (#3811)",
"author_name": "Sami Mazouz",
"author_login": "SychO9",
"committed_at": "2023-04-30T08:48:46Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "35f96f607acb0798fe6828ce85d76b59ad0292fd",
"body": "Signed-off-by: Sami Mazouz <ilyasmazouz@gmail.com>\r\nCo-authored-by: David <hi@davwheat.dev>",
"is_bot": false,
"headline": "feat: access tokens user management UI (#3587)",
"author_name": "Sami Mazouz",
"author_login": "SychO9",
"committed_at": "2023-02-21T13:14:53Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "44c92b807bd6e9926512fe9e2934f9f1bb69ba5e",
"body": "* Make it possible to extend Flarum\\Testing\\integration\\Setup\\SetupScript and added public methods to add settings or extensions to in initial installation pipeline\r\n\r\n* Fix syntax error, unexpected 'static'\r\n\r\n* Remove `addExtensions` method and document `addSettings`",
"is_bot": false,
"headline": "feat(test): Make it possible to extend SetupScript (#3643)",
"author_name": "Rafael Horvat",
"author_login": "iPurpl3x",
"committed_at": "2022-09-23T11:44:17Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ebd19f5443deada50b9528b937a221f1a2afd3b8",
"body": null,
"is_bot": false,
"headline": "feat: customizable session driver (#3610)",
"author_name": "Sami Mazouz",
"author_login": "SychO9",
"committed_at": "2022-09-14T17:10:30Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "64c6b2125c0da42cbb77deac5ea62913b97a0e0a",
"body": null,
"is_bot": false,
"headline": "chore: v1.5.0 preparations",
"author_name": "Daniël Klabbers",
"author_login": "luceos",
"committed_at": "2022-09-13T08:55:30Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9199962f6fcd3382a484c143fcbfef6c098f7f60",
"body": "* test: password tokens are generated and deleted on password change\r\n* chore: delete all password tokens when the password is changed\r\n* test: email tokens are generated and deleted on email change\r\n* test: email tokens are deleted after password reset\r\n* chore: delete email tokens after password change\r\n* test: password tokens are deleted after email change\r\n* chore: delete password tokens after email change\r\n* chore: syntactic sugar\r\n* chore: unify event listening",
"is_bot": false,
"headline": "feat: clear password & email tokens when appropriate (#3567)",
"author_name": "Sami Mazouz",
"author_login": "SychO9",
"committed_at": "2022-07-30T12:02:06Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "37f36d0a7f87b8e7668e50a92f846b8ef1aee8c6",
"body": "With all the commits below, we resolve all outstanding typing issues in the repo, and CI jobs run green.\r\n\r\n* fix: Convert DashboardPage and DashboardWidget to TypeScript\r\n\r\n* fix: fix type errors in package manager ext\r\n\r\n* fix: Convert Post component to TypeScript\r\n\r\n* fix: avatar typings should a\n[…]\nlarum-cli audit infra --monorepo --fix\r\n\r\n* feat: make `app.data` typings extensible\r\n\r\n* chore(core): format\r\n\r\n* chore: boost tags TypeScript coverage\r\n\r\n* fix(tags): further increase type coverage.",
"is_bot": false,
"headline": "fix: Assorted Typing Fixes (#3348)",
"author_name": "Alexander Skvortsov",
"author_login": "askvortsov1",
"committed_at": "2022-03-23T15:43:14Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "97df6620ce295b08502a43425b5060420922551d",
"body": "…i/js (#3345)\n\n* chore(deps): bump glob-parent in /extensions/emoji/js\r\n\r\nBumps [glob-parent](https://github.com/gulpjs/glob-parent) from 3.1.0 to 5.1.2.\r\n- [Release notes](https://github.com/gulpjs/glob-parent/releases)\r\n- [Changelog](https://github.com/gulpjs/glob-parent/blob/main/CHANGELOG.md)\r\n-\n[…]\nrt@github.com>\r\n\r\n* Apply fixes from StyleCI\r\n\r\n[ci skip] [skip ci]\r\n\r\nCo-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>\r\nCo-authored-by: StyleCI Bot <bot@styleci.io>",
"is_bot": true,
"headline": "chore(deps): bump glob-parent from 3.1.0 to 5.1.2 in /extensions/emoj…",
"author_name": "dependabot[bot]",
"author_login": "dependabot[bot]",
"committed_at": "2022-03-11T23:11:20Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "33cbae8106b6a5303c6c0284a705b28127f3ad30",
"body": null,
"is_bot": false,
"headline": "chore: set up composer path repos",
"author_name": "Alexander Skvortsov",
"author_login": "askvortsov1",
"committed_at": "2022-03-11T23:02:49Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6a60493cff12a3f90392062f6edf53f04e76affd",
"body": "- Remove .github conf folder from Flarum packages\n\n- Remove styleci config from all packages",
"is_bot": false,
"headline": "chore: remove centralizable repo config",
"author_name": "Alexander Skvortsov",
"author_login": "askvortsov1",
"committed_at": "2022-03-11T23:01:44Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "617cf037e58e4c3ec1f1b84f5c2e9a1f6b008f30",
"body": null,
"is_bot": false,
"headline": "allow empty db password \"\" again",
"author_name": "Daniel Klabbers",
"author_login": "luceos",
"committed_at": "2021-06-21T07:32:27Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2b9890970975a5c6d8fd22eebe93ac691f98ed14",
"body": null,
"is_bot": false,
"headline": "fix branch alias",
"author_name": "Daniel Klabbers",
"author_login": "luceos",
"committed_at": "2021-05-25T20:59:06Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "fefd46886ff42c600ae035b71d0c97fa62ffd6b3",
"body": null,
"is_bot": false,
"headline": "Update copyright year",
"author_name": "David Wheatley",
"author_login": "davwheat",
"committed_at": "2021-05-14T23:58:25Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "68bda3f994065797a08b93427b2219bec0f79dfc",
"body": "Before boot, we consider them \"disabled\" so they get migrated.",
"is_bot": false,
"headline": "Extensions should be considered enabled after boot.",
"author_name": "Alexander Skvortsov",
"author_login": "askvortsov1",
"committed_at": "2021-05-11T23:31:35Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0960a93d8be2eede83373773fcb2270423740ec3",
"body": null,
"is_bot": false,
"headline": "Ensure that migrations run",
"author_name": "Alexander Skvortsov",
"author_login": "askvortsov1",
"committed_at": "2021-05-11T21:15:11Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9ef0e5af606669865a0f9c8f8cec4c62af4f391b",
"body": null,
"is_bot": false,
"headline": "get/set enabled extensions from test case, not DB",
"author_name": "Alexander Skvortsov",
"author_login": "askvortsov1",
"committed_at": "2021-05-11T20:24:27Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e7f4e2bbe8536403410870b5950d86e1ee3e36ed",
"body": "The transaction is already started in the proper `BeginTransactionAndSetDatabase` extender.",
"is_bot": false,
"headline": "Remove second beginTransaction",
"author_name": "Alexander Skvortsov",
"author_login": "askvortsov1",
"committed_at": "2021-05-03T05:27:06Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "06e04c6c24281621b127243ac6b828128cfa8cfc",
"body": "In normal Flarum, extensions are only enabled during requests. Here, however, we enable some during boot. This resolves the FilesystemManager early, which resolves the Url Generator early. To fix this, we directly provide a filesystem disk for assets instead of getting it from the filesystem manager.",
"is_bot": false,
"headline": "Don't resolve routes early.",
"author_name": "Alexander Skvortsov",
"author_login": "askvortsov1",
"committed_at": "2021-04-23T22:26:41Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d88991d1abfe28bc6bc7e31d2989f8f74547eb49",
"body": null,
"is_bot": false,
"headline": "Ensure app is booted when getting database",
"author_name": "Alexander Skvortsov",
"author_login": "askvortsov1",
"committed_at": "2021-04-23T19:20:29Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "7c7190e4565553a956cf5314190c55838848b265",
"body": "This ensures a clean state for the extension currently being tested. The alternative requires the user to create and keep track of multiple test databases, or manually delete/re-recreate the database every time they switch between extensions being tested. Now, a simple `composer test:setup` will always reset the test environment to the original state.",
"is_bot": false,
"headline": "Drop all DB tables before installation during setup. (#9)",
"author_name": "Alexander Skvortsov",
"author_login": "askvortsov1",
"committed_at": "2021-04-20T18:47:07Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c4d9caf8f8a2c4d353cca0a22b82b2ade07c2745",
"body": "Similarly to `settings`, this allows setting/overriding config prior to application boot.",
"is_bot": false,
"headline": "TestCase Config method (#13)",
"author_name": "Alexander Skvortsov",
"author_login": "askvortsov1",
"committed_at": "2021-04-14T20:27:59Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "4c4b70b6bd2d76e27db884f9f0bed66c759b9d83",
"body": null,
"is_bot": false,
"headline": "Remove UsesSettingsTrait (#12)",
"author_name": "Sami Mazouz",
"author_login": "SychO9",
"committed_at": "2021-04-14T03:46:04Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "056d06663d7803762d6732ced9f33d1745cf8d44",
"body": "This make a cleaner state more likely, and ensures that settings set via `$this->setting` are cleaned up after the test case runs.",
"is_bot": false,
"headline": "Start transactions before the app is fully booted. (#11)",
"author_name": "Alexander Skvortsov",
"author_login": "askvortsov1",
"committed_at": "2021-04-12T14:26:05Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "eae3eca5183e8318c7b4642e00fd4debf0eade62",
"body": null,
"is_bot": false,
"headline": "Add a few more automated tests",
"author_name": "Alexander Skvortsov",
"author_login": "askvortsov1",
"committed_at": "2021-04-12T03:00:36Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "281d165edca3f6b81a29f60732defcce9aa4a8e4",
"body": "Since we're making changes for the dev version of core, we should test against that too.\n\nFor now, this fixes issues with the `extensions` method of `Installation` being undefined.",
"is_bot": false,
"headline": "Test against dev version of core",
"author_name": "Alexander Skvortsov",
"author_login": "askvortsov1",
"committed_at": "2021-04-12T02:47:09Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ac376c810bf0fe6ff5e65e59eb730c1aa6d302cb",
"body": null,
"is_bot": false,
"headline": "Don't enable extensions during installation (#7)",
"author_name": "Alexander Skvortsov",
"author_login": "askvortsov1",
"committed_at": "2021-04-08T22:39:21Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "6dca45010855fa45ab571e440f49c1b834c4f98a",
"body": null,
"is_bot": false,
"headline": "Add automated tests for `flarum/testing`",
"author_name": "Alexander Skvortsov",
"author_login": "askvortsov1",
"committed_at": "2021-04-07T21:38:58Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "181fa93105700cc3fbc08f2950b947a1f57f1114",
"body": "This allows adding settings before the app is booted. In the past we've used hacky workarounds like manually resetting a binding to override singletons to use custom setting values. It makes sense to support this through `TestCase`.",
"is_bot": false,
"headline": "Add `setting` method to integration TestCase",
"author_name": "Alexander Skvortsov",
"author_login": "askvortsov1",
"committed_at": "2021-04-07T19:01:40Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "231101bfd1fe5400d82ab673f1283a747292dd4c",
"body": "Add ext-json to composer requirements\r\nUpdate editorconfig to match core\r\nUpdate phpdoc to not reference missing import",
"is_bot": false,
"headline": "Requirement and formatting fixes (#5)",
"author_name": "Clark Winkelmann",
"author_login": "clarkwinkelmann",
"committed_at": "2021-03-21T18:26:25Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d503e27159b6df6b4446e62ff4d1c0cef93d9aae",
"body": "Replace bind with singleton, otherwise singleton behavior is lost",
"is_bot": false,
"headline": "Add missing import for ExtensionManager (#6)",
"author_name": "Clark Winkelmann",
"author_login": "clarkwinkelmann",
"committed_at": "2021-03-21T18:25:02Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "cc1d6940da87e1e317b908348f3309f4938463b2",
"body": "It's not causing any issue because the correct variable name is always used to set and read the value, and PHP is fine setting new attributes on a class dynamically. It's just the explicit variables declared don't match with those actually used later.",
"is_bot": false,
"headline": "Fix variable names (#4)",
"author_name": "Clark Winkelmann",
"author_login": "clarkwinkelmann",
"committed_at": "2021-03-20T22:46:03Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "1756fcf740357f8a49066fc82adcdad19d549cac",
"body": null,
"is_bot": false,
"headline": "Ignore generated tmp",
"author_name": "SychO9",
"author_login": "SychO9",
"committed_at": "2021-03-11T18:07:31Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "859abdcdcf0468a511ae62544bd37add5515b5f9",
"body": null,
"is_bot": false,
"headline": "Add required argument",
"author_name": "SychO9",
"author_login": "SychO9",
"committed_at": "2021-03-11T18:07:31Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "fb60426e94d9a8a01233d331718dda51a5224927",
"body": null,
"is_bot": false,
"headline": "Use mockery 1.4",
"author_name": "Alexander Skvortsov",
"author_login": "askvortsov1",
"committed_at": "2021-03-06T23:58:07Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "1f2d4acde3908f6409be389f774f432933e3a1ea",
"body": null,
"is_bot": false,
"headline": "Update PHPUnit to v9",
"author_name": "Alexander Skvortsov",
"author_login": "askvortsov1",
"committed_at": "2021-03-06T23:38:34Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8b14bee7e6db7d5b3770f013462f10b062ed6b79",
"body": null,
"is_bot": false,
"headline": "Update BuildsHttpRequests for new token system",
"author_name": "Alexander Skvortsov",
"author_login": "askvortsov1",
"committed_at": "2021-03-06T23:38:12Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c7f29633462e487114198cf5d7a3aee7696cde19",
"body": null,
"is_bot": false,
"headline": "Configurable Tmp Dir Location (#2)",
"author_name": "Alexander Skvortsov",
"author_login": "askvortsov1",
"committed_at": "2021-02-10T13:59:08Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "21cf1a3b061fbf081ded4356cd0dfa4fc32d2eff",
"body": "Core's ExtensionManager only looks for extensions in the vendor directory, which makes sense for a Flarum instance, but is problematic if used in the context of a test suite for an extension. This PR:\r\n\r\n- Adds a class extending ExtensionManager to include the current package\r\n- Adds an extender that replaces ExtensionManager with this new class in container bindings\r\n\r\nEffectively, this package can now be used to test extensions.",
"is_bot": false,
"headline": "If current package is an extension, add it to the extension manager (#1)",
"author_name": "Alexander Skvortsov",
"author_login": "askvortsov1",
"committed_at": "2021-01-24T17:13:27Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "063c71a44ec0d242f8fce6e9cc2fad6c74911644",
"body": null,
"is_bot": false,
"headline": "Fix vendor path",
"author_name": "Alexander Skvortsov",
"author_login": "askvortsov1",
"committed_at": "2021-01-13T21:49:39Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "27da25243f2ca60c0c6b9472a3e63c9db6177d70",
"body": null,
"is_bot": false,
"headline": "Move setup script to importable class",
"author_name": "Alexander Skvortsov",
"author_login": "askvortsov1",
"committed_at": "2021-01-13T21:22:47Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "2401525a4e3085e206e807544636e2c7ae6cff52",
"body": null,
"is_bot": false,
"headline": "Add composer.json",
"author_name": "Alexander Skvortsov",
"author_login": "askvortsov1",
"committed_at": "2021-01-13T06:27:27Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "146f4c9d3543dda5ee2e41edb5cab8e4113048a8",
"body": null,
"is_bot": false,
"headline": "Move test infrastructure to Testing namespace in src directory",
"author_name": "Alexander Skvortsov",
"author_login": "askvortsov1",
"committed_at": "2021-01-13T06:27:05Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "551284de665ec9c6ed3f7378926caea96d61e14e",
"body": "Some tests need to change settings, but since MemoryCacheSettingsRepository caches settings in-memory, those changes aren't reflected. The new `purgeSettingsCache` removes it from the container, eliminating that cache.\n\nFor UserTest, we also need to regenerate the display name driver, since that's set statically on boot, before we'll get a change to clear the settings cache.",
"is_bot": false,
"headline": "Tests: purge settings cache",
"author_name": "Alexander Skvortsov",
"author_login": "askvortsov1",
"committed_at": "2021-01-13T06:21:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "290943b70b7e806eadbb48fabe952fd19f56d2e4",
"body": null,
"is_bot": false,
"headline": "Add @inheritDoc to all setUp and tearDown methods",
"author_name": "Alexander Skvortsov",
"author_login": "askvortsov1",
"committed_at": "2021-01-13T06:21:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "79af839ee96ee607aa6b829c26e71c4d0dcb971f",
"body": null,
"is_bot": false,
"headline": "Tests: Always start transaction before seeding",
"author_name": "Franz Liedke",
"author_login": "franzliedke",
"committed_at": "2021-01-13T06:21:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "8c64712d7a45ddeac23d69a728a62a785698d8bd",
"body": null,
"is_bot": false,
"headline": "Tests: Stop using Eloquent models for seeding data",
"author_name": "Franz Liedke",
"author_login": "franzliedke",
"committed_at": "2021-01-13T06:21:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "003a48ea9aa844f88d1983573d2698fcedcab1b5",
"body": null,
"is_bot": false,
"headline": "Tests: Rely on admin user, groups, permissions from test setup script",
"author_name": "Franz Liedke",
"author_login": "franzliedke",
"committed_at": "2021-01-13T06:21:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "abd3ed841ee17be4161047a25490b08086f52011",
"body": null,
"is_bot": false,
"headline": "Run integration tests in a transaction",
"author_name": "Franz Liedke",
"author_login": "franzliedke",
"committed_at": "2021-01-13T06:21:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0cde58df60e4361d01b13ac964fc121597a6e593",
"body": null,
"is_bot": false,
"headline": "Add vscode config to gitignore",
"author_name": "Alexander Skvortsov",
"author_login": "askvortsov1",
"committed_at": "2021-01-13T06:21:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c0a728626e493721bd670a2cd68e9916bf76f795",
"body": null,
"is_bot": false,
"headline": "Improve developer experience by forcing LF line endings (#2321)",
"author_name": "Wadim Kalmykov",
"author_login": "w-4",
"committed_at": "2021-01-13T06:21:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d0fecc6cfa1d6a6751bb33f050dd4f34126ac498",
"body": null,
"is_bot": false,
"headline": "Use Config class for data from config.php",
"author_name": "Franz Liedke",
"author_login": "franzliedke",
"committed_at": "2021-01-13T06:21:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "665b3a2822df18eb852d66ab3dda0b8a44b2743a",
"body": "* Write source map without creating temp file\r\n\r\nLess I/O, and one less place where we access the global path helpers.\r\n\r\n* Drop useless app_path() helper\r\n\r\nThis was probably taken straight from Laravel. There is no equivalent\r\nconcept in Flarum, so this should be safe to remove.\r\n\r\n* Deprecate glo\n[…]\nm Application class\r\n\r\n* Avoid using public_path() in prerequisite check\r\n\r\na) The comparison was already outdated, as a different path was passed.\r\nb) We're trying to get rid of these global helpers.",
"is_bot": false,
"headline": "Clean up usages / deprecate path helpers (#2155)",
"author_name": "Franz Liedke",
"author_login": "franzliedke",
"committed_at": "2021-01-13T06:21:38Z",
"body_truncated": true,
"is_coding_agent": false
},
{
"oid": "b4fb4b4eb3bb62647d851629d62e5f57709e61ed",
"body": "We did pass multiple extenders to this method in the tests for the\n`Model` extender - now this actually has the desired effect.",
"is_bot": false,
"headline": "Tests: Actually accept multiple extenders",
"author_name": "Franz Liedke",
"author_login": "franzliedke",
"committed_at": "2021-01-13T06:21:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9cecb797bee055c18796b57605da568329069dea",
"body": "Not needed, and not working without a full Laravel installation.",
"is_bot": false,
"headline": "Test setup: Do not use env() helper",
"author_name": "Franz Liedke",
"author_login": "franzliedke",
"committed_at": "2021-01-13T06:21:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "7273de507fae8c0000de4fd1926a2c816e5991f6",
"body": "- Stop trying to implement Laravel's Application contract, which\n has no value for us.\n- Stop inheriting from the Container, injecting one works equally\n well and does not clutter up the interfaces.\n- Inject the Paths collection instead of unwrapping it again, for\n better encapsulation.\n\nThis brings us one step closer toward upgrading our Laravel\ncomponents (#2055), because we no longer need to adopt the changes\nto the Application contract.",
"is_bot": false,
"headline": "Split up Application and Container",
"author_name": "Franz Liedke",
"author_login": "franzliedke",
"committed_at": "2021-01-13T06:21:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "79230246bfc4ff97c26d0ff241f847f21928a901",
"body": "* Made the console command system extender-friendly\n\n* Added console extender\n\n* Added ConsoleTestCase to integration tests\n\n* Added integration tests for console extender\n\n* Marked event-based console extension system as deprecated\n\n* Moved trimming command output of whitespace into superclass\n\n* Renamed 'add' to 'command'\n\n* Added special processing for laravel commands\n\n* Code style fixes\n\n* More style fixes\n\n* Fixed $this->container",
"is_bot": false,
"headline": "Add console extender (#2057)",
"author_name": "Alexander Skvortsov",
"author_login": "askvortsov1",
"committed_at": "2021-01-13T06:21:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "094c45b192b1fc31a36a2f71c22e416ec356c6bc",
"body": "[ci skip] [skip ci]",
"is_bot": false,
"headline": "Apply fixes from StyleCI",
"author_name": "Franz Liedke",
"author_login": "franzliedke",
"committed_at": "2021-01-13T06:21:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "5d297bbd644494a02b38978b0b1514e1e7690129",
"body": "I feel this makes the parameters a bit more clear, does not rely on\ninheritance (you can only inherit from one class, but we might want more\nof these helpers in the future), and has less side effects (e.g. no\ncreation and, more importantly, deletion of users in the database).\n\nRefs #2052.",
"is_bot": false,
"headline": "Replace authenticatedRequest() by request() option",
"author_name": "Franz Liedke",
"author_login": "franzliedke",
"committed_at": "2021-01-13T06:21:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "9244753edc2914981ce9f5a08e2e0f4bf23d9a0b",
"body": null,
"is_bot": false,
"headline": "Tests: Extract trait for building requests",
"author_name": "Franz Liedke",
"author_login": "franzliedke",
"committed_at": "2021-01-13T06:21:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "0653d109f44fc6488acd73da6f4083f74e9f13e3",
"body": null,
"is_bot": false,
"headline": "Add Authenticated Test Case utility",
"author_name": "Alexander Skvortsov",
"author_login": "askvortsov1",
"committed_at": "2021-01-13T06:21:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "ed9263e211f62fc82540504dc38d1e516c09c62a",
"body": null,
"is_bot": false,
"headline": "Integration tests: Allow registering extenders",
"author_name": "Franz Liedke",
"author_login": "franzliedke",
"committed_at": "2021-01-13T06:21:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "65dfe987613e502cbc8cbdc67fb7a761c932a940",
"body": "This allows sending requests directly in an integration test, without\nhaving *explicitly* booted the app.",
"is_bot": false,
"headline": "Integration tests: Add lazy server helper",
"author_name": "Franz Liedke",
"author_login": "franzliedke",
"committed_at": "2021-01-13T06:21:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "acf74ebcc9cbe0acf87788669d0340f2b7060357",
"body": "This will allow registering extenders in test scenarios. Previously,\nthis would not have had any effect as the app would have booted already.",
"is_bot": false,
"headline": "Integration tests: Create app lazily when needed",
"author_name": "Franz Liedke",
"author_login": "franzliedke",
"committed_at": "2021-01-13T06:21:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "bf138360ac2895b6c8d138089a810ffa5b257d23",
"body": "Also ensure backwards compatibility for extensions that use the Zend framework but don't explicitly require it.",
"is_bot": false,
"headline": "Change Zend namespace to Laminas (#1963)",
"author_name": "Matt Kilgore",
"author_login": "tankerkiller125",
"committed_at": "2021-01-13T06:21:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "f6e9974f289b2a38f58051efefd6a898c17bc6cc",
"body": "[ci skip] [skip ci]",
"is_bot": false,
"headline": "Apply fixes from StyleCI",
"author_name": "Franz Liedke",
"author_login": "franzliedke",
"committed_at": "2021-01-13T06:21:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c74bde8f9e7fd9a7b9227417ad197796d98b87be",
"body": "- Use provided PhpUnit listener to enforce verification of expectations.\n- Include Mockery's trait to auto-close Mockery after each test.",
"is_bot": false,
"headline": "Automatically set up Mockery for unit tests",
"author_name": "Franz Liedke",
"author_login": "franzliedke",
"committed_at": "2021-01-13T06:21:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "245b7ef62c5322ce428641e8c0ba5d5be0468e45",
"body": "- Fix base url when is appended with a script filename\r\n- Add default base url http://flarum.local when CLI wizard used\r\n- Remove some code duplication\r\n- Add minor improvement to the UX when CLI wizard used\r\n- Add tests\r\n- Extract base url normalisation into its own value object",
"is_bot": false,
"headline": "Normalize Base URL during installation",
"author_name": "Stefan Totev",
"author_login": "relax4o",
"committed_at": "2021-01-13T06:21:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "d22fcd7a48ccd0e4337a0a6861cc4e064cb39947",
"body": "…s from tempnam when storing files in tmp",
"is_bot": false,
"headline": "fixed tests on master, missing views directory and suppressing notice…",
"author_name": "Daniël Klabbers",
"author_login": "luceos",
"committed_at": "2021-01-13T06:21:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "c8df5fd856ce96192e4ce0f6bcac6cc7ca199b42",
"body": "[ci skip] [skip ci]",
"is_bot": false,
"headline": "Apply fixes from StyleCI (#1800)",
"author_name": "Daniël Klabbers",
"author_login": "luceos",
"committed_at": "2021-01-13T06:21:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "81f7abd982cc08ec64091a9e689752ad3db7a187",
"body": "…ver you re-run them once smtp is set.\n\nFixed, badly, the test to create users etc caused by the prepareDatabase flushing all settings by default.",
"is_bot": false,
"headline": "Using a different setting key now, so that it won't break tests whene…",
"author_name": "Daniël Klabbers",
"author_login": "luceos",
"committed_at": "2021-01-13T06:21:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "692c18671fb336565edfaaab4c09aceffa1fe9d7",
"body": "…to notice.\n\nFixed csrf test that assumed an access token allows application access, which is actually api token.\nImproved return type hinting in the StartSession middleware",
"is_bot": false,
"headline": "Fixed issue with tmp/storage/views not existing, this caused tmpname …",
"author_name": "Daniël Klabbers",
"author_login": "luceos",
"committed_at": "2021-01-13T06:21:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "e0c6f7425faae9624b44d5a8369c04d630612e9f",
"body": "Multiple tests now provide JSON request bodies, and others copy cookies\nfrom previous responses, so let's provide convenient helpers for these.",
"is_bot": false,
"headline": "Refactor tests to shorten HTTP requests",
"author_name": "Franz Liedke",
"author_login": "franzliedke",
"committed_at": "2021-01-13T06:21:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "68a8f24e23624c84a854bfcdc30a4562580aacd7",
"body": "Now that this is possible, make the easy change...",
"is_bot": false,
"headline": "Integration tests: Configure vendor path",
"author_name": "Franz Liedke",
"author_login": "franzliedke",
"committed_at": "2021-01-13T06:21:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "3ac90ab7ea0615431e69e6855528674917a4e3e3",
"body": "This is useful to send HTTP requests (or their PSR-7 equivalents)\nthrough the entire application's middleware stack (instead of\ntalking to specific controllers, which should be considered\nimplementation detail).",
"is_bot": false,
"headline": "Integration tests: Memoize request handler as well",
"author_name": "Franz Liedke",
"author_login": "franzliedke",
"committed_at": "2021-01-13T06:21:38Z",
"body_truncated": false,
"is_coding_agent": false
},
{
"oid": "21a79358ab80947eb7e602dcbc3c5f58c621e328",
"body": null,
"is_bot": false,
"headline": "Integration tests: Fix test setup",
"author_name": "Franz Liedke",
"author_login": "franzliedke",
"committed_at": "2021-01-13T06:21:38Z",
"body_truncated": false,
"is_coding_agent": false
}
],
"releases_count": 22,
"commits_last_year": 4,
"latest_release_at": "2026-07-08T15:55:02Z",
"latest_release_tag": "v2.0.0-rc.5",
"releases_from_tags": false,
"days_since_last_push": 0,
"active_weeks_last_year": 4,
"days_since_latest_release": 19,
"mean_days_between_releases": 48
},
"community": {
"has_readme": false,
"has_license": true,
"has_description": true,
"has_contributing": true,
"health_percentage": 62,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": true
},
"ecosystem": {
"packages": [
{
"name": "flarum/testing",
"exists": true,
"license": "MIT",
"keywords": [
"forum",
"discussion"
],
"ecosystem": "packagist",
"matches_repo": true,
"registry_url": "https://packagist.org/packages/flarum/testing",
"is_deprecated": false,
"latest_version": "v2.0.0-rc.5",
"repository_url": "https://github.com/flarum/testing",
"versions_count": 25,
"total_downloads": 391233,
"dependents_count": 411,
"deprecation_note": null,
"maintainers_count": null,
"monthly_downloads": 21717,
"first_published_at": null,
"latest_published_at": "2026-04-18T09:09:56Z",
"latest_version_yanked": null,
"days_since_latest_publish": 101
}
]
},
"popularity": {
"forks": 1,
"stars": 0,
"watchers": 4,
"fork_history": {
"days": [
{
"date": "2026-05-06",
"count": 1
}
],
"complete": true,
"collected": 1,
"total_forks": 1
},
"star_history": {
"days": [],
"complete": true,
"collected": 0,
"total_stars": 0,
"collected_at": null
},
"open_issues_and_prs": 0
},
"ai_readiness": {
"has_nix": false,
"example_dirs": [],
"has_llms_txt": false,
"has_dockerfile": false,
"has_mcp_signal": false,
"bootstrap_files": [],
"api_schema_files": [],
"has_devcontainer": false,
"typecheck_configs": [],
"toolchain_manifests": [],
"largest_source_bytes": 11108,
"source_files_sampled": 20,
"oversized_source_files": 0,
"agent_instruction_files": [],
"agent_instruction_max_bytes": null
},
"dependencies": {
"manifests": [
"composer.json",
"tests/composer.json"
],
"advisories": {
"error": "No resolved dependencies carried a version and a supported ecosystem",
"scope": "repository_graph",
"source": null,
"findings": [],
"collected": false,
"malicious": [],
"truncated": false,
"by_severity": {},
"advisory_count": 0,
"affected_count": 0,
"assessed_count": 0,
"malicious_count": 0,
"assessed_package": null,
"unassessed_count": 6,
"direct_affected_count": 0
},
"ecosystems": [
"packagist"
],
"dependencies": [
{
"name": "mockery/mockery",
"manifest": "composer.json",
"ecosystem": "packagist",
"version_constraint": "^1.5"
}
],
"all_dependencies": {
"error": null,
"source": "github-sbom",
"packages": [
{
"name": "mockery/mockery",
"direct": true,
"version": null,
"ecosystem": "packagist"
},
{
"name": "ext-json",
"direct": false,
"version": null,
"ecosystem": "packagist"
},
{
"name": "flarum/core",
"direct": false,
"version": null,
"ecosystem": "packagist"
},
{
"name": "flarum/testing",
"direct": false,
"version": null,
"ecosystem": "packagist"
},
{
"name": "flarum/testing-tests",
"direct": false,
"version": null,
"ecosystem": "packagist"
},
{
"name": "phpunit/phpunit",
"direct": false,
"version": null,
"ecosystem": "packagist"
}
],
"collected": true,
"truncated": false,
"total_count": 6,
"direct_count": 1,
"indirect_count": 5
}
},
"maintainership": {
"issues": {
"open_prs": 0,
"merged_prs": 12,
"open_issues": 0,
"closed_ratio": null,
"closed_issues": 0,
"closed_unmerged_prs": 1
},
"bus_factor": 2,
"bot_contributors": 1,
"top_contributors": [
{
"type": "User",
"login": "askvortsov1",
"commits": 31,
"avatar_url": "https://avatars.githubusercontent.com/u/38059171?v=4"
},
{
"type": "User",
"login": "franzliedke",
"commits": 23,
"avatar_url": "https://avatars.githubusercontent.com/u/249125?v=4"
},
{
"type": "User",
"login": "SychO9",
"commits": 22,
"avatar_url": "https://avatars.githubusercontent.com/u/20267363?v=4"
},
{
"type": "User",
"login": "luceos",
"commits": 7,
"avatar_url": "https://avatars.githubusercontent.com/u/504687?v=4"
},
{
"type": "User",
"login": "imorland",
"commits": 4,
"avatar_url": "https://avatars.githubusercontent.com/u/16573496?v=4"
},
{
"type": "User",
"login": "clarkwinkelmann",
"commits": 3,
"avatar_url": "https://avatars.githubusercontent.com/u/5264300?v=4"
},
{
"type": "User",
"login": "n-peugnet",
"commits": 3,
"avatar_url": "https://avatars.githubusercontent.com/u/23519418?v=4"
},
{
"type": "User",
"login": "StyleCIBot",
"commits": 2,
"avatar_url": "https://avatars.githubusercontent.com/u/11048387?v=4"
},
{
"type": "User",
"login": "davwheat",
"commits": 1,
"avatar_url": "https://avatars.githubusercontent.com/u/7406822?v=4"
},
{
"type": "User",
"login": "johannsa",
"commits": 1,
"avatar_url": "https://avatars.githubusercontent.com/u/214734?v=4"
}
],
"contributors_sampled": 15,
"top_contributor_share": 0.304
},
"quality_signals": {
"has_ci": false,
"has_tests": true,
"ci_workflows": [],
"has_docs_dir": false,
"linter_configs": [],
"has_editorconfig": true,
"has_linter_config": false,
"has_precommit_config": false
},
"security_signals": {
"lockfiles": [],
"scorecard": {
"checks": [
{
"name": "Binary-Artifacts",
"score": 10,
"reason": "no binaries found in the repo",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
},
{
"name": "Branch-Protection",
"score": 0,
"reason": "branch protection not enabled on development/release branches",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
},
{
"name": "CI-Tests",
"score": null,
"reason": "no pull request found",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
},
{
"name": "CII-Best-Practices",
"score": 0,
"reason": "no effort to earn an OpenSSF best practices badge detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
},
{
"name": "Code-Review",
"score": 0,
"reason": "Found 0/30 approved changesets -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
},
{
"name": "Contributors",
"score": 10,
"reason": "project has 13 contributing companies or organizations",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
},
{
"name": "Dangerous-Workflow",
"score": null,
"reason": "no workflows found",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
},
{
"name": "Dependency-Update-Tool",
"score": 10,
"reason": "update tool detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
},
{
"name": "Fuzzing",
"score": 0,
"reason": "project is not fuzzed",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
},
{
"name": "License",
"score": 10,
"reason": "license file detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
},
{
"name": "Maintained",
"score": 0,
"reason": "1 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
},
{
"name": "Packaging",
"score": null,
"reason": "packaging workflow not detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
},
{
"name": "Pinned-Dependencies",
"score": null,
"reason": "no dependencies found",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
},
{
"name": "SAST",
"score": 0,
"reason": "no SAST tool detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
},
{
"name": "Security-Policy",
"score": 10,
"reason": "security policy file detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
},
{
"name": "Signed-Releases",
"score": null,
"reason": "no releases found",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
},
{
"name": "Token-Permissions",
"score": null,
"reason": "No tokens found",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
},
{
"name": "Vulnerabilities",
"score": 10,
"reason": "0 existing vulnerabilities detected",
"documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
}
],
"commit": "8b4cf12e5a7dbedd7afbc5dc716c9cbc56248442",
"ran_at": "2026-07-28T15:14:00Z",
"aggregate_score": 4.8,
"scorecard_version": "v5.5.0"
},
"has_codeql_workflow": false,
"has_security_policy": false,
"has_dependabot_config": false
},
"contribution_flow": {
"collected": true,
"ci_last_run_at": "2026-07-28T13:17:57Z",
"oldest_open_prs": [],
"last_merged_pr_at": "2021-04-20T18:47:07Z",
"ci_last_conclusion": null,
"oldest_open_issues": []
}
},
"config": {
"disabled_metrics": [],
"disabled_categories": [],
"disabled_components": {}
},
"source": {
"url": "https://github.com/flarum/testing",
"host": "github.com",
"name": "testing",
"owner": "flarum"
},
"metrics": {
"overall": {
"key": "overall",
"band": "moderate",
"name": "Overall health",
"note": null,
"notes": [],
"value": 52,
"inputs": {
"security": 48,
"vitality": 64,
"community": 38,
"governance": 75,
"engineering": 27
},
"components": []
},
"categories": [
{
"key": "vitality",
"band": "moderate",
"name": "Vitality",
"value": 64,
"weight": 0.22,
"metrics": [
{
"key": "development_activity",
"band": "at_risk",
"name": "Development activity",
"note": null,
"notes": [],
"value": 45,
"inputs": {
"commits_last_year": 4,
"human_commit_share": 0.99,
"days_since_last_push": 0,
"active_weeks_last_year": 4
},
"components": [
{
"key": "push_recency",
"name": "Push recency",
"detail": "last push 0 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "push_recency",
"params": {
"days": 0
}
}
],
"max_points": 36
},
{
"key": "commit_cadence",
"name": "Commit cadence",
"detail": "4/52 weeks with commits",
"points": 2.8,
"status": "partial",
"details": [
{
"code": "commit_cadence_weeks",
"params": {
"weeks": 4
}
}
],
"max_points": 36
},
{
"key": "commit_volume",
"name": "Commit volume",
"detail": "4 commits in the last year",
"points": 6.3,
"status": "partial",
"details": [
{
"code": "commits_last_year",
"params": {
"count": 4
}
}
],
"max_points": 18
},
{
"key": "openssf_scorecard_maintained",
"name": "OpenSSF Scorecard: Maintained",
"detail": "1 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
},
{
"key": "release_discipline",
"band": "excellent",
"name": "Release discipline",
"note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"openssf_scorecard_signed_releases"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 92,
"inputs": {
"releases_count": 22,
"latest_release_tag": "v2.0.0-rc.5",
"releases_from_tags": false,
"days_since_latest_release": 19,
"mean_days_between_releases": 48
},
"components": [
{
"key": "ships_releases",
"name": "Ships releases",
"detail": "22 releases published",
"points": 27,
"status": "met",
"details": [
{
"code": "releases_published",
"params": {
"count": 22
}
}
],
"max_points": 27
},
{
"key": "release_recency",
"name": "Release recency",
"detail": "latest release 19 days ago",
"points": 36,
"status": "met",
"details": [
{
"code": "release_recency",
"params": {
"days": 19
}
}
],
"max_points": 36
},
{
"key": "release_cadence",
"name": "Release cadence",
"detail": "a release every ~48 days",
"points": 19.8,
"status": "partial",
"details": [
{
"code": "release_cadence",
"params": {
"gap": 48
}
}
],
"max_points": 27
},
{
"key": "openssf_scorecard_signed_releases",
"name": "OpenSSF Scorecard: Signed-Releases",
"detail": "no releases found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 10
}
]
},
{
"key": "abandonment",
"band": "excellent",
"name": "Abandonment",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"cap": null,
"state": "maintained",
"guards": [],
"signals": [],
"red_flag": false,
"multiplier_pct": 100,
"declared_reason": null,
"unverified_reason": null,
"unanswered_open_prs": null,
"unanswered_open_issues": null,
"days_since_last_merged_pr": null,
"days_since_last_human_commit": 4,
"days_since_last_human_commit_is_floor": false
},
"components": [
{
"key": "project_is_still_maintained",
"name": "Project is still maintained",
"detail": "last human commit 4 days ago",
"points": 100,
"status": "met",
"details": [
{
"code": "abandonment_maintained",
"params": {
"days": 4
}
}
],
"max_points": 100
}
]
}
],
"description": "Is the project alive — is code being written and are releases shipping?"
},
{
"key": "community",
"band": "at_risk",
"name": "Community & Adoption",
"value": 38,
"weight": 0.18,
"metrics": [
{
"key": "popularity",
"band": "critical",
"name": "Popularity & adoption",
"note": null,
"notes": [],
"value": 3,
"inputs": {
"forks": 1,
"stars": 0,
"watchers": 4,
"growth_state": "unverified",
"growth_factor_pct": 100,
"growth_unverified_reason": "no_history"
},
"components": [
{
"key": "stars",
"name": "Stars",
"detail": "0 stars",
"points": 0,
"status": "missed",
"details": [
{
"code": "stars",
"params": {
"count": 0
}
}
],
"max_points": 60
},
{
"key": "forks",
"name": "Forks",
"detail": "1 forks",
"points": 0,
"status": "missed",
"details": [
{
"code": "forks",
"params": {
"count": 1
}
}
],
"max_points": 25
},
{
"key": "watchers",
"name": "Watchers",
"detail": "4 watchers",
"points": 2.7,
"status": "partial",
"details": [
{
"code": "watchers",
"params": {
"count": 4
}
}
],
"max_points": 15
}
]
},
{
"key": "community_health",
"band": "moderate",
"name": "Community health",
"note": null,
"notes": [],
"value": 52,
"inputs": {
"has_readme": false,
"has_license": true,
"has_contributing": true,
"has_issue_template": false,
"has_code_of_conduct": false,
"has_pull_request_template": true
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 22.5
},
{
"key": "license",
"name": "License",
"detail": "recognized license (MIT)",
"points": 22.5,
"status": "met",
"details": [
{
"code": "license_standard",
"params": {}
},
{
"code": "license_spdx",
"params": {
"spdx": "MIT"
}
}
],
"max_points": 22.5
},
{
"key": "contributing_guide",
"name": "CONTRIBUTING guide",
"detail": null,
"points": 18,
"status": "met",
"details": [],
"max_points": 18
},
{
"key": "code_of_conduct",
"name": "Code of conduct",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 13.5
},
{
"key": "issue_template",
"name": "Issue template",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.2
},
{
"key": "pr_template",
"name": "PR template",
"detail": null,
"points": 6.3,
"status": "met",
"details": [],
"max_points": 6.3
}
]
},
{
"key": "ecosystem_adoption",
"band": "good",
"name": "Ecosystem adoption (downloads)",
"note": null,
"notes": [],
"value": 75,
"inputs": {
"packages": [
"flarum/testing"
],
"dependents": 411,
"ecosystems": "packagist",
"total_downloads": 391233,
"monthly_downloads": 21717
},
"components": [
{
"key": "monthly_downloads",
"name": "Monthly downloads",
"detail": "21,717 downloads/month across packagist",
"points": 57.8,
"status": "partial",
"details": [
{
"code": "downloads_monthly",
"params": {
"count": 21717,
"ecosystems": "packagist"
}
}
],
"max_points": 80
},
{
"key": "registry_dependents",
"name": "Registry dependents",
"detail": "411 packages depend on it",
"points": 17.4,
"status": "partial",
"details": [
{
"code": "registry_dependents",
"params": {
"count": 411
}
}
],
"max_points": 20
}
]
}
],
"description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
},
{
"key": "governance",
"band": "good",
"name": "Sustainability & Governance",
"value": 75,
"weight": 0.24,
"metrics": [
{
"key": "maintainer_resilience",
"band": "moderate",
"name": "Maintainer resilience (bus factor)",
"note": null,
"notes": [],
"value": 64,
"inputs": {
"bus_factor": 2,
"contributors_sampled": 15,
"top_contributor_share": 0.304
},
"components": [
{
"key": "bus_factor",
"name": "Bus factor",
"detail": "2 contributor(s) cover half of all commits",
"points": 25.2,
"status": "partial",
"details": [
{
"code": "bus_factor",
"params": {
"count": 2
}
}
],
"max_points": 54
},
{
"key": "commit_distribution",
"name": "Commit distribution",
"detail": "top contributor authored 30% of commits",
"points": 15.7,
"status": "partial",
"details": [
{
"code": "top_contributor_share",
"params": {
"share": 30
}
}
],
"max_points": 22.5
},
{
"key": "contributor_breadth",
"name": "Contributor breadth",
"detail": "15 contributors",
"points": 13.5,
"status": "met",
"details": [
{
"code": "contributors_sampled",
"params": {
"count": 15
}
}
],
"max_points": 13.5
},
{
"key": "openssf_scorecard_contributors",
"name": "OpenSSF Scorecard: Contributors",
"detail": "project has 13 contributing companies or organizations",
"points": 10,
"status": "met",
"details": [],
"max_points": 10
}
]
},
{
"key": "responsiveness",
"band": "moderate",
"name": "Issue & PR responsiveness",
"note": "Excluded from scoring (no data or not applicable): Issue resolution. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"issue_resolution"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 66,
"inputs": {
"merged_prs": 12,
"open_issues": 0,
"closed_issues": 0,
"issue_closed_ratio": null,
"closed_unmerged_prs": 1
},
"components": [
{
"key": "issue_resolution",
"name": "Issue resolution",
"detail": "no issues or no data",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_issues_or_data",
"params": {}
}
],
"max_points": 46.75
},
{
"key": "pr_acceptance",
"name": "PR acceptance",
"detail": "12/13 decided PRs merged",
"points": 35.3,
"status": "partial",
"details": [
{
"code": "decided_prs_merged",
"params": {
"merged": 12,
"decided": 13
}
}
],
"max_points": 38.25
},
{
"key": "openssf_scorecard_code_review",
"name": "OpenSSF Scorecard: Code-Review",
"detail": "Found 0/30 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
}
]
},
{
"key": "stewardship",
"band": "good",
"name": "Ownership & stewardship",
"note": null,
"notes": [],
"value": 76,
"inputs": {
"followers": 798,
"owner_type": "Organization",
"is_verified": null,
"owner_login": "flarum",
"public_repos": 53,
"account_age_days": 4688
},
"components": [
{
"key": "ownership_backing",
"name": "Ownership backing",
"detail": "organization-owned",
"points": 30,
"status": "met",
"details": [
{
"code": "owner_organization",
"params": {}
}
],
"max_points": 30
},
{
"key": "verified_domain",
"name": "Verified domain",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 20
},
{
"key": "owner_reach",
"name": "Owner reach",
"detail": "798 followers of flarum",
"points": 20.9,
"status": "partial",
"details": [
{
"code": "owner_followers",
"params": {
"count": 798,
"login": "flarum"
}
}
],
"max_points": 25
},
{
"key": "track_record",
"name": "Track record",
"detail": "53 public repos, account ~12 yr old",
"points": 24.6,
"status": "partial",
"details": [
{
"code": "public_repos",
"params": {
"count": 53
}
},
{
"code": "account_age_years",
"params": {
"years": 12
}
}
],
"max_points": 25
}
]
},
{
"key": "package_maintenance",
"band": "excellent",
"name": "Package maintenance",
"note": null,
"notes": [],
"value": 100,
"inputs": {
"packages": [
"flarum/testing"
],
"ecosystems": "packagist",
"any_deprecated": false,
"min_days_since_publish": 101
},
"components": [
{
"key": "published_resolvable",
"name": "Published & resolvable",
"detail": "1 package(s) on packagist",
"points": 25,
"status": "met",
"details": [
{
"code": "packages_published",
"params": {
"count": 1,
"ecosystems": "packagist"
}
}
],
"max_points": 25
},
{
"key": "publish_recency",
"name": "Publish recency",
"detail": "latest publish 101 days ago",
"points": 35,
"status": "met",
"details": [
{
"code": "publish_recency",
"params": {
"days": 101
}
}
],
"max_points": 35
},
{
"key": "version_history",
"name": "Version history",
"detail": "25 published versions",
"points": 20,
"status": "met",
"details": [
{
"code": "published_versions",
"params": {
"count": 25
}
}
],
"max_points": 20
},
{
"key": "not_deprecated",
"name": "Not deprecated",
"detail": "active, not deprecated or yanked",
"points": 20,
"status": "met",
"details": [
{
"code": "package_not_deprecated",
"params": {}
}
],
"max_points": 20
}
]
}
],
"description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
},
{
"key": "engineering",
"band": "critical",
"name": "Engineering Quality",
"value": 27,
"weight": 0.2,
"metrics": [
{
"key": "engineering_practices",
"band": "at_risk",
"name": "Engineering practices",
"note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: CI-Tests. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"openssf_scorecard_ci_tests"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 38,
"inputs": {
"has_ci": false,
"has_tests": true,
"has_editorconfig": true,
"has_linter_config": false,
"has_precommit_config": false
},
"components": [
{
"key": "ci_workflows",
"name": "CI workflows",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 24
},
{
"key": "tests_present",
"name": "Tests present",
"detail": null,
"points": 24,
"status": "met",
"details": [],
"max_points": 24
},
{
"key": "linter_config",
"name": "Linter config",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 16
},
{
"key": "pre_commit_hooks",
"name": "Pre-commit hooks",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 9.6
},
{
"key": "editorconfig",
"name": ".editorconfig",
"detail": null,
"points": 6.4,
"status": "met",
"details": [],
"max_points": 6.4
},
{
"key": "openssf_scorecard_ci_tests",
"name": "OpenSSF Scorecard: CI-Tests",
"detail": "no pull request found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 20
}
]
},
{
"key": "documentation",
"band": "critical",
"name": "Documentation",
"note": null,
"notes": [],
"value": 10,
"inputs": {
"topics": [],
"has_wiki": false,
"homepage": null,
"has_readme": false,
"has_docs_dir": false,
"has_description": true
},
"components": [
{
"key": "readme",
"name": "README",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 30
},
{
"key": "documentation_directory",
"name": "Documentation directory",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 25
},
{
"key": "documentation_homepage_site",
"name": "Documentation / homepage site",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
},
{
"key": "repository_description",
"name": "Repository description",
"detail": null,
"points": 10,
"status": "met",
"details": [],
"max_points": 10
},
{
"key": "topics",
"name": "Topics",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
},
{
"key": "wiki",
"name": "Wiki",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
}
]
}
],
"description": "Are baseline engineering and documentation practices in place?"
},
{
"key": "security",
"band": "at_risk",
"name": "Security",
"value": 48,
"weight": 0.16,
"metrics": [
{
"key": "security_posture",
"band": "at_risk",
"name": "Security posture",
"note": "Excluded from scoring (no data or not applicable): CI-Tests, Dangerous-Workflow, Packaging, Pinned-Dependencies, Signed-Releases, Token-Permissions. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"ci_tests",
"dangerous_workflow",
"packaging",
"pinned_dependencies",
"signed_releases",
"token_permissions"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 48,
"inputs": {
"source": "openssf_scorecard",
"checks_evaluated": 12,
"scorecard_version": "v5.5.0",
"checks_inconclusive": 6,
"scorecard_aggregate": 4.8
},
"components": [
{
"key": "binary_artifacts",
"name": "Binary-Artifacts",
"detail": "no binaries found in the repo",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "branch_protection",
"name": "Branch-Protection",
"detail": "branch protection not enabled on development/release branches",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "ci_tests",
"name": "CI-Tests",
"detail": "no pull request found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 2.5
},
{
"key": "cii_best_practices",
"name": "CII-Best-Practices",
"detail": "no effort to earn an OpenSSF best practices badge detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 2.5
},
{
"key": "code_review",
"name": "Code-Review",
"detail": "Found 0/30 approved changesets -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "contributors",
"name": "Contributors",
"detail": "project has 13 contributing companies or organizations",
"points": 2.5,
"status": "met",
"details": [],
"max_points": 2.5
},
{
"key": "dangerous_workflow",
"name": "Dangerous-Workflow",
"detail": "no workflows found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 10
},
{
"key": "dependency_update_tool",
"name": "Dependency-Update-Tool",
"detail": "update tool detected",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
},
{
"key": "fuzzing",
"name": "Fuzzing",
"detail": "project is not fuzzed",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "license",
"name": "License",
"detail": "license file detected",
"points": 2.5,
"status": "met",
"details": [],
"max_points": 2.5
},
{
"key": "maintained",
"name": "Maintained",
"detail": "1 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0",
"points": 0,
"status": "missed",
"details": [],
"max_points": 7.5
},
{
"key": "packaging",
"name": "Packaging",
"detail": "packaging workflow not detected",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 5
},
{
"key": "pinned_dependencies",
"name": "Pinned-Dependencies",
"detail": "no dependencies found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 5
},
{
"key": "sast",
"name": "SAST",
"detail": "no SAST tool detected",
"points": 0,
"status": "missed",
"details": [],
"max_points": 5
},
{
"key": "security_policy",
"name": "Security-Policy",
"detail": "security policy file detected",
"points": 5,
"status": "met",
"details": [],
"max_points": 5
},
{
"key": "signed_releases",
"name": "Signed-Releases",
"detail": "no releases found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 7.5
},
{
"key": "token_permissions",
"name": "Token-Permissions",
"detail": "No tokens found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 7.5
},
{
"key": "vulnerabilities",
"name": "Vulnerabilities",
"detail": "0 existing vulnerabilities detected",
"points": 7.5,
"status": "met",
"details": [],
"max_points": 7.5
}
]
},
{
"key": "high_risk_jurisdiction_exposure",
"band": "excellent",
"name": "High-Risk Jurisdiction Exposure",
"note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
"notes": [
{
"code": "jurisdiction_evidence_limits",
"params": {}
}
],
"value": 100,
"inputs": {
"meaning": "self-published location evidence; not nationality or citizenship",
"red_flag": false,
"exposures": [],
"policy_countries": [
"Russia",
"Iran",
"North Korea"
],
"review_only_matches": 0,
"assessed_self_published_locations": 21
},
"components": [
{
"key": "policy_exposure_multiplier",
"name": "Policy exposure multiplier",
"detail": "no confirmed policy-scope location match",
"points": 100,
"status": "met",
"details": [
{
"code": "jurisdiction_no_match",
"params": {}
}
],
"max_points": 100
}
]
}
],
"description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
},
{
"key": "ai_readiness",
"band": "at_risk",
"name": "AI Readiness",
"value": 39,
"weight": 0,
"metrics": [
{
"key": "ai_agent_context",
"band": "at_risk",
"name": "Agent context & guidance",
"note": null,
"notes": [],
"value": 34,
"inputs": {
"has_llms_txt": false,
"legible_history_share": 0.636,
"agent_instruction_files": [],
"agent_instruction_max_bytes": null
},
"components": [
{
"key": "agent_instructions",
"name": "Agent instructions",
"detail": "no CLAUDE.md / AGENTS.md / editor rules",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_agent_instructions",
"params": {}
}
],
"max_points": 45
},
{
"key": "machine_readable_docs_llms_txt",
"name": "Machine-readable docs (llms.txt)",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 15
},
{
"key": "legible_commit_history",
"name": "Legible commit history",
"detail": "63 of 99 human commits state their intent (structured subject or explanatory body)",
"points": 33.9,
"status": "partial",
"details": [
{
"code": "legible_history",
"params": {
"legible": 63,
"sampled": 99
}
}
],
"max_points": 40
}
]
},
{
"key": "ai_verify_loop",
"band": "at_risk",
"name": "Verify loop (build / test / typecheck)",
"note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Pinned-Dependencies. Remaining weights renormalized.",
"notes": [
{
"code": "excluded_no_data",
"params": {
"components": [
"openssf_scorecard_pinned_dependencies"
]
}
},
{
"code": "weights_renormalized",
"params": {}
}
],
"value": 36,
"inputs": {
"has_nix": false,
"has_tests": true,
"lockfiles": [],
"has_dockerfile": false,
"typed_language": false,
"bootstrap_files": [],
"has_devcontainer": false,
"has_linter_config": false,
"typecheck_configs": [],
"agent_commit_share": 0.01,
"toolchain_manifests": [],
"dependency_bot_commit_share": 0.01
},
"components": [
{
"key": "one_command_bootstrap",
"name": "One-command bootstrap",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 18
},
{
"key": "automated_tests",
"name": "Automated tests",
"detail": null,
"points": 22,
"status": "met",
"details": [],
"max_points": 22
},
{
"key": "lint_format_config",
"name": "Lint / format config",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 11
},
{
"key": "static_type_checking",
"name": "Static type checking",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 11
},
{
"key": "reproducible_environment",
"name": "Reproducible environment",
"detail": null,
"points": 0,
"status": "missed",
"details": [],
"max_points": 10
},
{
"key": "demonstrated_agent_practice",
"name": "Demonstrated agent practice",
"detail": "1 of the last 100 commits agent-authored or agent-credited",
"points": 2,
"status": "partial",
"details": [
{
"code": "agent_authored_commits",
"params": {
"count": 1,
"sampled": 100
}
}
],
"max_points": 10
},
{
"key": "automated_maintenance",
"name": "Automated maintenance",
"detail": "1 of the last 100 commits are automated dependency updates",
"points": 8,
"status": "met",
"details": [
{
"code": "dependency_bot_commits",
"params": {
"count": 1,
"sampled": 100
}
}
],
"max_points": 8
},
{
"key": "openssf_scorecard_pinned_dependencies",
"name": "OpenSSF Scorecard: Pinned-Dependencies",
"detail": "no dependencies found",
"points": 0,
"status": "excluded",
"details": [
{
"code": "no_data",
"params": {}
}
],
"max_points": 10
}
]
},
{
"key": "ai_code_legibility",
"band": "moderate",
"name": "Code legibility for models",
"note": null,
"notes": [],
"value": 55,
"inputs": {
"primary_language": "PHP",
"largest_source_bytes": 11108,
"source_files_sampled": 20,
"oversized_source_files": 0
},
"components": [
{
"key": "type_checkable_code",
"name": "Type-checkable code",
"detail": "PHP without a type-check config",
"points": 0,
"status": "missed",
"details": [
{
"code": "no_typecheck_config_language",
"params": {
"language": "PHP"
}
}
],
"max_points": 45
},
{
"key": "manageable_file_sizes",
"name": "Manageable file sizes",
"detail": "0/20 source files over 60KB",
"points": 55,
"status": "met",
"details": [
{
"code": "oversized_source_files",
"params": {
"kb": 60,
"sampled": 20,
"oversized": 0
}
}
],
"max_points": 55
}
]
}
],
"description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
}
],
"metrics_version": "1.13.0"
},
"warnings": [
"No resolved dependencies carried a version and a supported ecosystem"
],
"report_type": "repository",
"generated_at": "2026-07-28T15:14:13.222055Z",
"schema_version": "0.27.0",
"badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/f/flarum/testing.svg",
"full_name": "flarum/testing",
"license_state": "standard",
"license_spdx": "MIT"
}