Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
7a6014c
feat: prep db identifiers for cross-platform portability
turegjorup May 7, 2026
15866e3
docs: substitute PR number in CHANGELOG entry
turegjorup May 7, 2026
9230fac
Merge branch 'main' into develop
tuj May 26, 2026
129a0d4
docs: retarget PR from 2.7 to 2.8 (changelog + migration docblock)
turegjorup May 27, 2026
3e5f668
Merge remote-tracking branch 'origin/develop' into feature/portabilit…
turegjorup May 27, 2026
6dab272
style: wrap CHANGELOG bullets to 120 chars (markdownlint MD013)
turegjorup May 27, 2026
25f774d
Merge pull request #444 from os2display/feature/portability-prep-rename
turegjorup May 27, 2026
ca821d5
Changed filter to filter through IDs instead of name on Area and Faci…
Jun 9, 2026
1279e8b
Added pull request link to CHANGELOG.md
Jun 9, 2026
c2e2cf2
feat: add app:utils:convert-env-to-3x command
turegjorup Jun 10, 2026
b09d251
docs: add changelog entry for #495
turegjorup Jun 10, 2026
c634de6
feat: make env/compose output byte-clean for host-side redirection
turegjorup Jun 10, 2026
927722c
Removed ID fields for v1.0 and added områdeId and facilitetsId in par…
Jun 11, 2026
1e4e56a
Move supportsIdFiltering into getData
Jun 12, 2026
c3ea1f0
Merge pull request #486 from os2display/358/change-area-and-facility-…
tuj Jun 15, 2026
d399707
fix: address review feedback on convert-env-to-3x command
turegjorup Jun 23, 2026
926413d
Merge remote-tracking branch 'origin/develop' into feature/convert-en…
turegjorup Jun 23, 2026
20a9031
Merge pull request #495 from os2display/feature/convert-env-to-3x-com…
turegjorup Jun 23, 2026
fee9179
chore(release): 2.8.0
turegjorup Jun 23, 2026
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
64 changes: 64 additions & 0 deletions .github/workflows/pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,70 @@ jobs:
- name: Validate Doctrine schema
run: APP_ENV=prod php bin/console doctrine:schema:validate

validate-doctrine-schema-postgres:
runs-on: ubuntu-latest
env:
DATABASE_URL: postgresql://db:db@127.0.0.1:5432/db?serverVersion=16&charset=utf8
strategy:
fail-fast: false
matrix:
php: ["8.3"]
name: Validate Doctrine Schema on Postgres (PHP ${{ matrix.php }})
services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_USER: db
POSTGRES_PASSWORD: db
POSTGRES_DB: db
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U db -d db"
--health-interval=5s
--health-timeout=3s
--health-retries=10
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup PHP, with composer and extensions
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php}}
# pgsql/pdo_pgsql added on top of the standard extension list so
# Doctrine can connect to Postgres for the portability gate.
extensions: apcu, ctype, iconv, imagick, json, pdo_pgsql, pgsql, redis, soap, xmlreader, zip
coverage: none

- name: Get composer cache directory
id: composer-cache
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT

- name: Cache composer dependencies
uses: actions/cache@v4
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ matrix.php }}-composer-

- name: 'Composer install with exported .env variables'
run: |
set -a && source .env && set +a
APP_ENV=prod composer install --no-dev -o

# The 2.x historical migrations use raw MariaDB SQL and can't run on
# Postgres — that's the whole reason this PR exists. We instead apply
# the entity layer directly via schema:update, which tests the
# load-bearing claim that the *metadata* (after the rename) is
# platform-portable. doctrine:schema:validate then catches any drift
# between Postgres' generated DDL and what Doctrine expects.
- name: Apply entity metadata to Postgres (schema:update)
run: APP_ENV=prod php bin/console doctrine:schema:update --force --complete --no-interaction

- name: Validate Doctrine schema (Postgres)
run: APP_ENV=prod php bin/console doctrine:schema:validate

php-cs-fixer:
runs-on: ubuntu-latest
strategy:
Expand Down
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,23 @@ All notable changes to this project will be documented in this file.

## [Unreleased]

## [2.8.0] - 2026-06-23

