Move Drupal templates into the PHP directory

This commit is contained in:
Oliver Davies 2024-02-10 11:42:36 +00:00
parent 30942b2d95
commit f602b6e1e6
17 changed files with 16 additions and 16 deletions

View file

@ -0,0 +1,4 @@
/README.md
{% if experimental.createGitHubActionsConfiguration %}
/.github/
{%-endif-%}

View file

@ -0,0 +1,20 @@
# {{ managedText|raw }}
export DOCKER_UID=1000
{% if dockerCompose %}
export COMPOSE_PROJECT_NAME={{ name }}
export COMPOSE_PROFILES=web,php,database
export DOCKER_WEB_VOLUME=.:{{ project_root }}
{% endif %}
{% if experimental.useNewDatabaseCredentials %}
export MYSQL_DATABASE=app
export MYSQL_PASSWORD=app
export MYSQL_USER=app
{% else %}
export MYSQL_DATABASE=drupal
export MYSQL_PASSWORD=drupal
export MYSQL_USER=drupal
{% endif %}

View file

@ -0,0 +1,25 @@
name: CI
on:
pull_request:
push:
workflow_dispatch:
env:
COMPOSE_DOCKER_CLI_BUILD: 1
DOCKER_BUILDKIT: 1
DOCKER_UID: 1001
jobs:
build_and_test:
name: Build and test
runs-on: ubuntu-latest
steps:
- name: Checkout the code
uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
- name: Build and test
run: |
./run ci:test

View file

@ -0,0 +1,63 @@
# {{ managedText|raw }}
{% if not experimental.createInclusiveGitIgnoreFile %}
.editorconfig
.env
.gitattributes
vendor/
{{ drupal.docroot }}/.csslintrc
{{ drupal.docroot }}/.eslintignore
{{ drupal.docroot }}/.eslintrc.json
{{ drupal.docroot }}/.ht.router.php
{{ drupal.docroot }}/.htaccess
{{ drupal.docroot }}/INSTALL.txt
{{ drupal.docroot }}/README.md
{{ drupal.docroot }}/autoload.php
{{ drupal.docroot }}/core/
{{ drupal.docroot }}/example.gitignore
{{ drupal.docroot }}/index.php
{{ drupal.docroot }}/modules/README.txt
{{ drupal.docroot }}/modules/contrib/
{{ drupal.docroot }}/profiles/README.txt
{{ drupal.docroot }}/robots.txt
{{ drupal.docroot }}/sites/*/files/
{{ drupal.docroot }}/sites/*/private/
{{ drupal.docroot }}/sites/*/services*.yml
{{ drupal.docroot }}/sites/*/settings*.php
{{ drupal.docroot }}/sites/README.txt
{{ drupal.docroot }}/sites/default/default.services.yml
{{ drupal.docroot }}/sites/default/default.settings.php
{{ drupal.docroot }}/sites/development.services.yml
{{ drupal.docroot }}/sites/example.settings.local.php
{{ drupal.docroot }}/sites/example.sites.php
{{ drupal.docroot }}/sites/simpletest/
{{ drupal.docroot }}/themes/README.txt
{{ drupal.docroot }}/themes/contrib/
{{ drupal.docroot }}/update.php
{{ drupal.docroot }}/web.config
{% if flake is not defined %}
# Docker.
.env
docker-compose.override.yaml
{% endif %}
{% if flake is defined %}
.dir-env/
{% endif %}
{% else %}
# Ignore everything.
*
# Include these things:
!/{{ drupal.docroot }}/*/custom/**
{% endif %}
{% for path in git.ignore|sort %}
{{ path }}
{% endfor %}
{% if experimental.createInclusiveGitIgnoreFile %}
# Even if they are in sub-directories.
!*/
{% endif %}

View file

@ -0,0 +1,2 @@
ignore:
- DL3059

View file

