Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
57e634c
Add project tooling and scaffolding
jeppekroghitk Jun 19, 2026
d400ae8
Add Docker development environment
jeppekroghitk Jun 19, 2026
389daf5
Add Symfony skeleton and dependencies
jeppekroghitk Jun 19, 2026
db99323
Add application code
jeppekroghitk Jun 19, 2026
16adfa4
Add docker-compose.yml
jeppekroghitk Jun 19, 2026
dc3cc25
Normalized composer
jeppekroghitk Jun 19, 2026
bdfa46d
Improved Taskfile
jeppekroghitk Jun 19, 2026
f99461c
Added project name and description to composer.json
jeppekroghitk Jun 19, 2026
68c78e0
Coding standards
jeppekroghitk Jun 19, 2026
58b2b02
Updated CHANGELOG
jeppekroghitk Jun 19, 2026
3f606d9
Removed dependency on task start for task install
jeppekroghitk Jun 19, 2026
164e963
Fix HTTPS and login behind the reverse proxy
jeppekroghitk Jun 19, 2026
33110da
Coding standards
jeppekroghitk Jun 22, 2026
6b7e149
Removed rabbitmq reference in readme
jeppekroghitk Jun 23, 2026
3fa9130
Removed API, draft and public states
jeppekroghitk Jun 23, 2026
7dae296
Added asset-map:compile command to install task
jeppekroghitk Jun 23, 2026
3616bc1
Removed nelmio_cors bundle and added reference.php to .gitignore
jeppekroghitk Jun 23, 2026
e8ea25f
Consolidated migrations
jeppekroghitk Jun 23, 2026
0f1c449
Add multiselect for kontaktpersoner
jeppekroghitk Jun 23, 2026
6a90008
fix: harden against stored XSS, role tampering and open redirects
jeppekroghitk Jun 24, 2026
1a2f871
fix: resolve CSV export N+1, LIKE wildcards and pagination edge cases
jeppekroghitk Jun 24, 2026
24bd24b
refactor: drop Google Fonts CDN and move inline styles to CSS
jeppekroghitk Jun 24, 2026
0e5b4e6
chore: document access model and tidy scaffolding comments
jeppekroghitk Jun 24, 2026
0d351b4
test: add test suite and a 100% coverage gate
jeppekroghitk Jun 24, 2026
1117668
ci: run the test suite via composer scripts across a MariaDB matrix
jeppekroghitk Jun 24, 2026
eb79b9a
fix tests
jeppekroghitk Jun 24, 2026
c494ca4
ci: test against a single (production) MariaDB version
jeppekroghitk Jun 24, 2026
bb1dc24
Removed nelmio cors and set default secret in env
jeppekroghitk Jun 24, 2026
7cbd647
use rregeer/phpunit-coverage-check to check coverage
jeppekroghitk Jun 24, 2026
6735441
use stubs for expectation-less doubles and fail on PHPUnit notices
jeppekroghitk Jun 24, 2026
75c1e01
Move max image size to .env for adjustment
jeppekroghitk Jun 25, 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
5 changes: 5 additions & 0 deletions .docker/data/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Ignore everything in this directory
*
# Except
!.gitignore
!README.md
5 changes: 5 additions & 0 deletions .docker/data/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# .docker/data

Please map persistent volumes to this directory on the servers.