- [#495](https://github.com/os2display/display-api-service/pull/495)
- Added `app:utils:convert-env-to-3x` command that converts the loaded configuration of a running 2.x
installation (env vars + admin/client config.json) to 3.x environment configuration, with screen,
dotenv and docker compose output formats.
- [#486](https://github.com/os2display/display-api-service/pull/486)
- Changed BRND feed area and facility filters to match on `områdeId` and `facilitetsId` instead of area/facility names.
- Mapped area and facility IDs centrally in `parseBrndBooking()`.
- ID filtering is only supported for BRND API v2.0; area/facility fields are hidden in admin for v1.0 feed sources.
- [#444](https://github.com/os2display/display-api-service/pull/444)
- Renamed 15 `changed_idx` indexes to `<table>_changed_idx` for cross-platform portability
(Postgres scopes index names schema-wide).
- Quoted `user` table identifier in entity metadata so Doctrine emits the platform-native quote on every reference.
- Added Postgres CI gate that runs `doctrine:schema:update --force --complete` +
`doctrine:schema:validate` against a Postgres 16 service container.

## [2.7.1] - 2026-05-26

- [#460](https://github.com/os2display/display-api-service/pull/460)
Expand Down
42 changes: 42 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,48 @@ variable](https://symfony.com/doc/current/components/phpunit_bridge.html#configu
docker compose exec --env SYMFONY_DEPRECATIONS_HELPER=disabled phpfpm composer tests
```

## Preparing an upgrade to 3.x

The `app:utils:convert-env-to-3x` command converts the configuration of this
(2.x) installation to 3.x environment configuration. The values _loaded_ in
the running application are treated as canonical — whether they come from
real environment variables, a docker compose `environment` block or
`.env`/`.env.local` files — and every variable the application reads is
written out under its 3.x name.

Unless `--skip-config-json` is given, the command also fetches the canonical
admin and client configuration from `<app-url>/admin/config.json` and
`<app-url>/client/config.json` and converts them to the 3.x `ADMIN_*` and
`CLIENT_*` variables. The base URL is inferred from the loaded OIDC redirect
URIs (or `COMPOSE_DOMAIN`) and can be overridden with `--app-url`.

```shell
# Review on screen (default):
docker compose exec phpfpm bin/console app:utils:convert-env-to-3x

# Write a dotenv file ON THE HOST, the starting point for the 3.x .env.local.
# With --output=env (and --output=compose) the document goes to stdout and all
# notes/warnings go to stderr, so the result can be redirected from outside
# the container (-T: no TTY, keeps stdout byte-clean):
docker compose exec -T phpfpm bin/console app:utils:convert-env-to-3x \
--output=env --app-url=https://display.example.com > env.3x

# Or a docker compose environment block:
docker compose exec -T phpfpm bin/console app:utils:convert-env-to-3x --output=compose > env.3x.yml
```

Note that `--file` writes inside the container, so it only makes sense for
paths on a mounted volume; prefer the host-side redirect above in dockerised
setups.

Loaded variables the Symfony application cannot read (`COMPOSE_*`, `PHP_*`,
`NGINX_*`, `MARIADB_*`/`MYSQL_*`) are listed in a trailing advisory with a
note on where each belongs in a 3.x deployment: compose orchestration values
go in the docker host `.env`, and the container-tuning values go on the
respective containers (`.env.php`, `.env.nginx`, `.env.mariadb` in the
`os2display-docker-server` file layout). They are never part of the
application env output.

## CI

Github Actions are used to run the test suite and code style checks on all PRs.
Expand Down
59 changes: 59 additions & 0 deletions migrations/Version20260507120000.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

/**
* Portability prep: give the 15 `changed_idx` indexes table-scoped names so
* they don't collide on platforms (such as Postgres) that scope index names
* schema-wide rather than per-table.
*
* No-op for MariaDB at runtime. Landing on 2.8 means the consolidated 3.0
* migration can emit the portable shape from the start, keeping
* `migrations:rollup` honest for 2.x → 3.0 upgraders. The reserved-keyword
* problem with the `user` table is handled separately by backtick-quoting
* the identifier in the entity attribute (no rename needed).
*/
final class Version20260507120000 extends AbstractMigration
{
private const CHANGED_IDX_TABLES = [
'feed',
'feed_source',
'media',
'playlist',
'playlist_screen_region',
'playlist_slide',
'screen',
'screen_campaign',
'screen_group',
'screen_group_campaign',
'screen_layout',
'screen_layout_regions',
'slide',
'template',
'theme',
];

public function getDescription(): string
{
return 'Uniquify the 15 `changed_idx` indexes (table-scoped names) for cross-platform portability.';
}

public function up(Schema $schema): void
{
foreach (self::CHANGED_IDX_TABLES as $table) {
$this->addSql(sprintf('ALTER TABLE `%s` RENAME INDEX `changed_idx` TO `%s_changed_idx`', $table, $table));
}
}

public function down(Schema $schema): void
{
foreach (self::CHANGED_IDX_TABLES as $table) {
$this->addSql(sprintf('ALTER TABLE `%s` RENAME INDEX `%s_changed_idx` TO `changed_idx`', $table, $table));
}
}
}
Loading
Loading