Compare commits

...

2 commits

Author SHA1 Message Date
921d59560e 169 - Run the test suite against MariaDB instead of SQLite
Some checks failed
CI / ci (pull_request) Failing after 27s
2026-09-27 00:59:12 +02:00
831983c87a 148 - Pin image versions and stop publishing latest
All checks were successful
CI / ci (pull_request) Successful in 1m53s
CI / ci (push) Successful in 1m49s
2026-09-26 23:06:30 +02:00
13 changed files with 45 additions and 22 deletions

View file

@ -11,8 +11,13 @@ BCRYPT_ROUNDS=4
LOG_CHANNEL=stack
LOG_STACK=single
DB_CONNECTION=sqlite
DB_DATABASE=:memory:
# Host and credentials must match docker/dev/docker-compose.yml; nothing enforces it.
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=ffr_testing
DB_USERNAME=ffr
DB_PASSWORD=ffr
SESSION_DRIVER=array

View file

@ -1,7 +1,6 @@
name: Build and Push Docker Image
on:
push:
branches: [main]
tags: ['v*']
jobs:

View file

@ -10,7 +10,20 @@ jobs:
ci:
runs-on: docker
container:
image: forge.lvl0.xyz/lvl0/fedi-feed-router-ci:php8.3-3
image: forge.lvl0.xyz/lvl0/fedi-feed-router-ci:php8.3-4
services:
db:
image: mariadb:11
env:
MARIADB_DATABASE: ffr_testing
MARIADB_USER: ffr
MARIADB_PASSWORD: ffr
MARIADB_ROOT_PASSWORD: ffr_root_ci
options: >-
--health-cmd="healthcheck.sh --connect --innodb_initialized"
--health-interval=10s
--health-timeout=5s
--health-retries=10
steps:
- uses: https://data.forgejo.org/actions/checkout@v4

View file

@ -18,10 +18,10 @@ jobs:
include:
- name: fedi-feed-router-base
file: docker/build/Dockerfile.base
version: php8.3-1
version: php8.3-2
- name: fedi-feed-router-ci
file: docker/build/Dockerfile.ci
version: php8.3-3
version: php8.3-4
steps:
- uses: https://data.forgejo.org/actions/checkout@v4
@ -43,5 +43,4 @@ jobs:
push: true
tags: |
forge.lvl0.xyz/lvl0/${{ matrix.name }}:${{ matrix.version }}
forge.lvl0.xyz/lvl0/${{ matrix.name }}:latest
forge.lvl0.xyz/lvl0/${{ matrix.name }}:${{ github.sha }}

View file

@ -1,5 +1,5 @@
# Production Dockerfile - uses pre-built base image
FROM forge.lvl0.xyz/lvl0/fedi-feed-router-base:latest
FROM forge.lvl0.xyz/lvl0/fedi-feed-router-base:php8.3-2
# Set working directory
WORKDIR /app

View file

@ -1,5 +1,5 @@
# Base image with FrankenPHP, PHP extensions, Node, and Composer
FROM dunglas/frankenphp:latest-php8.3-alpine
FROM dunglas/frankenphp:1.12.7-php8.3.35-alpine
# Install system dependencies
RUN apk add --no-cache \

View file

@ -1,6 +1,7 @@
# Image for CI: PHP and Composer only, no runtime server or frontend toolchain.
# Tests run against sqlite in memory (see .env.testing), so no database client
# or cache extension is needed.
# pdo_mysql is here for the MariaDB test database (#169); pdo_sqlite stays until
# that switch lands. No CLI database client — PHPUnit reaches the database
# through PDO and never shells out.
#
# Published as fedi-feed-router-ci:php<version>-<revision>, not :latest. Runners
# cache mutable tags and will not re-pull them, so bump the revision in the tag
@ -16,6 +17,7 @@ COPY --from=mlocati/php-extension-installer:2 /usr/bin/install-php-extensions /u
RUN install-php-extensions \
pdo_sqlite \
pdo_mysql \
mbstring \
dom \
xml \

View file

@ -56,6 +56,7 @@ services:
MYSQL_ROOT_PASSWORD: "${DB_ROOT_PASSWORD:-ffr_root_dev}"
volumes:
- db_data:/var/lib/mysql
- ./initdb:/docker-entrypoint-initdb.d:ro
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 10s

View file