@ -0,0 +1,106 @@
# {{ managedText|raw }}
FROM php:{{ php.version }} AS base
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
RUN which composer && composer -V
ARG DOCKER_UID=1000
ENV DOCKER_UID="${DOCKER_UID}"
WORKDIR {{ project_root }}
RUN adduser --disabled-password --uid "${DOCKER_UID}" app \
&& chown app:app -R {{ project_root }}
USER app
ENV PATH="${PATH}:{{ project_root }}/bin:{{ project_root }}/vendor/bin"
COPY --chown=app:app composer.* ./
################################################################################
FROM base AS build
USER root
{% if 'apache' in php.version %}
RUN a2enmod rewrite
{% endif %}
{% if dockerfile.stages.build.packages %}
RUN apt-get update -yqq \
&& apt-get install -yqq --no-install-recommends \
{{ dockerfile.stages.build.packages | join(' ') }} \
&& rm -rf /var/lib/apt/lists/* /usr/share/doc /usr/share/man \
&& apt-get clean
{% endif %}
RUN docker-php-ext-configure gd --with-jpeg
{% if dockerfile.stages.build.extensions.install %}
RUN docker-php-ext-install {{ dockerfile.stages.build.extensions.install | join(' ') }}
{% endif %}
COPY --chown=app:app phpunit.xml* ./
{% if dockerfile.stages.build.extra_files %}
COPY --chown=app:app {{ dockerfile.stages.build.extra_files | join(" ") }} ./
{% endif %}
{% for directory in dockerfile.stages.build.extra_directories %}
COPY --chown=app:app {{ directory }} {{ directory }}
{% endfor %}
{% for command in dockerfile.stages.build.root_commands | default([]) %}
RUN {{ command | raw }}
{% endfor %}
USER app
{% for command in dockerfile.stages.build.commands %}
RUN {{ command }}
{% endfor %}
COPY --chown=app:app tools/docker/images/php/root /
ENTRYPOINT ["/usr/local/bin/docker-entrypoint-php"]
CMD ["php-fpm"]
{% if dockerfile.stages.test %}
################################################################################
FROM {{ dockerfile.stages.test.extends }} AS test
COPY --chown=app:app . .
RUN {% for command in dockerfile.stages.test.commands -%}
{% if not loop.first %} && {% endif %}
{{ command }}
{%- if not loop.last %} \{% endif %}
{% endfor %}
{% endif %}
{% if web.type == "caddy" %}
################################################################################
FROM caddy:2 as web
WORKDIR {{ project_root }}
COPY tools/docker/images/web/root /
{% endif %}
{% if web.type == "nginx" %}
################################################################################
FROM nginx:1 as web
EXPOSE 8080
WORKDIR {{ project_root }}
COPY tools/docker/images/web/root /
{% endif %}

View file

@ -0,0 +1,6 @@
# {{ managedText | raw }}
:80
root * {{ project_root }}/{{ drupal.docroot }}
file_server
php_fastcgi php:9000

View file

@ -0,0 +1,88 @@
# {{ managedText|raw }}
x-proxy: &default-proxy
networks:
- default
- web
labels:
- "traefik.docker.network=traefik_proxy"
- "traefik.http.routers.${COMPOSE_PROJECT_NAME}.rule=Host(
`${COMPOSE_PROJECT_NAME}.localhost`,
{% for host in web.extra_hosts | default([]) -%}
{{ '`' ~ host ~ '`,' }}
{%- endfor %}
)"
x-app: &default-app
volumes:
- "${DOCKER_WEB_VOLUME:-./{{ drupal.docroot }}:{{ project_root }}/{{ drupal.docroot }}}"
env_file:
- .env
restart: "${DOCKER_RESTART_POLICY:-unless-stopped}"
networks:
- default
deploy:
resources:
limits:
cpus: "${DOCKER_MYSQL_CPUS:-0}"
memory: "${DOCKER_MYSQL_MEMORY:-0}"
labels:
- "traefik.enabled=false"
tty: true
services:
{% if "web" in dockerCompose.services %}
web:
<<: [*default-proxy, *default-app]
build:
context: .
target: web
depends_on:
- php
profiles: [web]
{% endif %}
{% set anchors = [
"apache" in php.version ? "*default-proxy" : null,
"*default-app",
] -%}
php:
<<: [{{ anchors | filter(item => item is not null) | join(", ") }}]
build:
context: .
target: build
args:
- "DOCKER_UID=${DOCKER_UID:-1000}"
volumes:
- .:{{ project_root }}
{% if "database" in dockerCompose.services -%}
depends_on:
- database
{% endif -%}
profiles: [php]
database:
image: {{ database.type }}:{{ database.version }}
deploy:
resources:
limits:
cpus: "${DOCKER_MYSQL_CPUS:-0}"
memory: "${DOCKER_MYSQL_MEMORY:-0}"
volumes:
- db-data:/var/lib/mysql
{{ database.extra_databases is not empty ? '- ./tools/docker/images/database/root/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d' : '' }}
env_file:
- .env
labels:
- "traefik.enabled=false"
environment:
MYSQL_RANDOM_ROOT_PASSWORD: true
profiles: [database]
volumes:
db-data: {}
networks:
web:
external: true
name: traefik_proxy

View file

@ -0,0 +1,7 @@
#!/usr/bin/env bash
# {{ managedText|raw }}
[[ -f composer.json && ! -d vendor ]] && composer install
eval "$@"

View file

@ -0,0 +1,5 @@
{% for database in database.extra_databases %}
CREATE DATABASE {{ database }};
GRANT ALL PRIVILEGES ON {{ database }}.* TO drupal@'%' IDENTIFIED BY 'drupal';
{% endfor %}

View file

@ -0,0 +1,22 @@
# {{ managedText | raw }}
server {
server_name _;
root {{ project_root }}/{{ drupal.docroot }};
location / {
try_files $uri /index.php?$query_string;
}
location ~ \.php(/|$) {
fastcgi_split_path_info ^(.+?\.php)(|/.*)$;
try_files $fastcgi_script_name =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param QUERY_STRING $query_string;
fastcgi_intercept_errors on;
fastcgi_pass php:9000;
}
}

View file

@ -0,0 +1,4 @@
# {{ managedText }}
max_vars_input = 1000
memory_limit = {{ php.ini.memory_limit | default('128M') }}

View file

@ -0,0 +1,38 @@
<?xml version="1.0"?>
<!-- {{ managedText | raw }} -->
<ruleset name="{{ name }} coding standards">
<description>PHPCS configuration file for {{ name }}.</description>
{% for path in php.phpcs.paths|default('[]') %}
<file>{{ path }}</file>
{% endfor %}
<arg value="np"/>
{% for standard in php.phpcs.standards|default(['Drupal', 'DrupalPractice']) %}
{% if not standard is same as "Drupal" %}
<rule ref="{{ standard }}"/>
{% endif %}
{% endfor %}
<rule ref="Drupal">
<exclude name="Drupal.Commenting.ClassComment.Missing"/>
<exclude name="Drupal.Commenting.DataTypeNamespace.DataTypeNamespace"/>
<exclude name="Drupal.Commenting.Deprecated"/>
<exclude name="Drupal.Commenting.DocComment.ContentAfterOpen"/>
<exclude name="Drupal.Commenting.DocComment.MissingShort"/>
<exclude name="Drupal.Commenting.FunctionComment.IncorrectParamVarName"/>
<exclude name="Drupal.Commenting.FunctionComment.IncorrectTypeHint"/>
<exclude name="Drupal.Commenting.FunctionComment.InvalidReturn"/>
<exclude name="Drupal.Commenting.FunctionComment.Missing"/>
<exclude name="Drupal.Commenting.FunctionComment.MissingParamComment"/>
<exclude name="Drupal.Commenting.FunctionComment.MissingReturnComment"/>
<exclude name="Drupal.Commenting.FunctionComment.ParamTypeSpaces"/>
<exclude name="Drupal.Commenting.FunctionComment.TypeHintMissing"/>
<exclude name="Drupal.Commenting.InlineComment.DocBlock"/>
<exclude name="Drupal.Commenting.VariableComment.Missing"/>
<exclude name="Drupal.NamingConventions.ValidFunctionName.ScopeNotCamelCaps"/>
<exclude name="DrupalPractice.Objects.StrictSchemaDisabled.StrictConfigSchema"/>
</rule>
</ruleset>

View file

@ -0,0 +1,18 @@
# {{ managedText | raw }}
parameters:
level: {{ php.phpstan.level }}
{% if not experimental.runStaticAnalysisOnTests %}
excludePaths:
- *Test.php
- *TestBase.php
{% endif %}
paths:
{% for path in php.phpstan.paths -%}
- {{ path }}
{%- endfor %}
{% if php.phpstan.baseline %}
includes:
- phpstan-baseline.neon
{% endif %}

View file

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- {{ managedText | raw }} -->
<phpunit
beStrictAboutChangesToGlobalState="true"
beStrictAboutOutputDuringTests="false"
beStrictAboutTestsThatDoNotTestAnything="true"
bootstrap="{{ drupal.docroot }}/core/tests/bootstrap.php"
cacheResult="false"
colors="true"
failOnWarning="true"
printerClass="\Drupal\Tests\Listeners\HtmlOutputPrinter"
>
<php>
<env name="BROWSERTEST_OUTPUT_BASE_URL" value=""/>
<env name="BROWSERTEST_OUTPUT_DIRECTORY" value=""/>
<env name="MINK_DRIVER_ARGS" value=''/>
<env name="MINK_DRIVER_ARGS_WEBDRIVER" value=''/>
<env name="MINK_DRIVER_CLASS" value=''/>
<env name="SIMPLETEST_BASE_URL" value="http://web"/>
<env name="SIMPLETEST_DB" value="sqlite://localhost//dev/shm/test.sqlite"/>
<ini name="error_reporting" value="32767"/>
<ini name="memory_limit" value="-1"/>
</php>
<testsuites>
<testsuite name="functional">
<directory>./{{ drupal.docroot }}/modules/custom/**/tests/**/Functional</directory>
</testsuite>
<testsuite name="kernel">
<directory>./{{ drupal.docroot }}/modules/custom/**/tests/**/Kernel</directory>
</testsuite>
<testsuite name="unit">
<directory>./{{ drupal.docroot }}/modules/custom/**/tests/**/Unit</directory>
</testsuite>
</testsuites>
</phpunit>