If a container needs to persist data between restarts you can map the relevant files in the container to ``docker/data/<container-name>`.
34 changes: 34 additions & 0 deletions .docker/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
worker_processes auto;

error_log /dev/stderr notice;
pid /tmp/nginx.pid;

events {
worker_connections 1024;
}

http {
proxy_temp_path /tmp/proxy_temp;
client_body_temp_path /tmp/client_temp;
fastcgi_temp_path /tmp/fastcgi_temp;
uwsgi_temp_path /tmp/uwsgi_temp;
scgi_temp_path /tmp/scgi_temp;

include /etc/nginx/mime.types;
default_type application/octet-stream;

# Note: set_real_ip_from is set in the server block

log_format main '$http_x_real_ip - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log /dev/stdout main;

sendfile on;
keepalive_timeout 65;

gzip on;

include /etc/nginx/conf.d/*.conf;
}
56 changes: 56 additions & 0 deletions .docker/templates/default.conf.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
server {
listen ${NGINX_PORT};
server_name localhost;

root ${NGINX_WEB_ROOT};

client_max_body_size ${NGINX_MAX_BODY_SIZE};

set_real_ip_from 172.16.0.0/16;
set_real_ip_from 192.168.39.0/24;
real_ip_recursive on;
real_ip_header X-Forwarded-For;

location = /cron-metrics {
# Proxy to supercronic metrics
proxy_pass http://${NGINX_CRON_METRICS}/metrics;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}

location / {
# try to serve file directly, fallback to index.php
try_files $uri /index.php$is_args$args;
}

# Protect files and directories from prying eyes.
location ~* \.(engine|inc|install|make|module|profile|po|sh|.*sql|.tar|.gz|.bz2|theme|twig|tpl(\.php)?|xtmpl|yml)(~|\.sw[op]|\.bak|\.orig|\.save)?$|^(\.(?!well-known).*|Entries.*|Repository|Root|Tag|Template|composer\.(json|lock)|web\.config)$|^#.*#$|\.php(~|\.sw[op]|\.bak|\.orig|\.save)$ {
deny all;
return 404;
}

location ~ ^/index\.php(/|$) {
fastcgi_buffers 16 32k;
fastcgi_buffer_size 64k;
fastcgi_busy_buffers_size 64k;

fastcgi_pass ${NGINX_FPM_SERVICE};
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;

fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;

internal;
}

location ~ \.php$ {
return 404;
}

# Send log message to files symlinked to stdout/stderr.
error_log /dev/stderr;
access_log /dev/stdout main;
}
17 changes: 17 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# editorconfig.org

root = true

[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true

[{compose.yaml,compose.*.yaml}]
indent_size = 2

[*.md]
trim_trailing_whitespace = false
51 changes: 51 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
COMPOSE_PROJECT_NAME=itk-project-database
COMPOSE_DOMAIN=itk-project-database.local.itkdev.dk
ITKDEV_TEMPLATE=symfony-8

# In all environments, the following files are loaded if they exist,
# the latter taking precedence over the former:
#
# * .env contains default values for the environment variables needed by the app
# * .env.local uncommitted file with local overrides
# * .env.$APP_ENV committed environment-specific defaults
# * .env.$APP_ENV.local uncommitted environment-specific overrides
#
# Real environment variables win over .env files.
#
# DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES.
# https://symfony.com/doc/current/configuration/secrets.html
#
# Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2).
# https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration

###> symfony/framework-bundle ###
APP_ENV=dev
APP_SECRET=dev-secret-not-for-production-override-in-prod
APP_SHARE_DIR=var/share
# Trust the local Docker reverse proxy (Traefik -> nginx) so X-Forwarded-Proto is
# honoured. nginx's real_ip sets REMOTE_ADDR to the real client, so trust REMOTE_ADDR.
TRUSTED_PROXIES=127.0.0.1,REMOTE_ADDR
###< symfony/framework-bundle ###

###> symfony/routing ###
# Configure how to generate URLs in non-HTTP contexts, such as CLI commands.
# See https://symfony.com/doc/current/routing.html#generating-urls-in-commands
DEFAULT_URI=http://localhost
###< symfony/routing ###

###> doctrine/doctrine-bundle ###
# Format described at https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
# IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml
#
# DATABASE_URL="sqlite:///%kernel.project_dir%/var/data_%kernel.environment%.db"
# DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=8.0.32&charset=utf8mb4"
# DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=10.11.2-MariaDB&charset=utf8mb4"
DATABASE_URL="mysql://db:db@mariadb:3306/db?serverVersion=10.11.2-MariaDB&charset=utf8mb4"
###< doctrine/doctrine-bundle ###

###> app ###
# Maximum upload sizes for initiative media. Accepts a number of bytes or a
# shorthand suffix (k, M, G), e.g. "8M" — see the Symfony File/Image constraint.
INITIATIVE_IMAGE_MAX_SIZE=8M
INITIATIVE_ATTACHMENT_MAX_SIZE=16M
###< app ###
8 changes: 8 additions & 0 deletions .env.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# define your env variables for the test env here
KERNEL_CLASS='App\Kernel'
APP_SECRET='$ecretf0rt3st'

# Tests connect as root so the suite can create/drop the ephemeral test database
# (the unprivileged app user only has access to the main database). Credentials
# match the dev MariaDB container; serverVersion is overridable for the CI matrix.
DATABASE_URL="mysql://root:password@mariadb:3306/db?serverVersion=${MARIADB_VERSION:-10.11.2-MariaDB}&charset=utf8mb4"
18 changes: 18 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#### Link to ticket

Please add a link to the ticket being addressed by this change.

#### Description

Please include a short description of the suggested change and the reasoning behind the approach you have chosen.

#### Screenshot of the result

If your change affects the user interface you should include a screenshot of the result with the pull request.

#### Checklist

- [ ] My code is covered by test cases.
- [ ] My code passes our test (all our tests).
- [ ] My code passes our static analysis suite.
- [ ] My code passes our continuous integration process.
27 changes: 27 additions & 0 deletions .github/workflows/changelog.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Do not edit this file! Make a pull request on changing
# github/workflows/changelog.yaml in
# https://github.com/itk-dev/devops_itkdev-docker if need be.

### ### Changelog
###
### Checks that changelog has been updated

name: Changelog

on:
pull_request:

jobs:
changelog:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 2

- name: Git fetch
run: git fetch

- name: Check that changelog has been updated.
run: git diff --exit-code origin/${{ github.base_ref }} -- CHANGELOG.md && exit 1 || exit 0
79 changes: 79 additions & 0 deletions .github/workflows/composer.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Do not edit this file! Make a pull request on changing
# github/workflows/composer.yaml in
# https://github.com/itk-dev/devops_itkdev-docker if need be.

### ### Composer
###
### Validates composer.json and checks that it's normalized.
###
### #### Assumptions
###
### 1. A docker compose service named `phpfpm` can be run and `composer` can be
### run inside the `phpfpm` service.
### 2. [ergebnis/composer-normalize](https://github.com/ergebnis/composer-normalize)
### is a dev requirement in `composer.json`:
###
### ``` shell
### docker compose run --rm phpfpm composer require --dev ergebnis/composer-normalize
### ```
###
### Normalize `composer.json` by running
###
### ``` shell
### docker compose run --rm phpfpm composer normalize
### ```

