stages:
  - check
  - test
  - build
  - deploy
  - release
.release_rules: &release_rules
  # rule to run job on a tag-reference which has the form number.number.number (semantic versioning)
  # or number.number.number-text (semantic versioning + release-name)
  # and where a Dockerfile exists
  - if: $CI_COMMIT_TAG =~ /^\d+[.]\d+[.]\d+$/ || $CI_COMMIT_TAG =~ /^\d+[.]\d+[.]\d+[-]\S+$/
    exists:
      - Dockerfile
build-openapi-scheme:
  stage: build
  image: python:3.11-slim
  variables:
    OPENAPI_JSON: ./public/api.json
  before_script:
    # we do this, because YAML anchors are not supported when executing locally
    - apt-get update
    - apt-get install -y gcc libldap2-dev libsasl2-dev libmagic-dev
    - python3 -m pip install --upgrade pip
    - python3 -m pip install poetry
    - poetry install --without dev,test --no-root
  script:
    - mkdir public
    - mkdir logs
    - poetry run python manage.py spectacular --validate --lang en --format openapi-json --file $OPENAPI_JSON
  artifacts:
    paths:
      - $OPENAPI_JSON
check-style:
  stage: check
  image: python:3.11-slim
  before_script:
    # we do this, because YAML anchors are not supported when executing locally
    - python3 -m pip install --upgrade pip
    - python3 -m pip install poetry
    - poetry install --no-root --only=dev
  script:
    - poetry run flake8 program steering
    - poetry run isort --check program steering
    - poetry run black --check --quiet program steering
run_test_cases:
  stage: test
  image: python:3.11-slim
  before_script:
    # we do this, because YAML anchors are not supported when executing locally
    - apt-get -qq update
    - apt-get install -y gcc libldap2-dev libsasl2-dev libmagic-dev
    - python3 -m pip install --upgrade pip
    - python3 -m pip install poetry
    - poetry install --no-interaction
  script:
    - mkdir logs
    - poetry run pytest --cov --cov-report term --cov-report xml:coverage.xml
  coverage: '/(?i)total.*? (100(?:\.0+)?\%|[1-9]?\d(?:\.\d+)?\%)$/'
  artifacts:
    reports:
      coverage_report:
        coverage_format: cobertura
        path: coverage.xml
deploy_spec:
  stage: deploy
  image: node:20-alpine
  needs:
    - build-openapi-scheme
  before_script:
    - apk update
    - apk add nodejs npm lftp
    - node -v
    - npm i -g npm@latest
    - npm install swagger-ui-dist@3.52.5
  script:
    - cp -rp node_modules/swagger-ui-dist/* ./public
    - 'sed -i "s@.*url.*@url: \"api.json\",@" ./public/index.html'
    - echo "Deploying AURA Steering API Spec..."
    - lftp -c "set ftp:ssl-allow no; open -u $FTP_AURA_RADIO_USER,$FTP_AURA_RADIO_PWD $FTP_AURA_RADIO_HOST; mirror -Rnev ./public/ ./api.aura.radio/steering --ignore-time --parallel=10 --exclude-glob .git* --exclude .git/"
    - echo "AURA Steering API Spec successfully deployed."
  artifacts:
    paths:
      - public
    expire_in: 2 days
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
      when: always
docker-push:
  # Use the official docker image.
  image: docker:latest
  stage: release
  variables:
    # the name of the image without version
    AURA_IMAGE_NAME: "autoradio/steering"
  services:
    - docker:dind
  before_script:
    # on a feature branch will login to gitlab registry
    # else to docker hub
    # hint: feature branches must begin with "feat"
    - |
      if expr "$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME" : ^feat > /dev/null
        then docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
      else docker login -u "$DOCKER_ID" -p "$DOCKER_HUB_AUTH"
      fi
  script:
    # every commit on main branch should build and push image as main
    # elseif it is a feature branch build and push to gitlab registry
    # else it is from a tag (enforced by gitlab-ci rules)
    # hint: tags are references independent of branches
    # hint: feature branches must begin with "feat"
    - |
      if [ "$CI_COMMIT_BRANCH" == "$CI_DEFAULT_BRANCH" ]
        then docker build -t $AURA_IMAGE_NAME:main .
        docker push $AURA_IMAGE_NAME:main
      elif expr "$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME" : ^feat > /dev/null
        then docker build -t $AURA_IMAGE_NAME -t $CI_REGISTRY_IMAGE:$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME .
        docker push $CI_REGISTRY_IMAGE:$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME
      else docker build -t $AURA_IMAGE_NAME -t $AURA_IMAGE_NAME:$CI_COMMIT_TAG .
      docker push $AURA_IMAGE_NAME:$CI_COMMIT_TAG
      fi
  rules:
    - *release_rules
    # every commit on master/main or feature branch should trigger a push
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^feat/
      exists:
        - Dockerfile
trigger_aura_tests:
  stage: release
  needs: [docker-push]
  trigger:
    project: aura/aura-tests
    branch: main
    strategy: depend
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
release_job:
  stage: release
  needs:
    - docker-push
  image: registry.gitlab.com/gitlab-org/release-cli:latest
  rules: *release_rules
  script:
    - echo "this will be a release when there is a tag, but tags should be protected to be only createable by maintainers."
  release:
    # TODO: automated release notes
    name: 'Release $CI_COMMIT_TAG'
    description: ./CHANGELOG.md
    tag_name: '$CI_COMMIT_TAG'
    ref: '$CI_COMMIT_TAG'