variables:
    DOCKER_DRIVER: overlay2
    # shopware 6
    WEB_DOCUMENT_ROOT: '$CI_PROJECT_DIR/public'
    MYSQL_ROOT_PASSWORD: root
    DEFAULT_PLATFORM_BRANCH: trunk
    LOG_STDOUT: $CI_PROJECT_DIR/stdout.log
    CYPRESS_PERCY_USAGE: $CYPRESS_PERCY_USAGE
    PERCY_BUILD_NAME: '000'
    CYPRESS_shopwareRoot: $CI_PROJECT_DIR
    CYPRESS_grepTags: '-quarantined'
    CYPRESS_localUsage: 'true'
    NODE_VERSION: '16'

stages:
    - build
    - analyze
    - test
    - prepare-release
    - release

include:
    -   local: .gitlab-ci/release_jobs.yml
    -   local: .gitlab-ci/test_base.yml
    -   local: .gitlab-ci/integration_jobs.yml

default:
    tags:
        - t3.medium

Build Test Package:
    interruptible: true
    stage: build
    tags:
        - m5.large
    only:
        refs:
            - schedules
            - merge_requests
    image: debian:bullseye-slim
    services:
      - name: docker:20.10-dind
        alias: dockerdaemon
    variables:
        GIT_STRATEGY: none
        SPLIT_REPOS: "Administration Storefront Core Elasticsearch Recovery"
        SPLITSH: /opt/splitsh-lite
        SHOPWARE_SKIP_BUNDLE_DUMP: 1
        SHOPWARE_SKIP_ASSET_COPY: 1
        SHOPWARE_SKIP_THEME_COMPILE: 1
        DOCKER_HOST: tcp://dockerdaemon:2375/
        DOCKER_TLS_CERTDIR: ""
    cache:
        key: "package_$CI_COMMIT_BRANCH"
        paths:
            - .platform
            - .composer
            - .apt
            - .npm
        policy: pull-push
    before_script:
        - apt-get update
        - DEB_PACKAGES="git jq curl docker.io build-essential nodejs php-cli php-ctype php-curl php-dom php-fileinfo php-gd php-iconv php-intl php-json php-mbstring php-pdo php-mysql php-simplexml php-xml php-zip"
        # setup caching
        - rm /etc/apt/apt.conf.d/docker-clean
        - cp -a /var/cache/apt .apt
        - echo "Dir::Cache::Archives ${PWD}/.apt;" >> /etc/apt/apt.conf.d/cache.conf
        - apt-get install -y --download-only curl && apt-get install -y curl
        - curl -sL https://deb.nodesource.com/setup_12.x | bash -
        - apt-get install -y --download-only $DEB_PACKAGES && apt-get install -y $DEB_PACKAGES
        - curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
        - npm config set cache $PWD/.npm
        # we need to do the checkout to have correct permissions. See: https://gitlab.com/gitlab-org/gitlab-runner/-/issues/1736
        - umask 0022
        - git config --global init.defaultBranch trunk
        - git init .
        - git remote add origin ${CI_REPOSITORY_URL}
        - git fetch origin $CI_COMMIT_BRANCH
        - git fetch --tags
        - git checkout -f -q ${CI_COMMIT_SHA}
        - git log -n 5
        - composer config --global  cache-dir $PWD/.composer
        # install helper tools
        - composer install --working-dir=.gitlab-ci/tools
        - '[[ -x $SPLITSH ]] || (curl -sL https://github.com/splitsh/lite/releases/download/v1.0.1/lite_linux_amd64.tar.gz | tar -xz ./splitsh-lite && mv splitsh-lite $SPLITSH)'
        - chmod +x $SPLITSH
        - HASH_CHECK_LINE="ec46c5a409422bf55b26f7de1faab67c2320362934947f984872b3aedc4a9d99  $SPLITSH"
        - echo $HASH_CHECK_LINE | sha256sum -c
    script:
        # clone platform if it's not cached. We use caching to speed up the split
        - export TAG=${TAG:-$(.gitlab-ci/tools/console release:show-next-tag)}
        - echo "$TAG"
        - SHOPWARE_VERSION="$(git describe --abbrev=0)"
        - SHOPWARE_VERSION="${SHOPWARE_VERSION#"v"}"
        - echo "$SHOPWARE_VERSION" > artifacts/SHOPWARE_VERSION
        - 'if [[ -z "$TAG" ]]; then echo "TAG is empty"; exit 1; fi'
        - '[[ -d .platform/ ]] || git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.shopware.com/shopware/6/product/platform.git -b ${DEFAULT_PLATFORM_BRANCH} --bare .platform'
        - git -C .platform remote set-url origin https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.shopware.com/shopware/6/product/platform.git
        # Find best matching branch. Example try: 6.3.2.1, 6.3.2, 6.3, master
        - export MATCHING_BRANCH=$(.gitlab-ci/tools/console release:show-platform-branch $TAG .platform)
        - if [[ -z $MATCHING_BRANCH ]]; then echo "No matching branch found"; exit 1; fi
        - echo "Checkout platform branch $MATCHING_BRANCH"
        # fetch newest changes from $MATCHING_BRANCH
        - git -C .platform fetch origin ${MATCHING_BRANCH}
        # set HEAD to newest commit in $$MATCHING_BRANCH
        - git -C .platform reset --soft FETCH_HEAD
        - git -C .platform fetch --tags origin
        - git -C .platform log -n 5
        # export e2e tests for usage in test jobs
        - git -C .platform archive --output $PWD/artifacts/tests.tar HEAD tests/
        - tar --append -f $PWD/artifacts/tests.tar .gitlab-ci/install_store_plugin.bash
        # split platform into separate repos/packages
        - >
            for pkg in $SPLIT_REPOS ; do
              .gitlab-ci/split_repo.sh .platform src/${pkg}
              git -C .platform/ rev-parse HEAD > repos/${pkg,,}/PLATFORM_COMMIT_SHA
            done
        # build test package
        - .gitlab-ci/build-nightly.sh
        - IMAGE_TAG=${TAG}-dev
        - docker build . -t "${CI_REGISTRY_IMAGE}:${IMAGE_TAG}"
        - mkdir artifacts || true
        - chmod 777 artifacts || true
        - .gitlab-ci/changed-files.sh > artifacts/additional_update_files
        - .gitlab-ci/changed-files.sh --deleted > artifacts/additional_deleted_files
        # TODO: get REFERENCE_INSTALLER_URL and REFERENCE_INSTALLER_SHA256 from shopware6.xml - use MINIMUM_VERSION
        # create package archive file
        - 'echo "Default env: $DEFAULT_ENV"'
        - docker run
            -v $PWD/artifacts:/artifacts
            -e DEFAULT_ENV -e REFERENCE_INSTALLER_URL -e REFERENCE_INSTALLER_SHA256
            --entrypoint=bin/package.sh ${CI_REGISTRY_IMAGE}:${IMAGE_TAG}
            /artifacts/additional_update_files
            /artifacts/additional_deleted_files
        - echo ${TAG} > artifacts/TAG
        - echo ${CI_JOB_ID} > artifacts/PACKAGE_JOB_ID
        - echo ${MATCHING_BRANCH} > artifacts/PLATFORM_BRANCH

    artifacts:
        expire_in: 1 week
        paths:
            - artifacts/
            - repos/