@ -0,0 +1,7 @@
-- Runs only on an empty data directory. Recreate the volume to apply changes.
CREATE DATABASE IF NOT EXISTS ffr_testing
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
GRANT ALL PRIVILEGES ON ffr_testing.* TO 'ffr'@'%';
FLUSH PRIVILEGES;

View file

@ -23,8 +23,8 @@
<server name="APP_MAINTENANCE_DRIVER" value="file" force="true"/>
<server name="BCRYPT_ROUNDS" value="4" force="true"/>
<server name="CACHE_STORE" value="array" force="true"/>
<server name="DB_CONNECTION" value="sqlite" force="true"/>
<server name="DB_DATABASE" value=":memory:" force="true"/>
<server name="DB_CONNECTION" value="mysql" force="true"/>
<server name="DB_DATABASE" value="ffr_testing" force="true"/>
<server name="MAIL_MAILER" value="array" force="true"/>
<server name="PULSE_ENABLED" value="false" force="true"/>
<server name="QUEUE_CONNECTION" value="sync" force="true"/>

View file

@ -62,7 +62,7 @@ public function test_maps_rows_to_the_local_channel_by_name(): void
{
$this->restoreLegacyTable();
$channel = PlatformChannel::factory()->create(['name' => 'newsbottest', 'channel_id' => 'newsbottest']);
$channel = PlatformChannel::factory()->create(['name' => 'newsbottest']);
$this->seedLegacyRow('217', 'newsbottest', '1');
$this->seedLegacyRow('217', 'newsbottest', '2');
@ -76,7 +76,7 @@ public function test_drops_rows_that_match_no_channel(): void
{
$this->restoreLegacyTable();
PlatformChannel::factory()->create(['name' => 'newsbottest', 'channel_id' => 'newsbottest']);
PlatformChannel::factory()->create(['name' => 'newsbottest']);
$this->seedLegacyRow('999', 'a-community-that-no-longer-exists', '1');
$this->runMigration();
@ -94,12 +94,10 @@ public function test_drops_rows_whose_channel_name_is_ambiguous_across_instances
PlatformChannel::factory()->create([
'platform_instance_id' => $first->id,
'name' => 'news',
'channel_id' => 'news',
]);
PlatformChannel::factory()->create([
'platform_instance_id' => $second->id,
'name' => 'news',
'channel_id' => 'news-two',
]);
$this->seedLegacyRow('8', 'news', '1');
@ -113,7 +111,7 @@ public function test_leaves_a_schema_the_new_code_can_use(): void
{
$this->restoreLegacyTable();
$channel = PlatformChannel::factory()->create(['name' => 'newsbottest', 'channel_id' => 'newsbottest']);
$channel = PlatformChannel::factory()->create(['name' => 'newsbottest']);
$this->seedLegacyRow('217', 'newsbottest', '1');
$this->runMigration();

View file

@ -41,7 +41,6 @@ protected function setUp(): void
$instance = PlatformInstance::factory()->create(['url' => 'https://lemmy.test']);
$channel = PlatformChannel::factory()->create([
'platform_instance_id' => $instance->id,
'channel_id' => 'news',
'name' => 'news',
]);
$account = PlatformAccount::factory()->create(['instance_url' => 'https://lemmy.test']);
@ -180,7 +179,6 @@ public function test_a_second_instance_with_the_same_community_name_does_not_col
$otherInstance = PlatformInstance::factory()->create(['url' => 'https://other.test']);
$otherChannel = PlatformChannel::factory()->create([
'platform_instance_id' => $otherInstance->id,
'channel_id' => 'news',
'name' => 'news',
]);

View file

@ -89,7 +89,8 @@ public function test_listener_skips_already_validated_articles(): void
public function test_listener_skips_articles_with_existing_publication(): void
{
$feed = Feed::factory()->create();
Route::factory()->active()->create(['feed_id' => $feed->id]);
/** @var Route $route */
$route = Route::factory()->active()->create(['feed_id' => $feed->id]);
$article = Article::factory()->create([
'feed_id' => $feed->id,
@ -98,7 +99,7 @@ public function test_listener_skips_articles_with_existing_publication(): void
ArticlePublication::create([
'article_id' => $article->id,
'post_id' => 'test-post-id',
'platform_channel_id' => 1,
'platform_channel_id' => $route->platform_channel_id,
'published_at' => now(),
'published_by' => 'test-user',
]);