Skip to content

chore(license): normalise 3 stray AGPL-3.0 SPDX declarations to EUPL-1.2 - #134

Merged
rubenvdlinde merged 1 commit into
developmentfrom
chore/eupl-license-normalisation-2026-08-05
Aug 5, 2026
Merged

chore(license): normalise 3 stray AGPL-3.0 SPDX declarations to EUPL-1.2#134
rubenvdlinde merged 1 commit into
developmentfrom
chore/eupl-license-normalisation-2026-08-05

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

What

Three test files still declared SPDX-License-Identifier: AGPL-3.0-or-later, while every
other licence signal in the repo says EUPL-1.2: LICENSE (EUPL-1.2 text), composer.json,
package.json, appinfo/info.xml (<licence>EUPL-1.2</licence>), and every
lib/**/*.php @license tag.

File Was Now
tests/e2e/docs-screenshots.spec.ts AGPL-3.0-or-later EUPL-1.2
tests/e2e/visual/_visual-helpers.ts AGPL-3.0-or-later EUPL-1.2
tests/e2e/visual/openbuild.visual.spec.ts AGPL-3.0-or-later EUPL-1.2

⚠️ Deliberately NOT changed — and it needs a decision

lib/Resources/template/appinfo/info.xml:40 still says <licence>agpl</licence>.

This is a real defect with real consequence: it is the app scaffold the exporter ships, so
every app generated by OpenBuild is born declaring AGPL in its info.xml while its
composer.json and package.json (populated from the {{license}} placeholder, which
defaults to EUPL-1.2) say EUPL-1.2. The template's own LICENSE file is the EUPL-1.2
text and its <description> even reads "Vrij en open source onder de EUPL-1.2-licentie".

I did not fix it here, for three reasons:

  1. lib/Resources/template/ is a vendored snapshot of nextcloud-app-template.
    docs/releasing.md says, verbatim: "Do not scripted-edit individual files inside
    the snapshot — copy the whole tree."
  2. lib/Resources/template/.snapshot-meta.json records the exact upstream commit
    (7ee06aae…, snapshotted 2026-05-11). Hand-editing one file desynchronises the tree
    from its recorded source, and the next rsync -a --delete refresh silently reverts it.
  3. Upstream is already correctnextcloud-app-template/appinfo/info.xml says
    <licence>EUPL-1.2</licence> today. This is stale snapshot drift, not a wrong
    declaration needing a new decision.

The right fix is a snapshot refresh (whole-tree rsync + .path-manifest.txt +
.snapshot-meta.json + minor version bump + CHANGELOG), which is its own change and out
of scope for a licence-header normalisation sweep. Filing this for follow-up.

Other things deliberately NOT changed

  • LICENSE:177 and lib/Resources/template/LICENSE:177 — "GNU Affero General Public
    License (AGPL) v. 3" is an entry in the EUPL-1.2's own Appendix of compatible
    licences
    , not a declaration.
  • lib/Resources/template/README.md:246 — a list of EUPL-compatible copyleft licences.
  • src/dialogs/ExportDialog.vue:185{ label: 'AGPL-3.0', value: 'AGPL-3.0' } is a
    dropdown option offering the user a licence for the app they are generating. Not a
    declaration on this file; removing it would remove a user choice.
  • .license-overrides.json — justifications for third-party dependency licences
    (pako, sha.js).
  • .claude/openspec/architecture/adr-014-licensing.md:2 — states "appinfo/info.xml:
    MUST use <licence>agpl</licence> — Nextcloud app store does not recognise EUPL."

    This ADR is stale (the repo's own info.xml now says EUPL-1.2 and contradicts it),
    but amending an architectural decision is not a lint fix. Flagged for follow-up.
  • All @copyright / SPDX-FileCopyrightText lines.

Verification

Run identically before and after (PHPUnit under PHP 8.5 in a container — host PHP is 8.2,
below this repo's ^8.3):

before after
PHPUnit 746 tests, 2342 assertions, OK 746 tests, 2342 assertions, OK
vitest (npm run test:unit) 140 files / 1364 tests passed 140 files / 1364 tests passed
gate-28 license-triangle PASS PASS

Incidental finding (not touched)

src/services/manifestValidation/documentAttachments.js:136 contains two literal NUL
(0x00) bytes
inside a template literal, used as a composite-key separator. That makes
file classify the file as data and makes grep treat it as binary. It is a functional
code path, so it is out of scope here — but it could be written as the \0 escape for the
same value and better tool compatibility. Repo owners' call.

Three test files declared SPDX-License-Identifier: AGPL-3.0-or-later while
every other licence signal in the repo (LICENSE, composer.json, package.json,
appinfo/info.xml and every lib/**.php @license tag) says EUPL-1.2.

- tests/e2e/docs-screenshots.spec.ts
- tests/e2e/visual/_visual-helpers.ts
- tests/e2e/visual/openbuild.visual.spec.ts

NOT changed: lib/Resources/template/appinfo/info.xml still says
<licence>agpl</licence>. That file is inside the vendored nextcloud-app-template
snapshot, which docs/releasing.md says must be refreshed wholesale by rsync and
never hand-edited, and whose .snapshot-meta.json records the exact upstream
commit it came from. Upstream already says EUPL-1.2, so the correct fix is a
snapshot refresh, not an edit here. See the PR body.

Header-only change; PHPUnit (746 tests) and vitest (1364 tests) are identical
before and after. gate-28: PASS -> PASS.
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/openbuild @ 23fdb77

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
test-l10n
composer ✅ 101/101
npm ✅ 654/654
PHPUnit
Newman ⏭️
Playwright ⏭️
Hydra gates

Quality workflow — 2026-08-05 18:51 UTC

Download the full PDF report from the workflow artifacts.

@rubenvdlinde

Copy link
Copy Markdown
Contributor Author

Merging with Hydra Gates / Quality Report red. Adjudication:

gate-28 license-triangle: PASS.

Diff is licence-only. Every changed line is - SPDX-License-Identifier: AGPL-3.0-or-later+ SPDX-License-Identifier: EUPL-1.2. Grepping the diff for non-licence lines returns 0; no file is added, deleted or renamed.

The single failing gate is gate-58 e2e-networkidle, and its finding pre-exists. gate-58 is diff-scoped per ADR-020: it inspects only changed e2e files. The files this PR touches happen to be e2e specs, so a one-line licence header edit pulls a pre-existing violation into the gate's window.

Verified directly against the base tree — networkidle already appears 2 time(s) in these files at ref=development, and the number of lines this PR adds containing networkidle is 0. The wait was there before and is unchanged.

Why the base "green" is not the right comparison. Hydra Gates reports green on development pushes, but that green is void — the gate diffs against origin/development, which is HEAD, and logs SCOPE WAS EMPTY: 0 files differ / Every gate below passed by inspecting NOTHING before printing ALL APPLICABLE GATES PASSED. It is not evidence the base tree is clean, so base-tree file evidence is used above in its place.

Quality Report is a pure aggregator of the above. Where check:manifest also fails, it is red on the base branch too.

Nothing suppressed: no waiver, no baseline entry, no gate disabled. gate-58 stays red and the pre-existing networkidle waits remain to be fixed on their own merits (ADR-074 rule 4).

@rubenvdlinde
rubenvdlinde merged commit b411541 into development Aug 5, 2026
32 of 34 checks passed
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.

1 participant