variables:
  PYTHONUNBUFFERED: "1"
  ARTIFACT_DOWNLOAD_ATTEMPTS: 3
  GET_SOURCES_ATTEMPTS: 3

default:
  interruptible: true

workflow:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "schedule" || $CI_PIPELINE_SOURCE == "web"'
    # Cfr. Workflows/MergeRequest-Pipelines.gitlab-ci.yml template
    - if: $CI_MERGE_REQUEST_IID
    - if: $CI_COMMIT_TAG
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

stages:
  - containers
  - build
  - platform
  - test
  - certification-dummy
  - upload

include:
  - local: "/ci/templates.yml"

.rules-for-expensive-job: &expensive-job
  rules:
    - if: '$CI_PIPELINE_SOURCE == "schedule"'
    - if: '$CI_MERGE_REQUEST_EVENT_TYPE == "merge_train"'
    - if: $CI_COMMIT_TAG
    - when: manual
      allow_failure: true

image-build-builder/ubuntu/bionic:
  extends: .image-build

image-build-tests-runner:
  extends: .image-build

image-build-boardfarm-ci:
  extends: .image-build

image-build-cppcheck:
  extends: .image-build

image-build-scripts:
  extends: .image-build

platform:
  stage: platform
  needs:
    - build-in-docker
    - image-build-boardfarm-ci
  rules:
    - if: $CI_MERGE_REQUEST_LABELS =~ /.*test-upgrade-image.*/
    - !reference [.rules-for-expensive-job, rules]
  variables:
    STABILITY_TESTS: $STABILITY_TESTS
    ALTRAN_TESTS: $ALTRAN_TESTS
    TESTS_TO_RUN_ESSENSIUM: $TESTS_TO_RUN_ESSENSIUM
    DEVICE_UNDER_TEST_ESSENSIUM: $DEVICE_UNDER_TEST_ESSENSIUM
    TESTS_TO_RUN_ISR: $TESTS_TO_RUN_ISR
    DEVICE_UNDER_TEST_ISR: $DEVICE_UNDER_TEST_ISR
    TESTS_TO_RUN_R2_ESSENSIUM: $TESTS_TO_RUN_R2_ESSENSIUM
    DEVICE_UNDER_TEST_R2_ESSENSIUM: $DEVICE_UNDER_TEST_R2_ESSENSIUM
    TESTS_TO_RUN_R4_ESSENSIUM: $TESTS_TO_RUN_R4_ESSENSIUM
    DEVICE_UNDER_TEST_R4_ESSENSIUM: $DEVICE_UNDER_TEST_R4_ESSENSIUM
    PARENT_PIPELINE_ID: $CI_PIPELINE_ID
    CI_PARENT_PIPELINE_SOURCE: $CI_PIPELINE_SOURCE
    BUILD_CGR: $BUILD_CGR
  trigger:
    include: "ci/platform.yml"
    strategy: depend

dco:
  stage: build
  variables:
    CI_COMMIT_BRANCH: $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME
  needs: []
  image: christophebedard/dco-check:latest
  rules:
    - if: $CI_MERGE_REQUEST_ID
    - if: $CI_EXTERNAL_PULL_REQUEST_IID
  script:
    - export CI_MERGE_REQUEST_TARGET_BRANCH_SHA=$(git merge-base --fork-point origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME)
    # if --forkpoint failed, fallback to just using merge-base:
    - test -z "$CI_MERGE_REQUEST_TARGET_BRANCH_SHA" && export CI_MERGE_REQUEST_TARGET_BRANCH_SHA=$(git merge-base "origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" "origin/$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME")
    - dco-check --verbose

cppcheck:
  stage: build
  image: $CI_REGISTRY_IMAGE/prplmesh-cppcheck:$CI_PIPELINE_ID
  script:
    # cppcheck runs in its own image because every new release brings
    # useful improvements (the versions from regular distros get old
    # too quickly) and to be able to update builders without having to
    # solve newly reported cppcheck issues at the same time.
    - tools/docker/static-analysis/cppcheck.sh .
  artifacts:
    paths:
      - cppcheck_results.txt
    when: always
  tags:
    - docker
  needs: ["image-build-cppcheck"]

cppcheck-diff:
  stage: build
  image: $CI_REGISTRY_IMAGE/prplmesh-cppcheck:$CI_PIPELINE_ID
  script:
    - ci/cppcheck/cppcheck-new-issues.sh
  artifacts:
    paths:
      - cppcheck_results.txt
      - cppcheck_existing_issues.txt
    expire_in: 4 weeks
    when: always
  tags:
    - docker
  needs: ["image-build-cppcheck"]

flake8:
  stage: build
  image: pipelinecomponents/flake8:f087c4c
  script:
    - apk add --update --no-cache git
    - git ls-files -z -- '*.py' ':(exclude)tools/maptools.py' ':(exclude)framework/tlvf/tlvf.py' |
      xargs -0 -t flake8 --verbose
  needs: []

