image: golang:1.22

stages:
  - test
  - pre-release
  - release

run_tests:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH)'
  stage: test
  script:
    - go install gotest.tools/gotestsum@latest
    - gotestsum --format testname --junitfile report.xml
  artifacts:
    when: always
    reports:
      junit: report.xml

lint:
  image: golangci/golangci-lint:v1.56-alpine
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH)'
  stage: test
  script:
    - golangci-lint run --issues-exit-code 1 --print-issued-lines=false --new-from-rev $CI_MERGE_REQUEST_DIFF_BASE_SHA --out-format code-climate:gl-code-quality-report.json,line-number
  artifacts:
    reports:
      codequality: gl-code-quality-report.json
    paths:
      - gl-code-quality-report.json

# ----- prepare release -----

# Расчет тега и формирование Changelog
get_changelog:
  stage: pre-release
  image:
    name: orhunp/git-cliff:latest
    entrypoint: [ "" ]
  rules:
    - if: '$CI_PIPELINE_SOURCE == "pipeline" && $PREPARE_RELEASE == "true"' # Запуск при инициации из perxis
    - if: $CI_PIPELINE_SOURCE == "web"                                      # или при ручном запуске из GUI
      when: manual                    
  variables:
    GIT_STRATEGY: clone
    GIT_DEPTH: 0
  script:
    - echo "$(git-cliff --unreleased | sed '1,6d' | sed '$d')" > current_changelog.md # удалить "лишние" строки для Changelog
  artifacts:
    reports:
      dotenv: vars.env # Use artifacts:reports:dotenv to expose the variables to other jobs
    paths:
      - current_changelog.md

# Релиз и запись тега в артефакт для использования в perxis
prepare_release:
  stage: pre-release
  image: bitnami/git:latest
  variables:
    GIT_DEPTH: 0
    GIT_STRATEGY: clone
  rules:
    - if: '$CI_PIPELINE_SOURCE == "pipeline" && $PREPARE_RELEASE == "true"'
    - if: $CI_PIPELINE_SOURCE == "web"
  needs:
    - job: get_changelog
      artifacts: true
  script:
    - |
      CURRENT_VERSION=$(git describe --tags --abbrev=0)
      RELEASE_VERSION=$CURRENT_VERSION
      
      # Релиз выполняется только при наличии изменений
      if [ $(git rev-list $CURRENT_VERSION..HEAD --count) -gt 0 ]; then
        # Если релиз на мастере, то устанавливается версия равная версии в Perxis
        RELEASE_VERSION=$PERXIS_RELEASE_VERSION
        
        # Если релиз хотфиксовый, то увеличиваем патчевую версию
        if [ $HOTFIX_RELEASE == "true" ]; then
          RELEASE_VERSION=$(echo $CURRENT_VERSION | awk -F . '{print $1"."$2"."$3+1}')
        fi
      fi
      
      # Если новая версия совпадает со старой, значит изменений не было, и выпускать новый релиз не нужно
      NEEDS_RELEASE=false
      if [ "$RELEASE_VERSION" != "$CURRENT_VERSION" ]; then
        NEEDS_RELEASE=true
      fi
        
      echo "PERXIS_GO_CURRENT_VERSION=$CURRENT_VERSION" >> vars.env
      echo "PERXIS_GO_RELEASE_VERSION=$RELEASE_VERSION" >> vars.env
      echo "PERXIS_GO_NEEDS_RELEASE=$NEEDS_RELEASE" >> vars.env
      
      printf '### Release perxis-go
      PERXIS_RELEASE_VERSION: %s
      HOTFIX_RELEASE: %s
      CURRENT_VERSION: %s
      RELEASE_VERSION: %s
      NEEDS_RELEASE: %s' $PERXIS_RELEASE_VERSION $HOTFIX_RELEASE $CURRENT_VERSION $RELEASE_VERSION $NEEDS_RELEASE
  artifacts:
    when: always
    paths:
      - vars.env
      - current_changelog.md
    expire_in: 1 week

# ----- release -----

create_release_branch:
  stage: release
  image: bitnami/git:latest
  variables:
    GIT_DEPTH: 0
    GIT_STRATEGY: clone
  rules:
    - if: $CI_PIPELINE_SOURCE == "pipeline" && $PREPARE_RELEASE != "true"
    - if: $CI_PIPELINE_SOURCE == "web"
  script:
    - |
      if [ $NEEDS_RELEASE == "true" ] && [ $CI_COMMIT_BRANCH == "master" ]; then
        git config user.email "gitlab@ci-cd.pipeline"
        git config user.name "gitlab-ci"
        git remote remove gitlab_origin || true
        git remote add gitlab_origin https://release_gitlab_ci:$PERXIS_GO_REPO_ACCESS_TOKEN@git.perx.ru/perxis/perxis-go.git
        RELEASE_BRANCH=${VERSION::-2}
        git branch release/$RELEASE_BRANCH || true
        git push gitlab_origin release/$RELEASE_BRANCH
      fi

release:
  stage: release
  image: registry.gitlab.com/gitlab-org/release-cli:latest
  rules:
    - if: $CI_PIPELINE_SOURCE == "pipeline" && $PREPARE_RELEASE != "true"
    - if: $CI_PIPELINE_SOURCE == "web"
      when: manual
  needs:
    - create_release_branch
  script:
    - echo "Start release $VERSION"
    - |
      if  [ $NEEDS_RELEASE != "true" ]; then
        exit 203
      fi
  allow_failure:
    exit_codes:
      - 203
  release:
    name: 'Release $VERSION'
    description: '$VERSION'
    tag_name: '$VERSION'