mirror of https://github.com/pixelfed/pixelfed
chore: add Psalm static analysis (types, baseline, CI)
Adds psalm/plugin-laravel (Laravel-aware Psalm) at error level 8 with a baseline so CI is green immediately. Type-analysis CI job with SHA-pinned actions and an egress-hardened runner.pull/6646/head
parent
c8bed78bee
commit
fe172ee044
@ -0,0 +1,54 @@
|
||||
# Generated by `psalm-laravel add github`, then trimmed to type analysis only.
|
||||
# Psalm 6 runs type and taint analysis in separate modes. This workflow runs the type-analysis
|
||||
# pass and fails on Psalm's exit code. Taint (security) scanning is available via
|
||||
# `./vendor/bin/psalm --taint-analysis`; enable it as a second job once you are ready to triage
|
||||
# its findings in a private channel (see the plugin README for the SARIF + Code Scanning setup).
|
||||
|
||||
name: Psalm
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ dev ]
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: psalm-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
static-analysis:
|
||||
name: Psalm type analysis
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Block unexpected egress
|
||||
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
|
||||
with:
|
||||
# Covers checkout, setup-php and Composer (public Packagist). Extend for other hosts
|
||||
# (private registry, VCS repos, extra plugins). Use egress-policy: audit to discover them.
|
||||
egress-policy: block
|
||||
allowed-endpoints: >
|
||||
api.github.com:443
|
||||
codeload.github.com:443
|
||||
github.com:443
|
||||
packagist.org:443
|
||||
release-assets.githubusercontent.com:443
|
||||
repo.packagist.org:443
|
||||
|
||||
# No git ops after checkout, so drop the token: a compromised later step cannot push.
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # 2.37.2
|
||||
with:
|
||||
php-version: '8.4'
|
||||
coverage: none
|
||||
|
||||
- uses: ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda # 4.0.0
|
||||
|
||||
# No --report, so Psalm exits non-zero on findings and fails the job directly.
|
||||
- name: Run Psalm (type analysis)
|
||||
run: ./vendor/bin/psalm
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,282 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<files psalm-version="6.16.1@f1f5de594dc76faf8784e02d3dc4716c91c6f6ac">
|
||||
<file src="app/Console/Commands/FixUsernames.php">
|
||||
<NoValue>
|
||||
<code><![CDATA[$u]]></code>
|
||||
</NoValue>
|
||||
</file>
|
||||
<file src="app/FailedJob.php">
|
||||
<PublicModelAccessor>
|
||||
<code><![CDATA[getFailedAtAttribute]]></code>
|
||||
</PublicModelAccessor>
|
||||
</file>
|
||||
<file src="app/Http/Controllers/AccountController.php">
|
||||
<NoValue>
|
||||
<code><![CDATA[return abort(403);]]></code>
|
||||
<code><![CDATA[return abort(403);]]></code>
|
||||
<code><![CDATA[return abort(403);]]></code>
|
||||
<code><![CDATA[return abort(403);]]></code>
|
||||
<code><![CDATA[return abort(406);]]></code>
|
||||
<code><![CDATA[return abort(406);]]></code>
|
||||
<code><![CDATA[return abort(406);]]></code>
|
||||
<code><![CDATA[return abort(406);]]></code>
|
||||
</NoValue>
|
||||
</file>
|
||||
<file src="app/Http/Controllers/Admin/AdminReportController.php">
|
||||
<NoValue>
|
||||
<code><![CDATA[return abort(403);]]></code>
|
||||
</NoValue>
|
||||
<UndefinedVariable>
|
||||
<code><![CDATA[$meta]]></code>
|
||||
<code><![CDATA[$status]]></code>
|
||||
<code><![CDATA[$status]]></code>
|
||||
<code><![CDATA[$status]]></code>
|
||||
<code><![CDATA[$status]]></code>
|
||||
<code><![CDATA[$status]]></code>
|
||||
</UndefinedVariable>
|
||||
</file>
|
||||
<file src="app/Http/Controllers/AdminController.php">
|
||||
<UndefinedClass>
|
||||
<code><![CDATA[AdminProfile]]></code>
|
||||
</UndefinedClass>
|
||||
</file>
|
||||
<file src="app/Http/Controllers/Api/AdminApiController.php">
|
||||
<NoValue>
|
||||
<code><![CDATA[return abort(403);]]></code>
|
||||
</NoValue>
|
||||
</file>
|
||||
<file src="app/Http/Controllers/Api/ApiV1Controller.php">
|
||||
<UndefinedVariable>
|
||||
<code><![CDATA[$account]]></code>
|
||||
</UndefinedVariable>
|
||||
</file>
|
||||
<file src="app/Http/Controllers/Api/ApiV1Dot1Controller.php">
|
||||
<UndefinedDocblockClass>
|
||||
<code><![CDATA[StatusTransformer]]></code>
|
||||
</UndefinedDocblockClass>
|
||||
</file>
|
||||
<file src="app/Http/Controllers/Api/ApiV2Controller.php">
|
||||
<UndefinedClass>
|
||||
<code><![CDATA[DB]]></code>
|
||||
<code><![CDATA[StatusService]]></code>
|
||||
<code><![CDATA[StatusService]]></code>
|
||||
<code><![CDATA[StatusService]]></code>
|
||||
<code><![CDATA[UserFilterService]]></code>
|
||||
<code><![CDATA[UserFilterService]]></code>
|
||||
</UndefinedClass>
|
||||
</file>
|
||||
<file src="app/Http/Controllers/Api/V1/DomainBlockController.php">
|
||||
<NoValue>
|
||||
<code><![CDATA[return abort(500, 'Invalid domain or already blocked by server admins');]]></code>
|
||||
</NoValue>
|
||||
</file>
|
||||
<file src="app/Http/Controllers/AppRegisterController.php">
|
||||
<InaccessibleProperty>
|
||||
<code><![CDATA[$token->token]]></code>
|
||||
</InaccessibleProperty>
|
||||
</file>
|
||||
<file src="app/Http/Controllers/Groups/GroupsPostController.php">
|
||||
<UndefinedVariable>
|
||||
<code><![CDATA[$status]]></code>
|
||||
<code><![CDATA[$status]]></code>
|
||||
<code><![CDATA[$status]]></code>
|
||||
<code><![CDATA[$status]]></code>
|
||||
<code><![CDATA[$status]]></code>
|
||||
<code><![CDATA[$status]]></code>
|
||||
<code><![CDATA[$status]]></code>
|
||||
<code><![CDATA[$status]]></code>
|
||||
<code><![CDATA[$status]]></code>
|
||||
</UndefinedVariable>
|
||||
</file>
|
||||
<file src="app/Http/Controllers/Import/Instagram.php">
|
||||
<NoValue>
|
||||
<code><![CDATA[return abort(500);]]></code>
|
||||
</NoValue>
|
||||
</file>
|
||||
<file src="app/Http/Controllers/PersonalAccessTokenController.php">
|
||||
<InaccessibleProperty>
|
||||
<code><![CDATA[$result->token]]></code>
|
||||
<code><![CDATA[$result->token]]></code>
|
||||
</InaccessibleProperty>
|
||||
</file>
|
||||
<file src="app/Http/Controllers/PortfolioController.php">
|
||||
<UndefinedVariable>
|
||||
<code><![CDATA[$metadata]]></code>
|
||||
</UndefinedVariable>
|
||||
</file>
|
||||
<file src="app/Http/Controllers/ProfileController.php">
|
||||
<NoValue>
|
||||
<code><![CDATA[return abort(404);]]></code>
|
||||
</NoValue>
|
||||
</file>
|
||||
<file src="app/Http/Controllers/RemoteAuthController.php">
|
||||
<NoValue>
|
||||
<code><![CDATA[$res]]></code>
|
||||
<code><![CDATA[$res]]></code>
|
||||
<code><![CDATA[$res]]></code>
|
||||
<code><![CDATA[$res]]></code>
|
||||
</NoValue>
|
||||
</file>
|
||||
<file src="app/Http/Controllers/ReportController.php">
|
||||
<NoValue>
|
||||
<code><![CDATA[return abort(400, 'Invalid report type');]]></code>
|
||||
<code><![CDATA[return abort(400, 'Invalid report type');]]></code>
|
||||
</NoValue>
|
||||
</file>
|
||||
<file src="app/Http/Controllers/StoryController.php">
|
||||
<NoValue>
|
||||
<code><![CDATA[return abort([], 403);]]></code>
|
||||
</NoValue>
|
||||
</file>
|
||||
<file src="app/Http/Controllers/TimelineController.php">
|
||||
<UndefinedClass>
|
||||
<code><![CDATA[StatusTimelineTransformer]]></code>
|
||||
</UndefinedClass>
|
||||
</file>
|
||||
<file src="app/Http/Kernel.php">
|
||||
<UndefinedClass>
|
||||
<code><![CDATA[CheckForAnyScope]]></code>
|
||||
<code><![CDATA[CheckScopes]]></code>
|
||||
</UndefinedClass>
|
||||
</file>
|
||||
<file src="app/Http/Middleware/Api/Admin.php">
|
||||
<NoValue>
|
||||
<code><![CDATA[return abort(403, 'You must be an administrator to do that');]]></code>
|
||||
</NoValue>
|
||||
</file>
|
||||
<file src="app/Jobs/CuratedOnboarding/CuratedOnboardingNotifyAdminNewApplicationPipeline.php">
|
||||
<NoValue>
|
||||
<code><![CDATA[$adminUsernames]]></code>
|
||||
<code><![CDATA[$ccAddresses]]></code>
|
||||
</NoValue>
|
||||
</file>
|
||||
<file src="app/Jobs/GroupsPipeline/DeleteCommentPipeline.php">
|
||||
<ParseError>
|
||||
<code><![CDATA[)]]></code>
|
||||
</ParseError>
|
||||
</file>
|
||||
<file src="app/Jobs/InboxPipeline/DeleteWorker.php">
|
||||
<UndefinedVariable>
|
||||
<code><![CDATA[$key]]></code>
|
||||
</UndefinedVariable>
|
||||
</file>
|
||||
<file src="app/Jobs/RemoteFollowPipeline/RemoteFollowPipeline.php">
|
||||
<UndefinedClass>
|
||||
<code><![CDATA[Context]]></code>
|
||||
<code><![CDATA[GuzzleHttpSignatures]]></code>
|
||||
</UndefinedClass>
|
||||
</file>
|
||||
<file src="app/Jobs/ReportPipeline/AutospamNotifyAdminViaEmail.php">
|
||||
<NoValue>
|
||||
<code><![CDATA[$addresses]]></code>
|
||||
<code><![CDATA[$addresses]]></code>
|
||||
<code><![CDATA[$to]]></code>
|
||||
</NoValue>
|
||||
</file>
|
||||
<file src="app/Jobs/ReportPipeline/ReportNotifyAdminViaEmail.php">
|
||||
<NoValue>
|
||||
<code><![CDATA[$addresses]]></code>
|
||||
<code><![CDATA[$addresses]]></code>
|
||||
<code><![CDATA[$to]]></code>
|
||||
</NoValue>
|
||||
</file>
|
||||
<file src="app/Models/CustomFilter.php">
|
||||
<PublicModelAccessor>
|
||||
<code><![CDATA[getExpiresInAttribute]]></code>
|
||||
<code><![CDATA[getFilterActionAttribute]]></code>
|
||||
<code><![CDATA[getIrreversibleAttribute]]></code>
|
||||
<code><![CDATA[getTitleAttribute]]></code>
|
||||
<code><![CDATA[setFilterActionAttribute]]></code>
|
||||
<code><![CDATA[setIrreversibleAttribute]]></code>
|
||||
<code><![CDATA[setTitleAttribute]]></code>
|
||||
</PublicModelAccessor>
|
||||
<UndefinedDocblockClass>
|
||||
<code><![CDATA[Collection]]></code>
|
||||
</UndefinedDocblockClass>
|
||||
</file>
|
||||
<file src="app/Models/CustomFilterKeyword.php">
|
||||
<PublicModelAccessor>
|
||||
<code><![CDATA[setKeywordAttribute]]></code>
|
||||
</PublicModelAccessor>
|
||||
</file>
|
||||
<file src="app/Observers/LikeObserver.php">
|
||||
<UndefinedDocblockClass>
|
||||
<code><![CDATA[\App\Models\Like]]></code>
|
||||
<code><![CDATA[\App\Models\Like]]></code>
|
||||
<code><![CDATA[\App\Models\Like]]></code>
|
||||
<code><![CDATA[\App\Models\Like]]></code>
|
||||
<code><![CDATA[\App\Models\Like]]></code>
|
||||
</UndefinedDocblockClass>
|
||||
</file>
|
||||
<file src="app/Services/StoryIndexService.php">
|
||||
<NoValue>
|
||||
<code><![CDATA[$results]]></code>
|
||||
</NoValue>
|
||||
</file>
|
||||
<file src="app/Util/ActivityPub/Helpers.php">
|
||||
<UndefinedClass>
|
||||
<code><![CDATA[UriException]]></code>
|
||||
</UndefinedClass>
|
||||
</file>
|
||||
<file src="app/Util/Lexer/Autolink.php">
|
||||
<UndefinedDocblockClass>
|
||||
<code><![CDATA[autolinkActiveUsersOnly]]></code>
|
||||
<code><![CDATA[protected $autolinkActiveUsersOnly = false;]]></code>
|
||||
</UndefinedDocblockClass>
|
||||
</file>
|
||||
<file src="app/Util/Lexer/Regex.php">
|
||||
<UnsupportedPropertyReferenceUsage>
|
||||
<code><![CDATA[$re = &self::$patterns]]></code>
|
||||
</UnsupportedPropertyReferenceUsage>
|
||||
</file>
|
||||
<file src="app/Util/RateLimit/User.php">
|
||||
<PublicModelAccessor>
|
||||
<code><![CDATA[getMaxCollectionsPerDayAttribute]]></code>
|
||||
<code><![CDATA[getMaxCollectionsPerHourAttribute]]></code>
|
||||
<code><![CDATA[getMaxCollectionsPerMonthAttribute]]></code>
|
||||
<code><![CDATA[getMaxCommentsPerDayAttribute]]></code>
|
||||
<code><![CDATA[getMaxCommentsPerHourAttribute]]></code>
|
||||
<code><![CDATA[getMaxComposeMediaUpdatesPerDayAttribute]]></code>
|
||||
<code><![CDATA[getMaxComposeMediaUpdatesPerHourAttribute]]></code>
|
||||
<code><![CDATA[getMaxComposeMediaUpdatesPerMonthAttribute]]></code>
|
||||
<code><![CDATA[getMaxHashtagFollowsPerDayAttribute]]></code>
|
||||
<code><![CDATA[getMaxHashtagFollowsPerHourAttribute]]></code>
|
||||
<code><![CDATA[getMaxInstanceBansPerDayAttribute]]></code>
|
||||
<code><![CDATA[getMaxLikesPerDayAttribute]]></code>
|
||||
<code><![CDATA[getMaxLikesPerHourAttribute]]></code>
|
||||
<code><![CDATA[getMaxPostEditsPerDayAttribute]]></code>
|
||||
<code><![CDATA[getMaxPostEditsPerHourAttribute]]></code>
|
||||
<code><![CDATA[getMaxPostsPerDayAttribute]]></code>
|
||||
<code><![CDATA[getMaxPostsPerHourAttribute]]></code>
|
||||
<code><![CDATA[getMaxSharesPerDayAttribute]]></code>
|
||||
<code><![CDATA[getMaxSharesPerHourAttribute]]></code>
|
||||
<code><![CDATA[getMaxStoriesPerDayAttribute]]></code>
|
||||
<code><![CDATA[getMaxStoriesPerHourAttribute]]></code>
|
||||
<code><![CDATA[getMaxStoryDeletePerDayAttribute]]></code>
|
||||
<code><![CDATA[getMaxUserBansPerDayAttribute]]></code>
|
||||
</PublicModelAccessor>
|
||||
</file>
|
||||
<file src="config/websockets.php">
|
||||
<UndefinedClass>
|
||||
<code><![CDATA[\BeyondCode\LaravelWebSockets\API\FetchChannel]]></code>
|
||||
<code><![CDATA[\BeyondCode\LaravelWebSockets\API\FetchChannels]]></code>
|
||||
<code><![CDATA[\BeyondCode\LaravelWebSockets\API\FetchUsers]]></code>
|
||||
<code><![CDATA[\BeyondCode\LaravelWebSockets\API\TriggerEvent]]></code>
|
||||
<code><![CDATA[\BeyondCode\LaravelWebSockets\Apps\ConfigAppManager]]></code>
|
||||
<code><![CDATA[\BeyondCode\LaravelWebSockets\ChannelManagers\LocalChannelManager]]></code>
|
||||
<code><![CDATA[\BeyondCode\LaravelWebSockets\ChannelManagers\RedisChannelManager]]></code>
|
||||
<code><![CDATA[\BeyondCode\LaravelWebSockets\Dashboard\Http\Middleware\Authorize]]></code>
|
||||
<code><![CDATA[\BeyondCode\LaravelWebSockets\Server\HealthHandler]]></code>
|
||||
<code><![CDATA[\BeyondCode\LaravelWebSockets\Server\WebSocketHandler]]></code>
|
||||
<code><![CDATA[\BeyondCode\LaravelWebSockets\Statistics\Collectors\MemoryCollector]]></code>
|
||||
<code><![CDATA[\BeyondCode\LaravelWebSockets\Statistics\Collectors\RedisCollector]]></code>
|
||||
<code><![CDATA[\BeyondCode\LaravelWebSockets\Statistics\Stores\DatabaseStore]]></code>
|
||||
<code><![CDATA[\React\Promise\FulfilledPromise]]></code>
|
||||
</UndefinedClass>
|
||||
</file>
|
||||
<file src="public/index.php">
|
||||
<MissingFile>
|
||||
<code><![CDATA[require __DIR__.'/../storage/framework/maintenance.php']]></code>
|
||||
</MissingFile>
|
||||
</file>
|
||||
</files>
|
||||
@ -0,0 +1,54 @@
|
||||
<?xml version="1.0"?>
|
||||
<psalm
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="https://getpsalm.org/schema/config"
|
||||
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
|
||||
errorLevel="8"
|
||||
findUnusedCode="false"
|
||||
ensureOverrideAttribute="false"
|
||||
errorBaseline="psalm-baseline.xml"
|
||||
>
|
||||
<projectFiles>
|
||||
<directory name="app"/>
|
||||
<directory name="bootstrap"/>
|
||||
<directory name="config"/>
|
||||
<directory name="database"/>
|
||||
<directory name="routes"/>
|
||||
<!-- composer require psalm/plugin-phpunit psalm/plugin-mockery for the full tests support -->
|
||||
<!-- <directory name="tests"/>-->
|
||||
|
||||
|
||||
<file name="public/index.php"/>
|
||||
<file name="artisan"/>
|
||||
<ignoreFiles allowMissingFiles="true">
|
||||
<directory name="bootstrap/cache"/>
|
||||
<directory name="storage"/>
|
||||
<directory name="vendor"/>
|
||||
</ignoreFiles>
|
||||
</projectFiles>
|
||||
|
||||
<plugins>
|
||||
<!-- All Psalm Laravel options: https://github.com/psalm/psalm-plugin-laravel/blob/master/docs/config.md -->
|
||||
<pluginClass class="Psalm\LaravelPlugin\Plugin">
|
||||
<resolveDynamicWhereClauses value="true" />
|
||||
<findMissingTranslations value="false" />
|
||||
<findMissingViews value="false" />
|
||||
</pluginClass>
|
||||
</plugins>
|
||||
|
||||
<issueHandlers>
|
||||
<ClassMustBeFinal errorLevel="info"/>
|
||||
<ImplicitToStringCast errorLevel="info"/>
|
||||
<MissingClosureReturnType errorLevel="info"/>
|
||||
<MissingImmutableAnnotation errorLevel="info"/>
|
||||
<MissingOverrideAttribute errorLevel="info"/>
|
||||
<RedundantCast errorLevel="info"/>
|
||||
<RedundantCondition errorLevel="info"/>
|
||||
<UnnecessaryVarAnnotation errorLevel="suppress"/>
|
||||
</issueHandlers>
|
||||
|
||||
<forbiddenFunctions>
|
||||
<function name="var_dump" />
|
||||
<function name="dd" />
|
||||
</forbiddenFunctions>
|
||||
</psalm>
|
||||
Loading…
Reference in New Issue