name: Composer

env:
COMPOSE_USER: runner

on:
pull_request:
paths: &paths
- "composer.json"
- "composer.lock"
- "docker-compose.yml"
push:
branches:
- main
- develop
paths: *paths

jobs:
composer-validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6

- name: Create docker network
run: |
docker network create frontend

- run: |
docker compose run --rm phpfpm composer validate --strict

composer-normalized:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6

- name: Create docker network
run: |
docker network create frontend

- run: |
docker compose run --rm phpfpm composer install
docker compose run --rm phpfpm composer normalize --dry-run

composer-audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6

- name: Create docker network
run: |
docker network create frontend

- run: |
docker compose run --rm phpfpm composer audit --locked
39 changes: 39 additions & 0 deletions .github/workflows/javascript.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Do not edit this file! Make a pull request on changing
# github/workflows/symfony/javascript.yaml in
# https://github.com/itk-dev/devops_itkdev-docker if need be.

### ### Symfony JavaScript (and TypeScript)
###
### Validates JavaScript files.
###
### #### Assumptions
###
### 1. A docker compose service named `prettier` for running
### [Prettier](https://prettier.io/) exists.

name: JavaScript

on:
pull_request:
paths: &paths
- "assets/**/*.js"
- "docker-compose.yml"
push:
branches:
- main
- develop
paths: *paths

jobs:
javascript-lint:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6

- name: Create docker network
run: |
docker network create frontend

- run: |
docker compose run --rm prettier 'assets/**/*.js' --check
45 changes: 45 additions & 0 deletions .github/workflows/markdown.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Do not edit this file! Make a pull request on changing
# github/workflows/markdown.yaml in
# https://github.com/itk-dev/devops_itkdev-docker if need be.

### ### Markdown
###
### Lints Markdown files (`**/*.md`) in the project.
###
### [markdownlint-cli configuration
### files](https://github.com/igorshubovych/markdownlint-cli?tab=readme-ov-file#configuration),
### `.markdownlint.jsonc` and `.markdownlintignore`, control what is actually
### linted and how.
###
### #### Assumptions
###
### 1. A docker compose service named `markdownlint` for running `markdownlint`
### (from
### [markdownlint-cli](https://github.com/igorshubovych/markdownlint-cli))
### exists.

name: Markdown

on:
pull_request:
paths: &paths
- "**/*.md"
push:
branches:
- main
- develop
paths: *paths

jobs:
markdown-lint:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6

- name: Create docker network
run: |
docker network create frontend

- run: |
docker compose run --rm markdownlint markdownlint '**/*.md'
Loading
Loading