Static Analysis:
    stage: analyze
    image: shopware/development:7.4-composer-2
    only:
        refs:
            - merge_requests
    script:
        - apt update && apt install shellcheck
        # SC1090: source is not resolved
        # SC2039: busybox sh supports [[
        - shellcheck --exclude=SC1090 --exclude=SC2039 bin/*.sh .gitlab-ci/*.sh .gitlab-ci/tools/bin/*.sh .gitlab-ci/e2e/*.sh
        - composer install
        - composer install -d .gitlab-ci/tools
        - php .gitlab-ci/tools/vendor/bin/ecs check --config easy-coding-standard.php
        - php .gitlab-ci/tools/vendor/bin/phpstan analyse

Tools unit test:
    stage: test
    image: shopware/development:7.4-composer-2
    only:
        refs:
            - merge_requests
    script:
        - composer install -d .gitlab-ci/tools
        - php .gitlab-ci/tools/vendor/bin/phpunit --configuration .gitlab-ci/tools/phpunit.xml.dist --log-junit phpunit.junit.xml
    artifacts:
        when: always
        paths:
            - phpunit.junit.xml
        reports:
            junit: phpunit.junit.xml

# Unit tests

Unit PHP 7.4:
    extends: .unit_base
    image: shopware/development:7.4-composer-2
    only:
        refs:
            - schedules
            - merge_requests

# e2e install tests

Install (Visual, EN):
    extends: .e2e_install_base
    only:
        refs:
            - schedules
            - merge_requests
        variables:
            - $CYPRESS_PERCY_USAGE == "true"
    variables:
        GIT_STRATEGY: none
        APP_ENV: e2e
    script:
        - cp artifacts/install*.tar.xz install.tar.xz
        - tar -xf install.tar.xz
        - rm install.tar.xz
        - >
            if [[ -n "$CI_MERGE_REQUEST_ID" ]]; then

            mkdir -p config/packages/ || true

            cat > config/packages/ci.yaml <<EOF

            parameters:
              kernel.shopware_version: '$SHOPWARE_VERSION'
            EOF

            fi
        - SERVICE_PHPFPM_OPTS=--allow-to-run-as-root CONTAINER_UID=root /entrypoint supervisord > artifacts/supervisord.log 2>&1 &
        - apt-get update && apt-get install -y xvfb
        - tar -xf artifacts/tests.tar
        - cd tests/e2e
        - npm clean-install
        - echo $PERCY_BUILD_NAME
        - timeout 20m npx percy exec -- cypress run
            --browser chrome --config baseUrl=http://localhost:8000,numTestsKeptInMemory=0 --headless
            --env expectedVersion=$TAG,usePercy=$CYPRESS_PERCY_USAGE,SKIP_INIT=true
            --spec cypress/e2e/installer/basic.cy.js
        - $CI_PROJECT_DIR/bin/console e2e:dump-db
        - timeout 20m npx percy exec -- cypress run
            --browser chrome --config baseUrl=http://localhost:8000,numTestsKeptInMemory=0 --headless
            --env expectedVersion=$TAG,usePercy=$CYPRESS_PERCY_USAGE
            --spec "cypress/e2e/recovery/visual/*"

Install (EN):
    extends: .e2e_install_base
    only:
        refs:
            - schedules
            - merge_requests
        variables:
            - $CYPRESS_PERCY_USAGE != "true"
    variables:
        GIT_STRATEGY: none
        APP_ENV: e2e
    script:
        - cp artifacts/install*.tar.xz install.tar.xz
        - tar -xf install.tar.xz
        - rm install.tar.xz
        - export SHOPWARE_VERSION=$(cat artifacts/SHOPWARE_VERSION)
        - >
            if [[ -n "$CI_MERGE_REQUEST_ID" ]]; then

            mkdir -p config/packages/ || true

            cat > config/packages/ci.yaml <<EOF

            parameters:
              kernel.shopware_version: '$SHOPWARE_VERSION'
            EOF

            fi
        - SERVICE_PHPFPM_OPTS=--allow-to-run-as-root CONTAINER_UID=root /entrypoint supervisord > artifacts/supervisord.log 2>&1 &
        - apt-get update && apt-get install -y xvfb
        - tar -xf artifacts/tests.tar
        - cd tests/e2e
        - npm clean-install
        - timeout 20m $(npm bin)/cypress run
            --browser chrome --config baseUrl=http://localhost:8000,numTestsKeptInMemory=0,retries=0 --headless
            --env expectedVersion=$TAG,SKIP_INIT=true
            --spec cypress/e2e/installer/basic.cy.js
        - $CI_PROJECT_DIR/bin/console e2e:dump-db
        - timeout 5m $(npm bin)/cypress run
            --browser chrome --config baseUrl=http://localhost:8000,numTestsKeptInMemory=0 --headless
            --env expectedVersion=$TAG
            --spec "cypress/e2e/recovery/visual/*"

Install (NL):
    extends: .e2e_install_base
    variables:
        GIT_STRATEGY: none
        CYPRESS_SKIP_INIT: 'true'
        APP_ENV: e2e
    script:
        - cp artifacts/install*.tar.xz install.tar.xz
        - tar -xf install.tar.xz
        - rm install.tar.xz
        - export SHOPWARE_VERSION=$(cat artifacts/SHOPWARE_VERSION)
        - >
            if [[ -n "$CI_MERGE_REQUEST_ID" ]]; then

            mkdir -p config/packages/ || true

            cat > config/packages/ci.yaml <<EOF

            parameters:
              kernel.shopware_version: '$SHOPWARE_VERSION'
            EOF

            fi
        - SERVICE_PHPFPM_OPTS=--allow-to-run-as-root CONTAINER_UID=root /entrypoint supervisord > artifacts/supervisord.log 2>&1 &
        - apt-get update && apt-get install -y xvfb
        - tar -xf artifacts/tests.tar
        - cd tests/e2e
        - npm clean-install
        - $(npm bin)/cypress run
            --browser chrome --config baseUrl=http://localhost:8000,numTestsKeptInMemory=0,retries=0 --headless
            --env expectedVersion=$TAG,locale="nl-NL"
            --spec cypress/e2e/installer/install_nl.cy.js


Install (NL) with scenarios:
    extends: .e2e_install_base
    only:
        refs:
            - schedules
            - merge_requests
    allow_failure: true
    variables:
        GIT_STRATEGY: none
        APP_ENV: e2e
    script:
        - export TAG=$(cat artifacts/TAG)
        - export SHOPWARE_VERSION=$(cat artifacts/SHOPWARE_VERSION)
        - cp artifacts/install*.tar.xz install.tar.xz
        - tar -xf install.tar.xz
        - rm install.tar.xz
        - SERVICE_PHPFPM_OPTS=--allow-to-run-as-root CONTAINER_UID=root /entrypoint supervisord > artifacts/supervisord.log 2>&1 &
        - apt-get update && apt-get install -y xvfb jq
        - tar -xf artifacts/tests.tar
        - >
            if [[ -n "$CI_MERGE_REQUEST_ID" ]]; then

            mkdir -p config/packages/ || true

            cat > config/packages/ci.yaml <<EOF

            parameters:
              kernel.shopware_version: '$SHOPWARE_VERSION'
            EOF

            fi
        - cat config/packages/ci.yaml || true
        - cd tests/e2e
        - npm clean-install
        - $(npm bin)/cypress run
            --browser chrome --config baseUrl=http://localhost:8000,numTestsKeptInMemory=0,retries=0 --headless
            --env expectedVersion=$TAG,locale="nl-NL",SKIP_INIT=true
            --spec cypress/e2e/installer/install_nl.cy.js
        - cd $CI_PROJECT_DIR
        - .gitlab-ci/install_store_plugin.bash SwagLanguagePack SwagPayPal
        - $CI_PROJECT_DIR/bin/console e2e:dump-db
        - cd tests/e2e
        - $(npm bin)/cypress run
            --browser chrome --headless
            --spec "cypress/e2e/scenarios/**/*.cy.js"

