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
13 changes: 13 additions & 0 deletions .docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
ARG PHP_VERSION=8.4

FROM php:${PHP_VERSION}-cli

COPY --from=composer:2 /usr/bin/composer /usr/local/bin/composer

RUN apt-get update \
&& apt-get install --no-install-recommends --yes unzip \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /app

COPY . .
12 changes: 12 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.git
.direnv
.idea
vendor
composer.lock
result
result-*
tests/coverage.dat
tests/**/*.actual
tests/**/*.expected
tests/tmp/*
!tests/tmp/.gitignore
2 changes: 2 additions & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# shellcheck shell=bash
use flake
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,8 @@
vendor

composer.lock

.direnv

result
result-*
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,40 @@ composer require kdyby/forms-replicator

**Note:** Version 3.0 requires `nette/component-model >= 3.1.0`.

## Local compatibility testing

Enter the reproducible development shell with [Nix](https://nixos.org/) and [direnv](https://direnv.net/):

```sh
direnv allow
```

The shell provides PHP 8.5, Composer, Just, the Docker CLI, ShellCheck, Actionlint, and the Nix formatter. Install highest dependencies locally for development and editor indexing with:

```sh
just install
```

Composer runs as your local user, so `vendor/` remains writable by your editor and development tools.

Run the local CI suite against the installed dependencies with `just ci`.

Docker is the compatibility source of truth. Run the complete PHP and dependency matrix with:

```sh
just matrix
```

The matrix copies source into ephemeral images instead of bind-mounting the checkout. Container-owned dependencies and lock files therefore never alter host permissions; only Composer's immutable download cache is shared through a Docker volume.

The seven cells cover PHP 8.2, 8.3, and 8.4 with lowest and highest Composer dependencies, plus PHP 8.5 with highest dependencies. PHP 8.5 with lowest dependencies is excluded because component-model 3.1 itself emits PHP 8.5 deprecations.

To run one focused cell, pass its PHP version and dependency set directly:

```sh
just cell 8.2 lowest
```

## Overview

- [Learn more in the documentation](https://github.com/Kdyby/FormsReplicator/blob/master/docs/en/index.md)
Expand Down
127 changes: 127 additions & 0 deletions bin/test-matrix
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
#!/bin/sh

set -eu

usage() {
printf 'Usage: %s [<php-version> <lowest|highest>]\n' "$0" >&2
}

case $# in
0)
php_versions='8.2 8.3 8.4 8.5'
dependency_sets='lowest highest'
;;
2)
case $1 in
8.2|8.3|8.4|8.5) ;;
*)
printf 'Unsupported PHP version: %s\n' "$1" >&2
usage
exit 2
;;
esac

case $2 in
lowest|highest) ;;
*)
printf 'Unsupported dependency set: %s\n' "$2" >&2
usage
exit 2
;;
esac

if [ "$1" = '8.5' ] && [ "$2" = 'lowest' ]; then
printf 'PHP 8.5 with lowest dependencies is not supported.\n' >&2
exit 2
fi

php_versions=$1
dependency_sets=$2
;;
*)
usage
exit 2
;;
esac

project_root=$(CDPATH='' cd "$(dirname "$0")/.." && pwd)
cd "$project_root"

cache_volume='forms-replicator-composer-download-cache'

cleanup_exit() {
status=$?
trap - 0
[ -z "$iidfile" ] || rm -f "$iidfile" || :
exit "$status"
}

cleanup_signal() {
signal=$1
trap - 0 1 2 15
[ -z "$iidfile" ] || rm -f "$iidfile" || :
kill -s "$signal" "$$"
}

for php_version in $php_versions; do
image="forms-replicator-test-matrix:php-${php_version}"
iidfile=''
trap cleanup_exit 0
trap 'cleanup_signal HUP' 1
trap 'cleanup_signal INT' 2
trap 'cleanup_signal TERM' 15
iidfile=$(mktemp "${TMPDIR:-/tmp}/forms-replicator-test-matrix.XXXXXX")

printf '\nBuilding source image for PHP %s\n' "$php_version"
if docker build \
--build-arg "PHP_VERSION=$php_version" \
--file .docker/Dockerfile \
--iidfile "$iidfile" \
--tag "$image" \
.; then
:
else
status=$?
printf 'Matrix image build failed: PHP %s\n' "$php_version" >&2
exit "$status"
fi

IFS= read -r image_id < "$iidfile" || [ -n "$image_id" ]
rm -f "$iidfile"
trap - 0 1 2 15

for dependency_set in $dependency_sets; do
cell="PHP $php_version / $dependency_set"
if [ "$php_version" = '8.5' ] && [ "$dependency_set" = 'lowest' ]; then
printf '\nSkipping unsupported matrix cell: %s\n' "$cell"
continue
fi

printf '\nRunning matrix cell: %s\n' "$cell"

case $dependency_set in
lowest)
commands='composer update --prefer-dist --no-interaction --no-progress --prefer-lowest --prefer-stable && composer phpstan && composer test'
;;
highest)
commands='composer update --prefer-dist --no-interaction --no-progress && composer ci'
;;
esac

if docker run \
--rm \
--env COMPOSER_ALLOW_SUPERUSER=1 \
--env COMPOSER_CACHE_DIR=/tmp/composer-cache \
--volume "$cache_volume:/tmp/composer-cache/files" \
"$image_id" \
sh -c "$commands"; then
printf 'Matrix cell passed: %s\n' "$cell"
else
status=$?
printf 'Matrix cell failed: %s\n' "$cell" >&2
exit "$status"
fi
done
done

printf '\nAll selected matrix cells passed.\n'
27 changes: 27 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 33 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
description = "Development tools for Kdyby FormsReplicator";

inputs.nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";

outputs = {nixpkgs, ...}: let
supportedSystems = [
"aarch64-darwin"
"aarch64-linux"
"x86_64-linux"
];
forAllSystems = function:
nixpkgs.lib.genAttrs supportedSystems (
system: function nixpkgs.legacyPackages.${system}
);
in {
formatter = forAllSystems (pkgs: pkgs.alejandra);

devShells = forAllSystems (pkgs: {
default = pkgs.mkShellNoCC {
packages = with pkgs; [
actionlint
alejandra
docker-client
just
php85
php85Packages.composer
shellcheck
];
};
});
};
}
27 changes: 27 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# List available development commands.
default:
@just --list

# Install highest dependencies locally for development and editor indexing.
install:
composer update --prefer-dist --no-interaction --no-progress

# Run the complete CI suite against locally installed dependencies.
ci:
composer ci

# Run every supported PHP and dependency combination in Docker.
matrix:
./bin/test-matrix

# Run lowest dependencies on every compatible PHP version.
lowest:
@set -eu; for php in 8.2 8.3 8.4; do ./bin/test-matrix "$php" lowest; done

# Run highest dependencies on every supported PHP version.
highest:
@set -eu; for php in 8.2 8.3 8.4 8.5; do ./bin/test-matrix "$php" highest; done

# Run one Docker matrix cell, e.g. `just cell 8.5 highest`.
cell $php $dependencies:
./bin/test-matrix "$php" "$dependencies"
Loading