152
templates/php/drupal/run.twig Executable file
View file

@ -0,0 +1,152 @@
#!/usr/bin/env bash
# {{ managedText | raw }}
set -o errexit
set -o pipefail
# If we're running in CI we need to disable TTY allocation for docker compose
# commands that enable it by default, such as exec and run.
TTY="${TTY:-}"
if [[ ! -t 1 ]]; then
TTY="-T"
fi
# Run automated tests as part of the Continuous Integration (CI) pipeline.
function ci:test {
lint:dockerfile
docker compose version
docker network create traefik_proxy
cp --no-clobber .env.example .env
docker compose build --progress plain
docker compose up --detach
docker compose logs
composer install --quiet --no-progress
{% if not php.phpcs is same as false %}
test --testdox
{% endif %}
{% if not php.phpcs is same as false and not php.phpstan is same as false %}
quality
{% endif %}
}
# Run a command within the php container.
function cmd {
docker compose exec php "${@}"
}
{% if not php.phpcs is same as false %}
function coding-standards {
cmd phpcs "${@}"
}
{% endif %}
function composer {
_exec php composer "${@}"
}
function drush {
_exec php drush "${@}"
}
function git-hooks:off {
git config --unset core.hooksPath
}
function git-hooks:on {
git config core.hooksPath .githooks
}
# Display a list of all available commands.
function help {
printf "%s <task> [args]\n\nTasks:\n" "${0}"
compgen -A function | grep -v "^_" | cat -n
printf "\nExtended help:\n Each task has comments for general usage\n"
}
# Install Drupal.
function install {
drush site:install -y "${@}"
}
function lint:dockerfile {
docker container run --rm -i \
hadolint/hadolint hadolint --ignore DL3008 --ignore DL3059 -t style "${@}" - < Dockerfile
}
{% if not php.phpcs is same as false and not php.phpstan is same as false %}
function quality {
{% if not php.phpcs is same as false %}
coding-standards
{% endif %}
{% if not php.phpstan is same as false %}
static-analysis
{% endif %}
}
{% endif %}
function start {
cp -v --no-clobber .env.example .env || true
docker compose up -d
}
{% if not php.phpstan is same as false %}
function static-analysis {
cmd phpstan --memory-limit=-1 --no-progress "${@}"
}
{% endif %}
function stop {
docker compose down
}
{% if not php.phpunit is same as false and not php.test_runner is same as false %}
function test {
_exec php {{ php.test_runner }} --colors=always "${@}"
}
{% endif %}
function test:commit {
{% if not php.phpunit is same as false %}
test --testdox --testsuite functional
test --testdox --testsuite kernel
test --testdox --testsuite unit
{% endif %}
quality
}
function _exec {
docker compose exec ${TTY} "${@}"
}
function _run {
local service="${1}"
local command="${2}"
docker compose run \
--entrypoint "${command}" \
--no-deps \
--rm \
${TTY} \
"${service}" "${@}"
}
# Include any local tasks.
[[ -e run.local ]] && source run.local
TIMEFORMAT=$'\nTask completed in %3lR'
time "${@:-help}"
# vim: ft=bash