# e2e update tests

Manual Update (EN):
    extends: .e2e_update_base
    variables:
        E2E_INSTALL_PACKAGE_URL: $REFERENCE_INSTALLER_URL
        E2E_TEST_DATA_FILE: "v6.1.6_test_data.tar.xz"
    script:
        - unzip -qqo artifacts/update.zip
        - chown -R application:application $CI_PROJECT_DIR
        - cd tests/e2e
        - timeout 20m $(npm bin)/cypress run
            --browser chrome --config baseUrl=http://localhost:8000,numTestsKeptInMemory=0 --headless
            --env expectedVersion=$TAG,SKIP_INIT=true
            --spec cypress/e2e/recovery/updater/manual-update.cy.js
        - APP_ENV=e2e $CI_PROJECT_DIR/bin/console e2e:dump-db
        - APP_ENV=e2e $(npm bin)/cypress run
            --browser chrome --config baseUrl=http://localhost:8000,numTestsKeptInMemory=0 --headless
            --env expectedVersion=$TAG,testDataUsage=true
            --spec cypress/e2e/recovery/updater/validation/storefront.cy.js
    after_script:
        - npx mochawesome-merge .gitlab-ci/e2e/test/artifacts/mochawesome/single-reports/mochawesome*.json > .gitlab-ci/e2e/test/artifacts/mochawesome/single-reports/report-final.json
        - npx mochawesome-report-generator .gitlab-ci/e2e/test/artifacts/mochawesome/single-reports/report-final.json --cdn true --reportDir .gitlab-ci/e2e/test/artifacts/mochawesome

