From 7bf0582aa0767504121dbb83d287b5de3ee2d067 Mon Sep 17 00:00:00 2001 From: Jeroen De Dauw Date: Sun, 10 May 2026 02:15:02 +0200 Subject: [PATCH 1/7] Drop EOL MW versions from CI matrix --- .github/workflows/ci.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 63a0d33..1f0cd15 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,15 +16,6 @@ jobs: - mw: 'REL1_39' php: 8.1 experimental: false - - mw: 'REL1_40' - php: 8.1 - experimental: false - - mw: 'REL1_41' - php: 8.2 - experimental: false - - mw: 'REL1_42' - php: 8.2 - experimental: false - mw: 'REL1_43' php: 8.3 experimental: false From e13445f87e3a00396b76f6d72a045bba98d261ff Mon Sep 17 00:00:00 2001 From: Jeroen De Dauw Date: Sun, 10 May 2026 14:47:41 +0200 Subject: [PATCH 2/7] Bump MW requirement to 1.43 and use composer phpunit on master --- .github/workflows/ci.yml | 14 ++++---------- extension.json | 2 +- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1f0cd15..04f3688 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,9 +13,6 @@ jobs: fail-fast: false matrix: include: - - mw: 'REL1_39' - php: 8.1 - experimental: false - mw: 'REL1_43' php: 8.3 experimental: false @@ -74,16 +71,13 @@ jobs: - name: Run update.php run: php maintenance/update.php --quick - - name: Run PHPUnit + - name: Run PHPUnit (MW < master) + if: matrix.mw != 'master' run: php tests/phpunit/phpunit.php -c extensions/ExternalContent/ - - name: Run PHPUnit with code coverage - run: php tests/phpunit/phpunit.php -c extensions/ExternalContent/ --coverage-clover coverage.xml - if: matrix.mw == 'master' - - - name: Upload code coverage - run: bash <(curl -s https://codecov.io/bash) + - name: Run PHPUnit (MW master) if: matrix.mw == 'master' + run: composer phpunit -- -c extensions/ExternalContent/ - name: Run parser tests run: php tests/parser/parserTests.php --file=extensions/ExternalContent/tests/parser/parserTests.txt diff --git a/extension.json b/extension.json index 082b975..c328cb2 100644 --- a/extension.json +++ b/extension.json @@ -13,7 +13,7 @@ "descriptionmsg": "external-content-desc", "requires": { - "MediaWiki": ">= 1.39.0", + "MediaWiki": ">= 1.43.0", "platform": { "php": ">= 8.0" } From 6432740f8a56def0bbeb53c85d0aad63322fcce0 Mon Sep 17 00:00:00 2001 From: Jeroen De Dauw Date: Sun, 10 May 2026 14:50:09 +0200 Subject: [PATCH 3/7] Fetch phpunit.xml.template before running composer phpunit on master --- .github/workflows/ci.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 04f3688..b3f576e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -77,7 +77,12 @@ jobs: - name: Run PHPUnit (MW master) if: matrix.mw == 'master' - run: composer phpunit -- -c extensions/ExternalContent/ + run: | + # phpunit.xml.template is export-ignored from the GitHub tarball, fetch it separately + if [ ! -f phpunit.xml.template ]; then + wget -q -O phpunit.xml.template "https://raw.githubusercontent.com/wikimedia/mediawiki/${{ matrix.mw }}/phpunit.xml.template" + fi + composer phpunit -- extensions/ExternalContent/tests/ - name: Run parser tests run: php tests/parser/parserTests.php --file=extensions/ExternalContent/tests/parser/parserTests.txt From da0e0bf9102912ce0bfa5691bc8d60c1ee8467ae Mon Sep 17 00:00:00 2001 From: Jeroen De Dauw Date: Sun, 10 May 2026 14:54:21 +0200 Subject: [PATCH 4/7] Use namespaced Title class for MW master compatibility --- tests/Integration/EmbedFunctionIntegrationTest.php | 2 +- tests/Integration/EmbedFunctionSystemTest.php | 2 +- tests/TestEnvironment.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Integration/EmbedFunctionIntegrationTest.php b/tests/Integration/EmbedFunctionIntegrationTest.php index 11a7641..d3ab3e3 100644 --- a/tests/Integration/EmbedFunctionIntegrationTest.php +++ b/tests/Integration/EmbedFunctionIntegrationTest.php @@ -54,7 +54,7 @@ public function testUsageIsTracked(): void { $parser->parse( '{{#embed:https://example.com/KITTENS.md}}', - \Title::newFromText( 'EmbedFunctionIntegrationTest' ), + \MediaWiki\Title\Title::newFromText( 'EmbedFunctionIntegrationTest' ), new \ParserOptions( \User::newSystemUser( 'TestUser' ) ) )->getText(); diff --git a/tests/Integration/EmbedFunctionSystemTest.php b/tests/Integration/EmbedFunctionSystemTest.php index 4392f64..ab58bf0 100644 --- a/tests/Integration/EmbedFunctionSystemTest.php +++ b/tests/Integration/EmbedFunctionSystemTest.php @@ -6,7 +6,7 @@ use CommentStoreComment; use FileFetcher\StubFileFetcher; -use Title; +use MediaWiki\Title\Title; use User; use WikiPage; diff --git a/tests/TestEnvironment.php b/tests/TestEnvironment.php index 2f9c5dd..064ec34 100644 --- a/tests/TestEnvironment.php +++ b/tests/TestEnvironment.php @@ -5,7 +5,7 @@ namespace ProfessionalWiki\ExternalContent\Tests; use MediaWiki\MediaWikiServices; -use Title; +use MediaWiki\Title\Title; class TestEnvironment { From bc2e336c60d7c3509f81cd6c949a08e0e6fbe35d Mon Sep 17 00:00:00 2001 From: Jeroen De Dauw Date: Sun, 10 May 2026 15:27:34 +0200 Subject: [PATCH 5/7] Migrate to namespaced MediaWiki classes for 1.43+ --- src/Adapters/EmbedPresenter/CategoryUsageTracker.php | 2 +- .../EmbedPresenter/ParserFunctionEmbedPresenter.php | 2 +- .../ParserFunctionEmbedResourceLoader.php | 2 +- src/Domain/ContentRenderer/CodeRenderer.php | 2 +- src/EmbedExtensionFactory.php | 2 +- src/EntryPoints/BitbucketFunction.php | 2 +- src/EntryPoints/EmbedFunction.php | 2 +- src/EntryPoints/MediaWikiHooks.php | 8 ++++---- tests/Integration/EmbedFunctionIntegrationTest.php | 9 ++++++--- tests/Integration/EmbedFunctionSystemTest.php | 12 +++++++----- tests/TestEnvironment.php | 6 ++++-- tests/TestFactory.php | 2 +- 12 files changed, 29 insertions(+), 22 deletions(-) diff --git a/src/Adapters/EmbedPresenter/CategoryUsageTracker.php b/src/Adapters/EmbedPresenter/CategoryUsageTracker.php index 5f20a2b..4b3805c 100644 --- a/src/Adapters/EmbedPresenter/CategoryUsageTracker.php +++ b/src/Adapters/EmbedPresenter/CategoryUsageTracker.php @@ -4,7 +4,7 @@ namespace ProfessionalWiki\ExternalContent\Adapters\EmbedPresenter; -use Parser; +use MediaWiki\Parser\Parser; class CategoryUsageTracker implements UsageTracker { diff --git a/src/Adapters/EmbedPresenter/ParserFunctionEmbedPresenter.php b/src/Adapters/EmbedPresenter/ParserFunctionEmbedPresenter.php index f538943..288daf2 100644 --- a/src/Adapters/EmbedPresenter/ParserFunctionEmbedPresenter.php +++ b/src/Adapters/EmbedPresenter/ParserFunctionEmbedPresenter.php @@ -4,7 +4,7 @@ namespace ProfessionalWiki\ExternalContent\Adapters\EmbedPresenter; -use Html; +use MediaWiki\Html\Html; use MessageLocalizer; use ProfessionalWiki\ExternalContent\UseCases\Embed\EmbedPresenter; diff --git a/src/Adapters/EmbedResourceLoader/ParserFunctionEmbedResourceLoader.php b/src/Adapters/EmbedResourceLoader/ParserFunctionEmbedResourceLoader.php index cf38e9c..c9a9819 100644 --- a/src/Adapters/EmbedResourceLoader/ParserFunctionEmbedResourceLoader.php +++ b/src/Adapters/EmbedResourceLoader/ParserFunctionEmbedResourceLoader.php @@ -4,7 +4,7 @@ namespace ProfessionalWiki\ExternalContent\Adapters\EmbedResourceLoader; -use ParserOutput; +use MediaWiki\Parser\ParserOutput; use ProfessionalWiki\ExternalContent\Domain\ContentRenderer; use ProfessionalWiki\ExternalContent\Domain\ContentRenderer\CodeRenderer; use ProfessionalWiki\ExternalContent\UseCases\Embed\EmbedResourceLoader; diff --git a/src/Domain/ContentRenderer/CodeRenderer.php b/src/Domain/ContentRenderer/CodeRenderer.php index 84a466e..5b3e8ef 100644 --- a/src/Domain/ContentRenderer/CodeRenderer.php +++ b/src/Domain/ContentRenderer/CodeRenderer.php @@ -4,7 +4,7 @@ namespace ProfessionalWiki\ExternalContent\Domain\ContentRenderer; -use Html; +use MediaWiki\Html\Html; use ProfessionalWiki\ExternalContent\Domain\ContentRenderer; class CodeRenderer implements ContentRenderer { diff --git a/src/EmbedExtensionFactory.php b/src/EmbedExtensionFactory.php index 589ffe7..b64e2ff 100644 --- a/src/EmbedExtensionFactory.php +++ b/src/EmbedExtensionFactory.php @@ -6,7 +6,7 @@ use FileFetcher\FileFetcher; use MediaWiki\MediaWikiServices; -use Message; +use MediaWiki\Message\Message; use MessageLocalizer; use ProfessionalWiki\ExternalContent\Adapters\FileFetcher\DomainCredentials; use ProfessionalWiki\ExternalContent\Adapters\FileFetcher\MediaWikiFileFetcher; diff --git a/src/EntryPoints/BitbucketFunction.php b/src/EntryPoints/BitbucketFunction.php index 62c0b70..abc26d3 100644 --- a/src/EntryPoints/BitbucketFunction.php +++ b/src/EntryPoints/BitbucketFunction.php @@ -4,7 +4,7 @@ namespace ProfessionalWiki\ExternalContent\EntryPoints; -use Parser; +use MediaWiki\Parser\Parser; use ProfessionalWiki\ExternalContent\Adapters\EmbedPresenter\CategoryUsageTracker; use ProfessionalWiki\ExternalContent\Adapters\EmbedPresenter\ParserFunctionEmbedPresenter; use ProfessionalWiki\ExternalContent\Adapters\EmbedResourceLoader\ParserFunctionEmbedResourceLoader; diff --git a/src/EntryPoints/EmbedFunction.php b/src/EntryPoints/EmbedFunction.php index 644e81f..2e2ce43 100644 --- a/src/EntryPoints/EmbedFunction.php +++ b/src/EntryPoints/EmbedFunction.php @@ -4,7 +4,7 @@ namespace ProfessionalWiki\ExternalContent\EntryPoints; -use Parser; +use MediaWiki\Parser\Parser; use ProfessionalWiki\ExternalContent\Adapters\EmbedPresenter\CategoryUsageTracker; use ProfessionalWiki\ExternalContent\Adapters\EmbedPresenter\ParserFunctionEmbedPresenter; use ProfessionalWiki\ExternalContent\Adapters\EmbedResourceLoader\ParserFunctionEmbedResourceLoader; diff --git a/src/EntryPoints/MediaWikiHooks.php b/src/EntryPoints/MediaWikiHooks.php index 3daf24d..ece12ea 100644 --- a/src/EntryPoints/MediaWikiHooks.php +++ b/src/EntryPoints/MediaWikiHooks.php @@ -4,14 +4,14 @@ namespace ProfessionalWiki\ExternalContent\EntryPoints; -use ContentHandler; +use MediaWiki\Content\ContentHandler; use MediaWiki\MediaWikiServices; +use MediaWiki\Page\WikiPage; +use MediaWiki\Parser\Parser; +use MediaWiki\Parser\ParserOutput; use MediaWiki\Revision\RevisionRecord; -use Parser; -use ParserOutput; use ProfessionalWiki\ExternalContent\EmbedExtensionFactory; use SearchEngine; -use WikiPage; final class MediaWikiHooks { diff --git a/tests/Integration/EmbedFunctionIntegrationTest.php b/tests/Integration/EmbedFunctionIntegrationTest.php index d3ab3e3..c22599e 100644 --- a/tests/Integration/EmbedFunctionIntegrationTest.php +++ b/tests/Integration/EmbedFunctionIntegrationTest.php @@ -7,6 +7,9 @@ use FileFetcher\InMemoryFileFetcher; use FileFetcher\StubFileFetcher; use MediaWiki\MediaWikiServices; +use MediaWiki\Parser\ParserOptions; +use MediaWiki\Title\Title; +use MediaWiki\User\User; use ProfessionalWiki\ExternalContent\Tests\TestEnvironment; /** @@ -54,9 +57,9 @@ public function testUsageIsTracked(): void { $parser->parse( '{{#embed:https://example.com/KITTENS.md}}', - \MediaWiki\Title\Title::newFromText( 'EmbedFunctionIntegrationTest' ), - new \ParserOptions( \User::newSystemUser( 'TestUser' ) ) - )->getText(); + Title::newFromText( 'EmbedFunctionIntegrationTest' ), + new ParserOptions( User::newSystemUser( 'TestUser' ) ) + )->runOutputPipeline( null, [] )->getRawText(); // Since the category name depends on the wiki language, we need to skip this test when it is not English. if ( MediaWikiServices::getInstance()->getContentLanguage()->getCode() === 'en' ) { diff --git a/tests/Integration/EmbedFunctionSystemTest.php b/tests/Integration/EmbedFunctionSystemTest.php index ab58bf0..3c946d7 100644 --- a/tests/Integration/EmbedFunctionSystemTest.php +++ b/tests/Integration/EmbedFunctionSystemTest.php @@ -4,11 +4,13 @@ namespace ProfessionalWiki\ExternalContent\Tests\Integration; -use CommentStoreComment; use FileFetcher\StubFileFetcher; +use MediaWiki\CommentStore\CommentStoreComment; +use MediaWiki\Content\Content; +use MediaWiki\Content\ContentHandler; +use MediaWiki\Page\WikiPage; use MediaWiki\Title\Title; -use User; -use WikiPage; +use MediaWiki\User\User; /** * @group Database @@ -56,11 +58,11 @@ private function createPage( string $title, string $content ): WikiPage { return $this->createPageWithContent( $title, - \ContentHandler::makeContent( $content, $titleObject ) + ContentHandler::makeContent( $content, $titleObject ) ); } - private function createPageWithContent( string $title, \Content $content ): WikiPage { + private function createPageWithContent( string $title, Content $content ): WikiPage { $titleObject = Title::newFromText( $title ); $page = new WikiPage( $titleObject ); diff --git a/tests/TestEnvironment.php b/tests/TestEnvironment.php index 064ec34..e1de123 100644 --- a/tests/TestEnvironment.php +++ b/tests/TestEnvironment.php @@ -5,7 +5,9 @@ namespace ProfessionalWiki\ExternalContent\Tests; use MediaWiki\MediaWikiServices; +use MediaWiki\Parser\ParserOptions; use MediaWiki\Title\Title; +use MediaWiki\User\User; class TestEnvironment { @@ -26,8 +28,8 @@ public function parse( string $textToParse, ?Title $contextPage = null ): string ->parse( $textToParse, $contextPage ?? Title::newFromText( 'ContextPage' ), - new \ParserOptions( \User::newSystemUser( 'TestUser' ) ) - )->getText(); + new ParserOptions( User::newSystemUser( 'TestUser' ) ) + )->runOutputPipeline( null, [] )->getRawText(); } } diff --git a/tests/TestFactory.php b/tests/TestFactory.php index d50fa16..29f5d5b 100644 --- a/tests/TestFactory.php +++ b/tests/TestFactory.php @@ -6,7 +6,7 @@ use FileFetcher\FileFetcher; use FileFetcher\NullFileFetcher; -use Message; +use MediaWiki\Message\Message; use MessageLocalizer; use ProfessionalWiki\ExternalContent\EmbedExtensionFactory; From bdfc6faf9f54ff9e4fae8a73a574dd409d17d371 Mon Sep 17 00:00:00 2001 From: Jeroen De Dauw Date: Sun, 10 May 2026 15:30:37 +0200 Subject: [PATCH 6/7] Fix runOutputPipeline args and revert WikiPage namespace (not in REL1_43) --- src/EntryPoints/MediaWikiHooks.php | 2 +- tests/Integration/EmbedFunctionIntegrationTest.php | 5 +++-- tests/Integration/EmbedFunctionSystemTest.php | 2 +- tests/TestEnvironment.php | 5 +++-- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/EntryPoints/MediaWikiHooks.php b/src/EntryPoints/MediaWikiHooks.php index ece12ea..3822a9d 100644 --- a/src/EntryPoints/MediaWikiHooks.php +++ b/src/EntryPoints/MediaWikiHooks.php @@ -6,12 +6,12 @@ use MediaWiki\Content\ContentHandler; use MediaWiki\MediaWikiServices; -use MediaWiki\Page\WikiPage; use MediaWiki\Parser\Parser; use MediaWiki\Parser\ParserOutput; use MediaWiki\Revision\RevisionRecord; use ProfessionalWiki\ExternalContent\EmbedExtensionFactory; use SearchEngine; +use WikiPage; final class MediaWikiHooks { diff --git a/tests/Integration/EmbedFunctionIntegrationTest.php b/tests/Integration/EmbedFunctionIntegrationTest.php index c22599e..5677dc0 100644 --- a/tests/Integration/EmbedFunctionIntegrationTest.php +++ b/tests/Integration/EmbedFunctionIntegrationTest.php @@ -54,12 +54,13 @@ public function testUsageIsTracked(): void { $this->extensionFactory->setFileFetcher( new InMemoryFileFetcher( [] ) ); $parser = MediaWikiServices::getInstance()->getParser(); + $parserOptions = new ParserOptions( User::newSystemUser( 'TestUser' ) ); $parser->parse( '{{#embed:https://example.com/KITTENS.md}}', Title::newFromText( 'EmbedFunctionIntegrationTest' ), - new ParserOptions( User::newSystemUser( 'TestUser' ) ) - )->runOutputPipeline( null, [] )->getRawText(); + $parserOptions + )->runOutputPipeline( $parserOptions, [] )->getRawText(); // Since the category name depends on the wiki language, we need to skip this test when it is not English. if ( MediaWikiServices::getInstance()->getContentLanguage()->getCode() === 'en' ) { diff --git a/tests/Integration/EmbedFunctionSystemTest.php b/tests/Integration/EmbedFunctionSystemTest.php index 3c946d7..21635de 100644 --- a/tests/Integration/EmbedFunctionSystemTest.php +++ b/tests/Integration/EmbedFunctionSystemTest.php @@ -8,9 +8,9 @@ use MediaWiki\CommentStore\CommentStoreComment; use MediaWiki\Content\Content; use MediaWiki\Content\ContentHandler; -use MediaWiki\Page\WikiPage; use MediaWiki\Title\Title; use MediaWiki\User\User; +use WikiPage; /** * @group Database diff --git a/tests/TestEnvironment.php b/tests/TestEnvironment.php index e1de123..821aafe 100644 --- a/tests/TestEnvironment.php +++ b/tests/TestEnvironment.php @@ -24,12 +24,13 @@ public function wikiUrl( string $pageName ): ?string { } public function parse( string $textToParse, ?Title $contextPage = null ): string { + $parserOptions = new ParserOptions( User::newSystemUser( 'TestUser' ) ); return MediaWikiServices::getInstance()->getParser() ->parse( $textToParse, $contextPage ?? Title::newFromText( 'ContextPage' ), - new ParserOptions( User::newSystemUser( 'TestUser' ) ) - )->runOutputPipeline( null, [] )->getRawText(); + $parserOptions + )->runOutputPipeline( $parserOptions, [] )->getRawText(); } } From 51f528a5ab925e2599fb94ee880481be5081318e Mon Sep 17 00:00:00 2001 From: Jeroen De Dauw Date: Sun, 10 May 2026 15:33:49 +0200 Subject: [PATCH 7/7] Use getContentHolderText (works on REL1_43 and master) --- tests/Integration/EmbedFunctionIntegrationTest.php | 2 +- tests/TestEnvironment.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Integration/EmbedFunctionIntegrationTest.php b/tests/Integration/EmbedFunctionIntegrationTest.php index 5677dc0..be34453 100644 --- a/tests/Integration/EmbedFunctionIntegrationTest.php +++ b/tests/Integration/EmbedFunctionIntegrationTest.php @@ -60,7 +60,7 @@ public function testUsageIsTracked(): void { '{{#embed:https://example.com/KITTENS.md}}', Title::newFromText( 'EmbedFunctionIntegrationTest' ), $parserOptions - )->runOutputPipeline( $parserOptions, [] )->getRawText(); + )->runOutputPipeline( $parserOptions, [] )->getContentHolderText(); // Since the category name depends on the wiki language, we need to skip this test when it is not English. if ( MediaWikiServices::getInstance()->getContentLanguage()->getCode() === 'en' ) { diff --git a/tests/TestEnvironment.php b/tests/TestEnvironment.php index 821aafe..754f7b6 100644 --- a/tests/TestEnvironment.php +++ b/tests/TestEnvironment.php @@ -30,7 +30,7 @@ public function parse( string $textToParse, ?Title $contextPage = null ): string $textToParse, $contextPage ?? Title::newFromText( 'ContextPage' ), $parserOptions - )->runOutputPipeline( $parserOptions, [] )->getRawText(); + )->runOutputPipeline( $parserOptions, [] )->getContentHolderText(); } }