chore(ci): update to Psalm 6

Signed-off-by: Oleksander Piskun <oleksandr2088@icloud.com>
This commit is contained in:
Oleksander Piskun
2025-06-05 15:10:22 +03:00
parent 5386235bb3
commit c207a7a7b1
16 changed files with 490 additions and 356 deletions

View File

@ -94,30 +94,6 @@ jobs:
- name: Run coding standards check
run: composer run psalm
php-security-analysis:
runs-on: ubuntu-22.04
permissions:
contents: read
actions: read
security-events: write
name: security analysis
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
with:
submodules: recursive
- name: Psalm
uses: docker://vimeo/psalm-github-actions:4.30.0
with:
security_analysis: true
composer_ignore_platform_reqs: false
report_file: results.sarif
- name: Upload Security Analysis results to GitHub
uses: github/codeql-action/upload-sarif@6bb031afdd8eb862ea3fc1848194185e076637e5 # v3.28.11
with:
sarif_file: results.sarif
js-eslint:
runs-on: ubuntu-22.04
name: eslint
@ -147,7 +123,7 @@ jobs:
permissions:
contents: none
runs-on: ubuntu-22.04
needs: [xml-lint, php-lint, php-cs, php-psalm-analysis, php-security-analysis, js-eslint, stylelint]
needs: [xml-lint, php-lint, php-cs, php-psalm-analysis, js-eslint, stylelint]
name: Lint-OK
steps:
- run: echo "Lint passed successfully"

View File

@ -18,7 +18,7 @@
"require-dev": {
"nextcloud/ocp": "dev-master",
"roave/security-advisories": "dev-latest",
"psalm/phar": "^5.15",
"psalm/phar": "6.7.x",
"nextcloud/coding-standard": "^1.1",
"friendsofphp/php-cs-fixer": "3.16"
},
@ -50,6 +50,7 @@
}
},
"require": {
"ext-simplexml": "*"
"ext-simplexml": "*",
"php": ">=8.1.0"
}
}

728
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -44,14 +44,13 @@ class ExAppInitStatusCheckJob extends TimedJob {
continue;
}
if ($exApp->getAppid() === Application::TEST_DEPLOY_APPID) {
// Check for smaller timeout for test deploy app
$initTimeoutMinutes = 0.5;
$initTimeoutSeconds = 30; // Check for smaller timeout(half of minute) for test deploy app
} else {
$initTimeoutMinutes = $initTimeoutMinutesSetting;
$initTimeoutSeconds = (int) ($initTimeoutMinutesSetting * 60);
}
if ((time() >= ($status['init_start_time'] + $initTimeoutMinutes * 60)) && (empty($status['error']))) {
if ((time() >= ($status['init_start_time'] + $initTimeoutSeconds)) && (empty($status['error']))) {
$this->service->setAppInitProgress(
$exApp, 0, sprintf('ExApp %s initialization timed out (%sm)', $exApp->getAppid(), $initTimeoutMinutes * 60)
$exApp, 0, sprintf('ExApp %s initialization timed out (%sm)', $exApp->getAppid(), $initTimeoutSeconds)
);
}
}

View File