.E2E Update:
    extends: .e2e_update_base
    artifacts:
        when: always
        expire_in: 1 week
        paths:
            - .gitlab-ci/e2e/test/artifacts/*
            - var/log/*
            - development/var/log/*
            - $CI_PROJECT_DIR/stdout.log
    after_script:
        - npx mochawesome-merge .gitlab-ci/e2e/test/artifacts/mochawesome/single-reports/mochawesome*.json > .gitlab-ci/e2e/test/artifacts/mochawesome/single-reports/report-final.json
        - npx mochawesome-report-generator .gitlab-ci/e2e/test/artifacts/mochawesome/single-reports/report-final.json --cdn true --reportDir .gitlab-ci/e2e/test/artifacts/mochawesome

Update (Visual, DE):
    extends: .E2E Update
    only:
        refs:
            - schedules
            - merge_requests
        variables:
            - $CYPRESS_PERCY_USAGE == "true"
    script:
        - cd tests/e2e
        - echo $PERCY_BUILD_NAME
        - chown "$(id -u):$(id -g)" . # Hack to prevent npm exec from dropping privileges. This behaviour has been removed already, but is used either by our version of `npm` or probably `percy exec`: https://github.com/npm/promise-spawn/commit/a8b21fc66b31e3d724f6b91c77d8bc4f6172ed13#diff-e727e4bdf3657fd1d798edcd6b099d6e092f8573cba266154583a746bba0f346
        - timeout 20m npx percy exec -- cypress run
            --browser chrome --config baseUrl=http://localhost:8000,numTestsKeptInMemory=0 --headless
            --env expectedVersion=$TAG,usePercy=$CYPRESS_PERCY_USAGE,testBase="Update",SKIP_INIT=true
            --spec cypress/e2e/recovery/updater/auto-update.cy.js
        - APP_ENV=e2e $CI_PROJECT_DIR/bin/console e2e:dump-db
        - APP_ENV=e2e npx percy exec -- cypress run
            --browser chrome --config baseUrl=http://localhost:8000,numTestsKeptInMemory=0 --headless
            --env expectedVersion=$TAG,testDataUsage=true,testBase="Update",locale="de-DE",usePercy=$CYPRESS_PERCY_USAGE
            --spec "cypress/e2e/recovery/visual/*"
    variables:
        E2E_INSTALL_PACKAGE_URL: $REFERENCE_INSTALLER_URL
        E2E_TEST_DATA_FILE: "v6.1.6_test_data.tar.xz"

Update (DE):
    extends: .E2E Update
    only:
        refs:
            - schedules
            - merge_requests
        variables:
            - $CYPRESS_PERCY_USAGE != "true"
    script:
        - cd tests/e2e
        - timeout 20m $(npm bin)/cypress run
            --browser chrome --config baseUrl=http://localhost:8000,numTestsKeptInMemory=0 --headless
            --env expectedVersion=$TAG,testBase="Update",SKIP_INIT=true
            --spec cypress/e2e/recovery/updater/auto-update.cy.js
        - APP_ENV=e2e $CI_PROJECT_DIR/bin/console e2e:dump-db
        - APP_ENV=e2e $(npm bin)/cypress run
            --browser chrome --config baseUrl=http://localhost:8000,numTestsKeptInMemory=0 --headless
            --env expectedVersion=$TAG,testDataUsage=true,testBase="Update",locale="de-DE"
            --spec "cypress/e2e/recovery/visual/*"
    variables:
        E2E_INSTALL_PACKAGE_URL: $REFERENCE_INSTALLER_URL
        E2E_TEST_DATA_FILE: "v6.1.6_test_data.tar.xz"


Update from latest:
    extends: .E2E Update
    tags:
        - m5.large
    only:
        refs:
            - schedules
            - merge_requests
        variables:
            - $E2E_INSTALL_PACKAGE_URL_LATEST
    script:
        - cd tests/e2e
        - timeout 20m $(npm bin)/cypress run
            --browser chrome --config baseUrl=http://localhost:8000,numTestsKeptInMemory=0 --headless
            --env expectedVersion=$TAG,testBase="Update",SKIP_INIT=true
            --spec cypress/e2e/recovery/updater/auto-update.cy.js
        - APP_ENV=e2e $CI_PROJECT_DIR/bin/console e2e:dump-db
        - APP_ENV=e2e $(npm bin)/cypress run
            --browser chrome --config baseUrl=http://localhost:8000,numTestsKeptInMemory=0 --headless
            --env expectedVersion=$TAG,testDataUsage=true,testBase="Update",locale="de-DE"
            --spec "cypress/e2e/recovery/visual/*"
        - cd $CI_PROJECT_DIR
        - php bin/console bundle:dump
    variables:
        E2E_INSTALL_PACKAGE_URL: $E2E_INSTALL_PACKAGE_URL_LATEST
        E2E_TEST_DATA_FILE: "v6.1.6_test_data.tar.xz"

Finalize Percy Build:
    extends: .e2e_install_base
    stage: prepare-release
    when: always
    only:
        refs:
            - schedules
        variables:
            - '$CYPRESS_PERCY_USAGE == "true" && $PERCY_TOKEN'
    script:
        # finalize all visual testing jobs
        - export PERCY_TOKEN=$PERCY_TOKEN
        - export PERCY_BUILD_NAME=$CI_PIPELINE_ID
        - export PERCY_PARALLEL_NONCE=$PERCY_BUILD_NAME
        - export PERCY_PARALLEL_TOTAL=-1
        - npm install --save-dev @percy/cli
        - npx percy build:finalize