diff --git a/.env.backstopjs b/.env.backstopjs new file mode 100644 index 0000000..e1a8115 --- /dev/null +++ b/.env.backstopjs @@ -0,0 +1,4 @@ +#ddev-generated + +BACKSTOPJS_TESTDIR="tests/backstop" +BACKSTOPJS_ALLOW_PERM_REPAIR="true" \ No newline at end of file diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1c52fb9 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,4 @@ +# Exclude files from releases/tarballs +tests/ export-ignore +.github/ export-ignore +.gitattributes export-ignore \ No newline at end of file diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a884ede..c7e448c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,22 +1,30 @@ name: tests on: pull_request: + paths-ignore: + - "**.md" push: branches: [ main, develop ] + paths-ignore: + - "**.md" schedule: - - cron: '25 08 * * *' + - cron: '25 08 * * *' workflow_dispatch: inputs: debug_enabled: - description: 'Debug with tmate set "debug_enabled"' + type: boolean + description: Debug with tmate required: false - default: "false" + default: false + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true -# Required permissions for keep-alive, used by ddev/github-action-add-on-test permissions: - actions: write + contents: read jobs: tests: @@ -28,10 +36,10 @@ jobs: runs-on: ubuntu-latest steps: - - uses: ddev/github-action-add-on-test@v2 - with: - ddev_version: ${{ matrix.ddev_version }} - token: ${{ secrets.GITHUB_TOKEN }} - debug_enabled: ${{ github.event.inputs.debug_enabled }} - addon_repository: ${{ env.GITHUB_REPOSITORY }} - addon_ref: ${{ env.GITHUB_REF }} + - uses: ddev/github-action-add-on-test@v2 + with: + ddev_version: ${{ matrix.ddev_version }} + token: ${{ secrets.GITHUB_TOKEN }} + debug_enabled: ${{ github.event.inputs.debug_enabled }} + addon_repository: ${{ env.GITHUB_REPOSITORY }} + addon_ref: ${{ env.GITHUB_REF }} \ No newline at end of file diff --git a/.shellcheckrc b/.shellcheckrc new file mode 100644 index 0000000..8226afb --- /dev/null +++ b/.shellcheckrc @@ -0,0 +1 @@ +external-sources=true diff --git a/README.md b/README.md index e5f2bc9..14fee51 100644 --- a/README.md +++ b/README.md @@ -81,12 +81,13 @@ open tests/backstop/backstop_data/_mytestproject_/html_report/index.html ## Changes to the original docker image -The backstopjs docker image is extended with some functions using a custom docker build, see [Dockerfile](backstopBuild/Dockerfile) -and uses a custom [entrypoint](backstopBuild/entrypoint.sh). +The backstopjs docker image is extended with some functions using a custom docker build, see [Dockerfile](backstopjs-build/Dockerfile) +and uses a custom [entrypoint](backstopjs-build/entrypoint.sh). In the Dockerfile the following is added/changed: - add the custom entrypoint.sh to the image +- add custom healthcheck.sh to the image for addressing possible permissions issues when changing the test directory - delete the default 'node' user with uid 1000 and add current ddev user - install the [minimist](https://www.npmjs.com/package/minimist) npm package globally. This is not needed by default but very handy to parse command line args for more complex custom backstopjs configs. @@ -96,6 +97,10 @@ The entrypoint is responsible for: - add /etc/hosts entries for all hosts configured in the ddev web container automatically - add sleep command to keep the container running +The healthcheck is responsible for: +- confirming file ownership for /src is set to the container user +- optionally, repairing ownership issues (enabled by default) + ## Advanced ### How to add additional hostnames? @@ -115,10 +120,11 @@ See: [ddev FAQ: Can different projects communicate with each other?](https://dde ### Change backstop tests directory -Per default the backstop directory containing backstop config etc. is expected in your project directory (besides the -.ddev folder) in the directory *tests/backstop*. +The test directory is now managed via custom [environment variables](https://docs.ddev.com/en/stable/users/extend/customization-extendibility/#environment-variables-for-containers-and-services) only visible to host and container that can be saved into your project and shared with other developers. -If you want to change that edit the file [docker-compose.backstop.yaml](docker-compose.backstop.yaml) and -change the line in volumes to the path you want to use, move the files to the new directory and restart ddev. +To change from the default *tests/backstop* path, you can update the `BACKSTOPJS_TESTDIR` variable by running: +```shell +ddev dotenv set .ddev/.env.backstopjs --backstopjs-testdir +``` -Make sure to remove the #ddev-generated line from the file to prevent ddev from making changes to it. +Before you start/restart ddev, you should confirm the new directory exists, or Docker will automatically create with the owner set to root. [`healthcheck.sh`](backstopjs-build/healthcheck.sh) will detect this on container start and attempt to update the owner/group to match the rest of ddev; however, it can only update the files/directories the container can see. If this behavior is problematic, you can set `BACKSTOPJS_ALLOW_PERM_REPAIR` to `false` and it will only notify you. diff --git a/backstopBuild/Dockerfile b/backstopjs-build/Dockerfile similarity index 91% rename from backstopBuild/Dockerfile rename to backstopjs-build/Dockerfile index 5b89cc3..1569e0e 100644 --- a/backstopBuild/Dockerfile +++ b/backstopjs-build/Dockerfile @@ -6,6 +6,10 @@ FROM $BASE_IMAGE COPY ./entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh +# Add healthcheck script +COPY ./healthcheck.sh /healthcheck.sh +RUN chmod +x /healthcheck.sh + # delete the default 'node' user with uid 1000 and add current ddev user ARG username ARG uid diff --git a/backstopBuild/entrypoint.sh b/backstopjs-build/entrypoint.sh similarity index 100% rename from backstopBuild/entrypoint.sh rename to backstopjs-build/entrypoint.sh diff --git a/backstopjs-build/healthcheck.sh b/backstopjs-build/healthcheck.sh new file mode 100644 index 0000000..ac0d39d --- /dev/null +++ b/backstopjs-build/healthcheck.sh @@ -0,0 +1,24 @@ +#!/bin/bash +#ddev-generated + +VOLUME_OWNER="$(stat -c '%U' /src)" +VOLUME_GROUP="$(stat -c '%G' /src)" +DDEV_USER="$(id -un)" +DDEV_GROUP="$(id -gn)" + +# Confirm /src owner and group matches container user. Attempt to fix, if BACKSTOPJS_ALLOW_PERM_REPAIR is true. +# This is to handle cases where BACKSTOPJS_TESTDIR is changed to a directory that does not exist and docker auto-creates it. +if ! [ "$VOLUME_OWNER" = "$DDEV_USER" ] || ! [ "$VOLUME_GROUP" = "$DDEV_GROUP" ]; then + if [ "${BACKSTOPJS_ALLOW_PERM_REPAIR:-"false"}" = "true" ]; then + if ! sudo chown -R "$DDEV_USER":"$DDEV_GROUP" /src &> /dev/null; then + printf "Automated repair failed. %s owner/group is %s/%s, should be %s/%s. On host, run 'sudo chown -R %s:%s %s'." "$BACKSTOPJS_TESTDIR" "$VOLUME_OWNER" "$VOLUME_GROUP" "$DDEV_USER" "$DDEV_GROUP" "$DDEV_USER" "$DDEV_GROUP" "$BACKSTOPJS_TESTDIR" + exit 1 + fi + else + printf "%s owner/group is %s/%s, should be %s/%s. On host, run 'sudo chown -R %s:%s %s'." "$BACKSTOPJS_TESTDIR" "$VOLUME_OWNER" "$VOLUME_GROUP" "$DDEV_USER" "$DDEV_GROUP" "$DDEV_USER" "$DDEV_GROUP" "$BACKSTOPJS_TESTDIR" + exit 1 + fi +fi + +printf "container healthy" +exit 0 \ No newline at end of file diff --git a/commands/backstop/backstop b/commands/backstopjs/backstop similarity index 83% rename from commands/backstop/backstop rename to commands/backstopjs/backstop index a6beb32..4c39de3 100755 --- a/commands/backstop/backstop +++ b/commands/backstopjs/backstop @@ -7,7 +7,7 @@ ## Example: "ddev backstop version" ## ExecRaw: true -if [ "$1" == "openReport" -o "$1" == "remote" ]; then +if [ "$1" == "openReport" ] || [ "$1" == "remote" ]; then echo "This does not work for backstop in ddev. See ddev backstop-results command." exit 1 fi diff --git a/commands/host/backstop-results b/commands/host/backstop-results index d12e96e..66a3588 100755 --- a/commands/host/backstop-results +++ b/commands/host/backstop-results @@ -6,14 +6,17 @@ ## Usage: backstop-results ## Example: "ddev backstop-results" +# shellcheck source=../../.env.backstopjs +source .ddev/.env.backstopjs + case $OSTYPE in linux-gnu) - xdg-open ${DDEV_APPROOT}/tests/backstop/backstop_data/html_report/index.html + xdg-open "${DDEV_APPROOT}/${BACKSTOPJS_TESTDIR}/backstop_data/html_report/index.html" ;; "darwin"*) - open ${DDEV_APPROOT}/tests/backstop/backstop_data/html_report/index.html + open "${DDEV_APPROOT}/${BACKSTOPJS_TESTDIR}/backstop_data/html_report/index.html" ;; "win*"* | "msys"*) - start ${DDEV_APPROOT}/tests/backstop/backstop_data/html_report/index.html + start "${DDEV_APPROOT}/${BACKSTOPJS_TESTDIR}/backstop_data/html_report/index.html" ;; esac diff --git a/docker-compose.backstop.yaml b/docker-compose.backstopjs.yaml similarity index 77% rename from docker-compose.backstop.yaml rename to docker-compose.backstopjs.yaml index 39dfafa..c5b6847 100644 --- a/docker-compose.backstop.yaml +++ b/docker-compose.backstopjs.yaml @@ -3,12 +3,12 @@ services: # This is the service name used when running ddev commands accepting the # --service flag. - backstop: + backstopjs: # This is the name of the container. It is recommended to follow the same # name convention used in the main docker-compose.yml file. - container_name: ddev-${DDEV_SITENAME}-backstop + container_name: ddev-${DDEV_SITENAME}-backstopjs build: - context: './backstopBuild' + context: './backstopjs-build' args: BASE_IMAGE: backstopjs/backstopjs:6.3.25 username: $USER @@ -19,9 +19,9 @@ services: # Add init to reap Chrome processes, as noted at # https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#running-puppeteer-in-docker init: true - entrypoint: [ /entrypoint.sh ] + entrypoint: [/entrypoint.sh] volumes: - - ../tests/backstop:/src + - ../${BACKSTOPJS_TESTDIR}:/src - .:/mnt/ddev_config:ro shm_size: 1gb environment: @@ -33,3 +33,8 @@ services: networks: ddev_default: null default: null + healthcheck: + test: ["CMD", "/healthcheck.sh"] + retries: 3 + start_period: 5s + start_interval: 1s diff --git a/install.yaml b/install.yaml index b5f67af..5b36f93 100644 --- a/install.yaml +++ b/install.yaml @@ -1,9 +1,11 @@ -name: ddev-backstopjs +name: backstopjs pre_install_actions: - - test -d ${DDEV_APPROOT}/tests/backstop || mkdir -p ${DDEV_APPROOT}/tests/backstop - - test -f "${DDEV_APPROOT}/tests/backstop/.gitignore" || printf "## ddev-generated\n**/bitmaps_test\n**/html_report\n" > ${DDEV_APPROOT}/tests/backstop/.gitignore - - grep -q "## ddev-generated" ${DDEV_APPROOT}/tests/backstop/.gitignore && printf "## ddev-generated\n**/bitmaps_test\n**/html_report\n" > ${DDEV_APPROOT}/tests/backstop/.gitignore || true + - test -d .ddev/backstopBuild && ddev add-on remove ddev-backstopjs || exit 0 + - test -f ${DDEV_APPROOT}/.ddev/.env.backstopjs || ddev dotenv set ${DDEV_APPROOT}/.ddev/.env.backstopjs --backstopjs-testdir tests/backstop --backstopjs-allow-perm-repair true + - test -d ${DDEV_APPROOT}/${BACKSTOPJS_TESTDIR} || mkdir -p ${DDEV_APPROOT}/${BACKSTOPJS_TESTDIR} + - test -f "${DDEV_APPROOT}/${BACKSTOPJS_TESTDIR}/.gitignore" || printf "## ddev-generated\n**/bitmaps_test\n**/html_report\n" > ${DDEV_APPROOT}/${BACKSTOPJS_TESTDIR}/.gitignore + - grep -q "## ddev-generated" ${DDEV_APPROOT}/${BACKSTOPJS_TESTDIR}/.gitignore && printf "## ddev-generated\n**/bitmaps_test\n**/html_report\n" > ${DDEV_APPROOT}/${BACKSTOPJS_TESTDIR}/.gitignore || true # list of files and directories listed that are copied into project .ddev directory @@ -11,9 +13,9 @@ pre_install_actions: # if it hasn't been modified by the user. # DDEV environment variables can be interpolated into these filenames project_files: -- docker-compose.backstop.yaml -- backstopBuild/ -- commands/backstop/backstop +- docker-compose.backstopjs.yaml +- backstopjs-build/ +- commands/backstopjs/ - commands/host/backstop-results post_install_actions: @@ -24,4 +26,4 @@ post_install_actions: # and prevent add-on from being installed if it doesn't validate. # See https://github.com/Masterminds/semver#checking-version-constraints for constraint rules. # Available with DDEV v1.23.4+, and works only for DDEV v1.23.4+ binaries -ddev_version_constraint: '>= v1.24.3' +ddev_version_constraint: '>= v1.24.5'