@ -51,7 +51,7 @@ class ExAppOccCommand extends Entity implements JsonSerializable {
$this->addType('appid', 'string');
$this->addType('name', 'string');
$this->addType('description', 'string');
$this->addType('hidden', 'int');
$this->addType('hidden', 'integer');
$this->addType('arguments', 'json');
$this->addType('options', 'json');
$this->addType('usages', 'json');

View File

@ -73,12 +73,12 @@ class ExApp extends Entity implements JsonSerializable {
$this->addType('daemonConfigName', 'string');
$this->addType('protocol', 'string');
$this->addType('host', 'string');
$this->addType('port', 'int');
$this->addType('port', 'integer');
$this->addType('secret', 'string');
$this->addType('status', 'json');
$this->addType('enabled', 'int');
$this->addType('createdTime', 'int');
$this->addType('lastCheckTime', 'int');
$this->addType('enabled', 'integer');
$this->addType('createdTime', 'integer');
$this->addType('lastCheckTime', 'integer');
$this->addType('deployConfig', 'json');
$this->addType('acceptsDeployId', 'string');
$this->addType('routes', 'json');

View File

@ -39,7 +39,7 @@ class ExAppConfig extends Entity implements JsonSerializable {
$this->addType('appid', 'string');
$this->addType('configkey', 'string');
$this->addType('configvalue', 'string');
$this->addType('sensitive', 'int');
$this->addType('sensitive', 'integer');
if (isset($params['id'])) {
$this->setId($params['id']);

View File

@ -43,7 +43,7 @@ class ExAppPreference extends Entity implements JsonSerializable {
$this->addType('appid', 'string');
$this->addType('configkey', 'string');
$this->addType('configvalue', 'string');
$this->addType('sensitive', 'int');
$this->addType('sensitive', 'integer');
if (isset($params['id'])) {
$this->setId($params['id']);

View File

@ -56,7 +56,7 @@ class FilesActionsMenu extends Entity implements JsonSerializable {
$this->addType('displayName', 'string');
$this->addType('mime', 'string');
$this->addType('permissions', 'string');
$this->addType('order', 'int');
$this->addType('order', 'integer');
$this->addType('icon', 'string');
$this->addType('actionHandler', 'string');
$this->addType('version', 'string');

View File

@ -43,7 +43,7 @@ class TopMenu extends Entity implements JsonSerializable {
$this->addType('name', 'string');
$this->addType('display_name', 'string');
$this->addType('icon', 'string');
$this->addType('admin_required', 'int');
$this->addType('admin_required', 'integer');
if (isset($params['id'])) {
$this->setId($params['id']);

View File

@ -354,6 +354,9 @@ class DockerActions implements IDeployActions {
private function createTarArchive(string $filePath, string $pathInContainer): string {
$tempFile = $this->tempManager->getTemporaryFile('.tar');
if ($tempFile === false) {
throw new Exception("Failed to create tar archive (getTemporaryFile fails).");
}
try {
if (file_exists($tempFile)) {
@ -725,7 +728,7 @@ class DockerActions implements IDeployActions {
if (!$disableProgressTracking) {
$completedLayers = count(array_filter($layers));
$totalLayers = count($layers);
$newLastPercent = intval($totalLayers > 0 ? ($completedLayers / $totalLayers) * ($maxPercent - $startPercent) : 0);
$newLastPercent = intval($totalLayers > 0 ? (int)($completedLayers / $totalLayers) * ($maxPercent - $startPercent) : 0);
if ($lastPercent != $newLastPercent) {
$this->exAppService->setAppDeployProgress($exApp, $newLastPercent);
$lastPercent = $newLastPercent;

View File

@ -34,7 +34,7 @@ class ExAppUiMiddleware extends Middleware {
$output);
foreach ($controller->jsProxyMap as $key => $value) {
$output = preg_replace(
'/(src=")(\/.*?)(\/app_api\/js\/)(proxy_js\/' . $key . '.js)(.*")/',
'/(src=")(\/.*?)(\/app_api\/js\/)(proxy_js\/' . (string)$key . '.js)(.*")/',
'$1/index.php/apps/app_api/proxy/' . $value . '.js$5',
$output,
limit: 1);

View File

@ -14,7 +14,7 @@ use OCP\AppFramework\Http\ICallbackResponse;
use OCP\AppFramework\Http\IOutput;
use OCP\AppFramework\Http\Response;
/** @template-extends Response<int, array<string, mixed>> */
/** @template-extends Response<HttpAlias::STATUS_*, array<string, mixed>> */
class ProxyResponse extends Response implements ICallbackResponse {
private mixed $data;

View File

@ -89,12 +89,12 @@ class ScriptsService {
$mapResult = [];
$scripts = $this->mapper->findByAppIdTypeName($appId, $type, $name);
if (count($scripts) > self::MAX_JS_FILES) {
throw new LengthException('More than' . self::MAX_JS_FILES . 'JS files on one page are not supported.');
throw new LengthException('More than' . (string)self::MAX_JS_FILES . 'JS files on one page are not supported.');
}
$i = 0;
foreach ($scripts as $value) {
$fakeJsPath = 'proxy_js/' . $i;
$fakeJsPath = 'proxy_js/' . (string)$i;
if (empty($value['after_app_id'])) {
Util::addScript(Application::APP_ID, $fakeJsPath);
} else {

View File

@ -12,6 +12,8 @@
errorBaseline="tests/psalm-baseline.xml"
findUnusedCode="false"
findUnusedBaselineEntry="true"
ensureOverrideAttribute="false"
phpVersion="8.1"
>
<projectFiles>
<directory name="lib" />
@ -23,11 +25,6 @@
<directory name="vendor" />
</extraFiles>
<issueHandlers>
<UndefinedMagicMethod>
<errorLevel type="suppress">
<directory name="lib/" />
</errorLevel>
</UndefinedMagicMethod>
<UndefinedClass>
<errorLevel type="suppress">
<referencedClass name="OC" />

View File

@ -3,13 +3,12 @@
- SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
- SPDX-License-Identifier: AGPL-3.0-or-later
-->
<files psalm-version="5.25.0@01a8eb06b9e9cc6cfb6a320bf9fb14331919d505">
<files psalm-version="6.7.1@a2f190972555ea01b0cfcc1913924d6c5fc1a64e">
<file src="lib/AppInfo/Application.php">
<InvalidArgument>
<code><![CDATA[LoadFilesPluginListener::class]]></code>
<code><![CDATA[LoadMenuEntriesListener::class]]></code>
<code><![CDATA[SabrePluginAuthInitListener::class]]></code>
<code><![CDATA[registerEventListener]]></code>
</InvalidArgument>
<MissingDependency>
<code><![CDATA[DavPlugin]]></code>
@ -59,7 +58,6 @@
<code><![CDATA[ConnectException]]></code>
<code><![CDATA[ConnectException]]></code>
<code><![CDATA[Factory]]></code>
<code><![CDATA[ServerVersion]]></code>
</UndefinedClass>
</file>
<file src="lib/Fetcher/ExAppFetcher.php">
@ -79,9 +77,6 @@
<MissingTemplateParam>
<code><![CDATA[IEventListener]]></code>
</MissingTemplateParam>
<UndefinedClass>
<code><![CDATA[GetTaskProcessingProvidersEvent]]></code>
</UndefinedClass>
</file>
<file src="lib/Listener/LoadFilesPluginListener.php">
<ImplementedParamTypeMismatch>
@ -104,6 +99,28 @@
<ImplementedParamTypeMismatch>
<code><![CDATA[$event]]></code>
</ImplementedParamTypeMismatch>
<InvalidArgument>
<code><![CDATA[static function () use ($menuEntry) {
$appId = $menuEntry->getAppid();
$entryName = $menuEntry->getName();
$icon = $menuEntry->getIcon();
$urlGenerator = Server::get(IURLGenerator::class);
return [
'id' => Application::APP_ID . '_' . $appId . '_' . $entryName,
'type' => 'link',
'app' => Application::APP_ID,
'href' => $urlGenerator->linkToRoute(
'app_api.TopMenu.viewExAppPage', ['appId' => $appId, 'name' => $entryName]
),
'icon' => $icon === '' ?
$urlGenerator->imagePath('app_api', 'app.svg') :
$urlGenerator->linkToRoute(
'app_api.ExAppProxy.ExAppGet', ['appId' => $appId, 'other' => $icon]
),
'name' => Server::get(IFactory::class)->get($appId)->t($menuEntry->getDisplayName()),
];
}]]></code>
</InvalidArgument>
<InvalidDocblock>
<code><![CDATA[class LoadMenuEntriesListener implements IEventListener {]]></code>
</InvalidDocblock>
@ -113,9 +130,6 @@
<MissingTemplateParam>
<code><![CDATA[IEventListener]]></code>
</MissingTemplateParam>
<UndefinedClass>
<code><![CDATA[LoadAdditionalEntriesEvent]]></code>
</UndefinedClass>
</file>
<file src="lib/Listener/SabrePluginAuthInitListener.php">
<ImplementedParamTypeMismatch>
@ -135,6 +149,14 @@
<code><![CDATA[IEventListener]]></code>
</MissingTemplateParam>
</file>
<file src="lib/Middleware/ExAppUiMiddleware.php">
<InvalidNullableReturnType>
<code><![CDATA[beforeOutput]]></code>
</InvalidNullableReturnType>
<NullableReturnStatement>
<code><![CDATA[$output]]></code>
</NullableReturnStatement>
</file>
<file src="lib/Service/ExAppService.php">
<UndefinedClass>
<code><![CDATA[\OC\Memcache\APCu]]></code>