Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions .github/workflows/ci-linux.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
name: Linux

permissions:
contents: read

on:
push:
branches:
Expand Down Expand Up @@ -204,3 +207,97 @@ jobs:
run: |
cd galette-core/galette/plugins/plugin-activities
../../vendor/bin/phpunit --test-suffix=.php --bootstrap tests/TestsBootstrap.php --no-coverage --process-isolation tests/GaletteActivities/

upgrade:
runs-on: ubuntu-latest

strategy:
matrix:
db-image: ['mysql:8.4', 'mariadb:11', 'postgres:17']
fail-fast: false

env:
DB: ${{ matrix.db-image }}

services:
# Label used to access the service container
db:
# Docker Hub image
image: ${{ matrix.db-image }}
# Provide env variables for both mysql and pgsql
env:
POSTGRES_USER: galette_tests
POSTGRES_PASSWORD: g@l3tte
POSTGRES_DB: galette_tests
MYSQL_USER: galette_tests
MYSQL_PASSWORD: g@l3tte
MYSQL_ROOT_PASSWORD: g@l3tte
MYSQL_DATABASE: galette_tests
# Open network ports for both mysql and pgsql
ports:
- 3306:3306
- 5432:5432
# Set health checks to wait until postgres has started
options: >-
--health-cmd="bash -c 'if [[ -n $(command -v pg_isready) ]]; then pg_isready; else if [[ -n $(command -v mysqladmin) ]]; then mysqladmin ping; else mariadb-admin ping; fi fi'"
--health-interval=10s
--health-timeout=5s
--health-retries=10

name: Upgrade from previous release on ${{ matrix.db-image }}

steps:
- name: PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.4'
tools: composer, pecl
coverage: none
extensions: apcu
ini-values: apc.enable_cli=1

- name: Build Galette
uses: galette/.github/actions/build-galette@main
with:
php-version: '8.4'

- name: Checkout plugin
uses: actions/checkout@v7
with:
path: galette-core/galette/plugins/plugin-activities
fetch-depth: 0

- name: Find previous release
run: |
cd galette-core/galette/plugins/plugin-activities
echo "PREVIOUS_RELEASE=$(git tag --list '[0-9]*' --sort=-v:refname --no-contains HEAD | head -n1)" >> $GITHUB_ENV

- name: Install previous release for PostgreSQL
env:
PGPASSWORD: g@l3tte
run: |
cd galette-core
bin/console galette:install -v --dbtype=pgsql --dbhost=localhost --dbname=galette_tests --dbuser=galette_tests --dbpass=g@l3tte --admin=admin --password=admin --no-interaction -w
git -C galette/plugins/plugin-activities show "$PREVIOUS_RELEASE:scripts/pgsql.sql" \
| psql -v ON_ERROR_STOP=1 -h localhost -U galette_tests galette_tests
if: startsWith(matrix.db-image, 'postgres')

- name: Install previous release for MariaDB
run: |
cd galette-core
mysql -e 'create database IF NOT EXISTS galette_tests;' -u galette_tests --password=g@l3tte -h 127.0.0.1 -P 3306
bin/console galette:install -v --dbtype=mysql --dbhost=127.0.0.1 --dbname=galette_tests --dbuser=galette_tests --dbpass=g@l3tte --admin=admin --password=admin --no-interaction -w
git -C galette/plugins/plugin-activities show "$PREVIOUS_RELEASE:scripts/mysql.sql" \
| mysql -u galette_tests --password=g@l3tte -h 127.0.0.1 -P 3306 galette_tests
if: startsWith(matrix.db-image, 'mysql') || startsWith(matrix.db-image, 'mariadb')

- name: Upgrade
run: |
cd galette-core
bin/console galette:plugins:install-db --no-interaction plugin-activities | tee upgrade.log
grep -q 'Database for plugin "plugin-activities" upgraded' upgrade.log

- name: Unit tests
run: |
cd galette-core/galette/plugins/plugin-activities
../../vendor/bin/phpunit --test-suffix=.php --bootstrap tests/TestsBootstrap.php --no-coverage --process-isolation tests/GaletteActivities/
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
2 changes: 1 addition & 1 deletion _define.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@
acls: [ //Permissions needed
'/activities_.*/' => 'staff'
],
dbver: 1.00
dbver: 1.1
);
25 changes: 25 additions & 0 deletions lib/GaletteActivities/PluginGaletteActivities.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@
use Galette\Core\Plugins\MemberActionProviderInterface;
use Galette\Core\Plugins\MenuProviderInterface;
use Galette\Entity\Adherent;
use Galette\Entity\Group;
use Galette\Core\GalettePlugin;
use GaletteActivities\Entity\Activity;
use GaletteActivities\Entity\Subscription;
use Laminas\Db\Metadata\Object\ConstraintObject;
use Laminas\Db\Metadata\Source\Factory;