# This step both generates documentation from ODL files,
# but also verifies that the ODL files are parse-able.
# For this reason, it makes sense to run this on all MRs,
# so that no-one accidentally checks in an ODL file with syntax errors
nbapi-docgen:
  stage: build
  extends: .in-prplmesh-builder
  variables:
    VERSION: $CI_COMMIT_REF_NAME-$CI_COMMIT_TIMESTAMP
  script:
    - tools/nbapi-docgen/parse_api.sh
  artifacts:
    paths:
      - build/html
    when: always
  needs:
    - job: build-in-docker

# Updates gitlab pages with the NBAPI documentation:
# https://prpl-foundation.gitlab.io/prplmesh/prplMesh/
# Only run on the master branch, to avoid unnecessary pushes.
pages:
  stage: upload
  needs: ["nbapi-docgen"]
  script:
    - mv build/html public
  artifacts:
    paths:
      - public
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

shellcheck:
  stage: build
  image: koalaman/shellcheck-alpine:v0.7.1
  before_script:
    - apk add --update --no-cache git
  script:
    - git ls-files -z '*.sh' '*.sh.in'  | xargs -0 shellcheck -x -P tools
  needs: []

clang-format:
  extends: .in-prplmesh-builder
  stage: build
  script:
    # Run clang-format and check there are no modified files
    - ./clang-format.sh
    # `diff-index` doesn't update the index so doesn't actually see changes. Need to manually update index.
    - git update-index -q --refresh
    # Use `diff-index` instead of `status` or `diff` because it gives more predictable output and exit code.
    - |
      git diff-index --exit-code HEAD || {
        ret=$?
        echo "Inconsistent formatting, please apply patch from artifacts"
        git diff > correct-formatting.patch
        exit $ret
      }
  artifacts:
    paths:
      - correct-formatting.patch
    when: on_failure

.build-in-docker:
  extends: .in-prplmesh-builder
  stage: build
  variables:
    CMAKE_BUILD_TYPE: "Release"
    EXTRA_CMAKE_FLAGS: ""
  script:
    # To be sure that AutoGenerated is correct, remove it first and check later that it's unchanged.
    - rm -rf framework/tlvf/AutoGenerated common/beerocks/tlvf/AutoGenerated
    - cmake -DBUILD_TESTS=ON $EXTRA_CMAKE_FLAGS -DCMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE \
      -DCMAKE_INSTALL_PREFIX=build/install -H. -Bbuild -G Ninja
    - ninja -C build install
    # Check that the AutoGenerated files are correct by checking git status
    - git update-index -q --refresh
    - git diff-index --exit-code HEAD
  artifacts:
    paths:
      - build/install
      - build/controller
      - build/agent/src/beerocks/slave/nbapi/agent/odl

pytest:
  extends: .build-in-docker
  script:
    - cd tools
    - pytest-3

build-in-docker:
  extends: .build-in-docker
  variables:
    EXTRA_CMAKE_FLAGS: ""

build-in-docker-legacy:
  extends: .build-in-docker
  variables:
    EXTRA_CMAKE_FLAGS: "-DENABLE_VBSS=ON -DUSE_PRPLMESH_WHM=OFF"

build-in-docker-static:
  extends: build-in-docker
  variables:
    EXTRA_CMAKE_FLAGS: "-DBUILD_SHARED_LIBS=OFF"
  rules:
    - !reference [.rules-for-expensive-job, rules]

tlvf_test:
  extends: .run-test-in-docker

bwl_whm_unit_tests:
  extends: .run-test-in-docker

bcl_unit_tests:
  extends: .run-test-in-docker

mapf_common_encryption_tests:
  extends: .run-test-in-docker

ieee1905_transport_broker_tests:
  extends: .run-test-in-docker

beerocks_agent_unit_tests:
  extends: .run-test-in-docker

nbapi_unit_tests:
  extends: .run-test-in-docker

db_unit_tests:
  extends: .run-test-in-docker

test-gw-repeater:
  stage: test
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - tests/test_gw_repeater.sh --rm --unique-id $CI_JOB_ID --tag $CI_PIPELINE_ID
  artifacts:
    paths:
      - logs
    when: always
  needs:
    - job: build-in-docker-legacy
  tags:
    - docker-test
  retry: 2

boardfarm-tests:
  stage: test
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - ./dctest.py
  artifacts:
    paths:
      - logs
    when: always
  needs:
    - job: build-in-docker-legacy
    - job: image-build-boardfarm-ci
  tags:
    - boardfarm-compose
  timeout: 30m
  retry: 2

boardfarm-stability-tests:
  extends: boardfarm-tests
  parallel: 10
  rules:
    - if: "$STABILITY_TESTS"
  retry: 0

run-certification-tests-R1-prplmesh-essensium:
  extends: .run-certification-tests-R1
  before_script:
    - !reference [.run-certification-tests-R1, before_script]
    - echo "$TESTS_TO_RUN_ESSENSIUM" > .tests-to-run
    - echo "$DEVICE_UNDER_TEST_ESSENSIUM" > .device-under-test
  tags:
    - certs-tests-essensium
  needs:
    - job: build-in-docker
  rules:
    - if: '$TESTS_TO_RUN_ESSENSIUM !~ /^\$/ && $DEVICE_UNDER_TEST_ESSENSIUM == "prplmesh"'
