Skip to content

ci: enable Psalm static analysis with a baseline (#82) - #120

Merged
Jaggob merged 3 commits into
mainfrom
chore/82-psalm
Jun 2, 2026
Merged

ci: enable Psalm static analysis with a baseline (#82)#120
Jaggob merged 3 commits into
mainfrom
chore/82-psalm

Conversation

@Jaggob

@Jaggob Jaggob commented Jun 2, 2026

Copy link
Copy Markdown
Collaborator

What

psalm.xml was referenced in the issue but didn't actually exist, and Psalm was never installed or run. This wires up static analysis end-to-end.

Changes

  • Dev-deps: vimeo/psalm ^6.16 + nextcloud/ocp ^31 (the public OCP type signatures; ^31 = our min supported NC, so usage of newer-than-31 APIs gets flagged).
  • OCP resolution without disturbing PHPUnit: nextcloud/ocp registers no composer autoload, so a Psalm-only SPL autoloader (tests/psalm/ocp-autoload.php, referenced via psalm.xml's autoloader=) makes OCP\/NCU\ types resolvable. The runtime/PHPUnit autoloader keeps using its local stubs — no double-definition, PHPUnit stays green (396).
  • Config: psalm.xml analyses lib/ at errorLevel="4"; vendor/ is scanned for symbols only.
  • Baseline strategy: the current 134 findings are captured in psalm-baseline.xml so the check passes today and only fails on new issues — gradual cleanup, no blocking up-front pass (per the issue's "baseline" option).
  • CI: new paths-filtered Psalm workflow runs composer psalm on PRs.
  • Convenience: composer psalm / composer psalm:baseline scripts.
  • Release hygiene: psalm.xml + psalm-baseline.xml excluded from the release tarball and the rsync deploy.

Acceptance

  • vendor/bin/psalm exits 0 (with baseline) on this branch
  • CI runs Psalm on PRs and fails on new issues
  • PHPUnit unaffected (396 green)

Follow-up (not this PR)

The 134 baselined findings (~66 trivial: MissingOverrideAttribute, RedundantCast; ~36 OCP-resolution artifacts; ~32 real type issues) can be burned down incrementally — each fix shrinks the baseline.

Tooling/CI only, no runtime code path changes.

Closes #82.

Jaggob added 3 commits June 2, 2026 18:55
Psalm was configured but never installed or run. Wire it up:

- Add vimeo/psalm + nextcloud/ocp (the public OCP type signatures) as
  dev-dependencies. nextcloud/ocp ships no composer autoload, so a Psalm-only
  SPL autoloader (tests/psalm/ocp-autoload.php, referenced via psalm.xml's
  <autoloader>) makes the OCP/NCU types resolvable for analysis without
  touching the runtime/PHPUnit autoloader (which keeps its local stubs).
- psalm.xml analyses lib/ at errorLevel 4; vendor is scanned for symbols only.
- Capture the current 134 findings in psalm-baseline.xml so the check passes
  today and only fails on NEW issues — gradual cleanup instead of a blocking
  up-front pass.
- New Psalm CI job (paths-filtered) runs composer psalm on PRs.
- composer scripts: psalm / psalm:baseline.
- Exclude psalm.xml + psalm-baseline.xml from the release tarball and the
  rsync deploy (dev tooling, not shipped).

PHPUnit (396) stays green; composer psalm exits 0 against the baseline.

Closes #82.
…the PHPUnit matrix

Psalm pulled symfony 8.x transitively, which requires PHP >= 8.4, so the
shared dev lock could not be installed on the PHPUnit matrix's 8.2/8.3 jobs
(composer install failed there). Set config.platform.php to 8.2.27 (psalm's
lowest supported 8.2 patch) and re-resolve: symfony drops to 7.4.x, which
supports PHP 8.2+, so composer install now succeeds across 8.2/8.3/8.4.

Psalm + PHPUnit (396) stay green.
Review follow-up on #120: the composer platform pin (8.2.27) only governs
dependency resolution; Psalm's analysis target is separate. Set phpVersion=8.1
to match info.xml's declared php min-version, so 8.2-only language usage that
would break on 8.1 is flagged. Baseline regenerated against 8.1 (still 134).

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR wires up Psalm static analysis end-to-end for the repository (config + baseline + CI), so static analysis runs on pull requests and only fails on newly introduced issues while the existing findings remain suppressed via a baseline.

Changes:

  • Add Psalm configuration (psalm.xml) and a baseline file (psalm-baseline.xml) to enable incremental adoption.
  • Add a Psalm-only autoloader for resolving Nextcloud public API (OCP/NCU) type stubs without affecting runtime/PHPUnit.
  • Add a new GitHub Actions workflow to run Psalm on PRs (paths-filtered), and add Composer scripts + dev dependencies to support it.

Reviewed changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated no comments.

Show a summary per file
File Description
tests/psalm/ocp-autoload.php Adds a Psalm-only SPL autoloader to resolve OCP\/NCU\ type signature files from nextcloud/ocp.
scripts/deploy-rsync.sh Excludes Psalm config/baseline files from rsync deploy output.
scripts/build-release-tarball.sh Excludes psalm-baseline.xml from release tarball (alongside existing psalm.xml exclusion).
psalm.xml Introduces Psalm configuration (scopes analysis to lib/, uses baseline, registers custom autoloader).
psalm-baseline.xml Captures current Psalm findings so CI only fails on new issues.
composer.json Adds vimeo/psalm + nextcloud/ocp dev dependencies and Composer scripts for running Psalm / generating baseline.
composer.lock Locks new dev dependencies (Psalm + transitive deps; nextcloud/ocp).
.github/workflows/psalm.yml Adds a PR workflow that runs composer psalm, gated by a paths filter.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@Jaggob
Jaggob merged commit 26a60fd into main Jun 2, 2026
14 checks passed
@Jaggob
Jaggob deleted the chore/82-psalm branch June 17, 2026 14:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enable Psalm static analysis

2 participants