/**
* Galette Activities plugin
Expand Down Expand Up @@ -142,4 +145,26 @@ public function isInstalled(): bool
$this->zdb->tableExists(ACTIVITIES_PREFIX . Activity::TABLE)
&& $this->zdb->tableExists(ACTIVITIES_PREFIX . Subscription::TABLE);
}

/**
* Database version of tables created before plugins versions tracking
*
* Before 1.1, the group foreign key was not updated in cascade on MySQL,
* and subscriptions columns accepted NULL on PostgreSQL.
*/
public function getLegacyDbVersion(): ?float
{
$metadata = Factory::createSourceFromAdapter($this->zdb->db);
/** @var ConstraintObject $constraint */
foreach ($metadata->getConstraints(PREFIX_DB . ACTIVITIES_PREFIX . Activity::TABLE) as $constraint) {
if ($constraint->isForeignKey() && $constraint->getColumns() === [Group::PK]) {
if ($constraint->getUpdateRule() !== 'CASCADE') {
return 1.0;
}
}
}

$column = $metadata->getColumn(Activity::PK, PREFIX_DB . ACTIVITIES_PREFIX . Subscription::TABLE);
return $column->isNullable() ? 1.0 : null;
}
}
13 changes: 8 additions & 5 deletions scripts/mysql.sql
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ CREATE TABLE galette_activities_activities (
creation_date date NOT NULL,
comment text,
PRIMARY KEY (id_activity),
FOREIGN KEY (id_group) REFERENCES galette_groups (id_group) ON DELETE RESTRICT ON UPDATE RESTRICT
CONSTRAINT galette_activities_activities_id_group_fkey FOREIGN KEY (id_group)
REFERENCES galette_groups (id_group) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;

--
Expand All @@ -33,16 +34,18 @@ CREATE TABLE galette_activities_subscriptions (
id_activity int(10) NOT NULL,
id_adh int(10) unsigned NOT NULL,
is_paid tinyint(1) NOT NULL default 0,
payment_amount decimal(15, 2) default '0',
payment_amount decimal(15, 2) default NULL,
payment_method tinyint(3) unsigned NOT NULL default '0',
creation_date date NOT NULL,
subscription_date date NOT NULL,
end_date date NOT NULL,
comment text,
PRIMARY KEY (id_subscription),
UNIQUE KEY (id_activity, id_adh),
FOREIGN KEY (id_activity) REFERENCES galette_activities_activities (id_activity) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (id_adh) REFERENCES galette_adherents (id_adh) ON DELETE CASCADE ON UPDATE CASCADE
CONSTRAINT galette_activities_subscriptions_id_activity_id_adh_key UNIQUE (id_activity, id_adh),
CONSTRAINT galette_activities_subscriptions_id_activity_fkey FOREIGN KEY (id_activity)
REFERENCES galette_activities_activities (id_activity) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT galette_activities_subscriptions_id_adh_fkey FOREIGN KEY (id_adh)
REFERENCES galette_adherents (id_adh) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;

SET FOREIGN_KEY_CHECKS=1;
6 changes: 3 additions & 3 deletions scripts/pgsql.sql
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ CREATE SEQUENCE galette_activities_subscriptions_id_seq
DROP TABLE IF EXISTS galette_activities_subscriptions CASCADE;
CREATE TABLE galette_activities_subscriptions (
id_subscription integer DEFAULT nextval('galette_activities_subscriptions_id_seq'::text) NOT NULL,
id_activity integer REFERENCES galette_activities_activities (id_activity) ON DELETE CASCADE ON UPDATE CASCADE,
id_adh integer REFERENCES galette_adherents (id_adh) ON DELETE CASCADE ON UPDATE CASCADE,
is_paid boolean default FALSE,
id_activity integer NOT NULL REFERENCES galette_activities_activities (id_activity) ON DELETE CASCADE ON UPDATE CASCADE,
id_adh integer NOT NULL REFERENCES galette_adherents (id_adh) ON DELETE CASCADE ON UPDATE CASCADE,
is_paid boolean NOT NULL default FALSE,
payment_amount decimal(15,2) NULL DEFAULT NULL,
payment_method smallint default '0' NOT NULL,
creation_date date NOT NULL,
Expand Down
65 changes: 65 additions & 0 deletions scripts/upgrade-to-1.1-mysql.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
--
-- This file is part of Galette Activities plugin (https://galette.eu).
-- SPDX-FileCopyrightText: Copyright © 2024-2026 The Galette Team
-- SPDX-License-Identifier: GPL-3.0-or-later
--

-- Align schema with PostgreSQL one: same foreign keys names and actions,
-- no default amount. Foreign keys names depend on the MySQL version that
-- created them, and MySQL cannot drop them conditionally: tables are rebuilt.
-- Foreign keys are added with checks enabled: without them, MariaDB records
-- ON DELETE RESTRICT as NO ACTION.
SET FOREIGN_KEY_CHECKS=0;

CREATE TABLE galette_activities_activities_new (
id_activity int(10) NOT NULL auto_increment,
name varchar(150) NOT NULL,
type varchar(3) NOT NULL default '',
price decimal(15, 2) default NULL,
id_group int unsigned default NULL,
creation_date date NOT NULL,
comment text,
PRIMARY KEY (id_activity)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;

INSERT INTO galette_activities_activities_new (id_activity, name, type, price, id_group, creation_date, comment)
SELECT id_activity, name, type, price, id_group, creation_date, comment
FROM galette_activities_activities;

CREATE TABLE galette_activities_subscriptions_new (
id_subscription int(10) NOT NULL auto_increment,
id_activity int(10) NOT NULL,
id_adh int(10) unsigned NOT NULL,
is_paid tinyint(1) NOT NULL default 0,
payment_amount decimal(15, 2) default NULL,
payment_method tinyint(3) unsigned NOT NULL default '0',
creation_date date NOT NULL,
subscription_date date NOT NULL,
end_date date NOT NULL,
comment text,
PRIMARY KEY (id_subscription),
CONSTRAINT galette_activities_subscriptions_id_activity_id_adh_key UNIQUE (id_activity, id_adh)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;

INSERT INTO galette_activities_subscriptions_new (id_subscription, id_activity, id_adh, is_paid, payment_amount,
payment_method, creation_date, subscription_date, end_date, comment)
SELECT id_subscription, id_activity, id_adh, is_paid, payment_amount,
payment_method, creation_date, subscription_date, end_date, comment
FROM galette_activities_subscriptions;

DROP TABLE galette_activities_subscriptions, galette_activities_activities;

RENAME TABLE galette_activities_activities_new TO galette_activities_activities,
galette_activities_subscriptions_new TO galette_activities_subscriptions;

SET FOREIGN_KEY_CHECKS=1;

ALTER TABLE galette_activities_activities
ADD CONSTRAINT galette_activities_activities_id_group_fkey FOREIGN KEY (id_group)
REFERENCES galette_groups (id_group) ON DELETE RESTRICT ON UPDATE CASCADE;

ALTER TABLE galette_activities_subscriptions
ADD CONSTRAINT galette_activities_subscriptions_id_activity_fkey FOREIGN KEY (id_activity)
REFERENCES galette_activities_activities (id_activity) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT galette_activities_subscriptions_id_adh_fkey FOREIGN KEY (id_adh)
REFERENCES galette_adherents (id_adh) ON DELETE CASCADE ON UPDATE CASCADE;
15 changes: 15 additions & 0 deletions scripts/upgrade-to-1.1-pgsql.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
--
-- This file is part of Galette Activities plugin (https://galette.eu).
-- SPDX-FileCopyrightText: Copyright © 2024-2026 The Galette Team
-- SPDX-License-Identifier: GPL-3.0-or-later
--

-- Align schema with MySQL one: subscriptions always have an activity, a member
-- and a payment status.
DELETE FROM galette_activities_subscriptions WHERE id_activity IS NULL OR id_adh IS NULL;
UPDATE galette_activities_subscriptions SET is_paid = FALSE WHERE is_paid IS NULL;

ALTER TABLE galette_activities_subscriptions
ALTER COLUMN id_activity SET NOT NULL,
ALTER COLUMN id_adh SET NOT NULL,
ALTER COLUMN is_paid SET NOT NULL;
20 changes: 20 additions & 0 deletions tests/GaletteActivities/tests/units/PluginGaletteActivities.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,24 @@ public function testIsInstalled(): void
{
$this->assertTrue($this->getPlugin()->isInstalled());
}

/**
* Tables created before 1.1 are detected; on MySQL, schema changes cannot be rolled back,
* the CI upgrade job covers them
*/
public function testLegacyDbVersion(): void
{
$plugin = $this->getPlugin();
$this->assertNull($plugin->getLegacyDbVersion());

if ($this->zdb->isPostgres()) {
//rolled back with the test transaction
$this->zdb->db->query(
'ALTER TABLE ' . PREFIX_DB . ACTIVITIES_PREFIX . \GaletteActivities\Entity\Subscription::TABLE
. ' ALTER COLUMN ' . \GaletteActivities\Entity\Activity::PK . ' DROP NOT NULL',
\Laminas\Db\Adapter\Adapter::QUERY_MODE_EXECUTE
);
$this->assertSame(1.0, $plugin->getLegacyDbVersion());
}
}
}
Loading