variables:
  TEST_PROJECT_DIR: 'tests/iac'

.gitlab-tofu-test-base:
  image: "$GITLAB_OPENTOFU_IMAGE_NAME"
  variables:
    TF_STATE_NAME: ci-unit-$CI_JOB_ID
  cache:
    key: "$OPENTOFU_VERSION-$CI_COMMIT_REF_SLUG"
    paths:
      - $TEST_PROJECT_DIR/.terraform/
  before_script:
    - gitlab-tofu version
    - jq --version
  after_script:
    - curl --request DELETE -u "gitlab-ci-token:$CI_JOB_TOKEN" "$CI_API_V4_URL/projects/$CI_PROJECT_ID/terraform/state/$TF_STATE_NAME"

.gitlab-tofu-test:
  extends:
    - .gitlab-tofu-test-base
  before_script:
    - !reference [.gitlab-tofu-test-base, before_script]
    - cd $TEST_PROJECT_DIR

.test-gitlab-tofu-root:
  extends:
    - .gitlab-tofu-test-base
  variables:
    TF_ROOT: $TEST_PROJECT_DIR

gitlab-tofu-init:
  extends:
    - .gitlab-tofu-test
    - .opentofu-versions
  stage: test
  script:
    - export DEBUG_OUTPUT=true
    - gitlab-tofu init

gitlab-tofu-init-with-args:
  extends:
    - .gitlab-tofu-test
    - .opentofu-versions
  stage: test
  script:
    - export DEBUG_OUTPUT=true
    - gitlab-tofu init -get=true -no-color

gitlab-tofu-init-with-flags:
  extends:
    - .gitlab-tofu-test
    - .opentofu-versions
  stage: test
  script:
    - export DEBUG_OUTPUT=true
    - export TF_INIT_FLAGS="-get=true -no-color"
    - gitlab-tofu init

gitlab-tofu-init-with-flags-and-args:
  extends:
    - .gitlab-tofu-test
    - .opentofu-versions
  stage: test
  script:
    - export DEBUG_OUTPUT=true
    - export TF_INIT_FLAGS="-get=true"
    - gitlab-tofu init -no-color

gitlab-tofu-init-tf-root:
  extends:
    - .test-gitlab-tofu-root
    - .opentofu-versions
  stage: test
  script:
    - export DEBUG_OUTPUT=true
    - gitlab-tofu init

gitlab-tofu-init-tf-root-with-cd:
  extends:
    - .test-gitlab-tofu-root
    - .opentofu-versions
  stage: test
  script:
    - cd $TEST_PROJECT_DIR
    - export DEBUG_OUTPUT=true
    - gitlab-tofu init

gitlab-tofu-init-tf-root-with-args:
  extends:
    - .test-gitlab-tofu-root
    - .opentofu-versions
  stage: test
  script:
    - export DEBUG_OUTPUT=true
    - gitlab-tofu init -get=true -no-color

gitlab-tofu-init-tf-root-with-flags:
  extends:
    - .test-gitlab-tofu-root
    - .opentofu-versions
  stage: test
  script:
    - export DEBUG_OUTPUT=true
    - export TF_INIT_FLAGS="-get=true -no-color"
    - gitlab-tofu init

gitlab-tofu-init-tf-root-with-flags-and-args:
  extends:
    - .test-gitlab-tofu-root
    - .opentofu-versions
  stage: test
  script:
    - export DEBUG_OUTPUT=true
    - export TF_INIT_FLAGS="-get=true"
    - gitlab-tofu init -no-color

gitlab-tofu-init-without-reconfigure:
  extends:
    - .test-gitlab-tofu-root
    - .opentofu-versions
  stage: test
  script:
    - gitlab-tofu init
    - |
      cat <<EOF > $TF_ROOT/backend_override.tf
      terraform {
        backend "local" {}
      }
      EOF
    - export TF_INIT_NO_RECONFIGURE=true
    - FAILED=false
    - gitlab-tofu init -no-color >/tmp/output.txt 2>&1 || FAILED=true
    - cat /tmp/output.txt
    - test $FAILED = true
    - 'cat /tmp/output.txt | grep "Error: Backend configuration changed"'

gitlab-tofu-init-with-reconfigure:
  extends:
    - .test-gitlab-tofu-root
    - .opentofu-versions
  stage: test
  script:
    - gitlab-tofu init
    - |
      cat <<EOF > $TF_ROOT/backend_override.tf
      terraform {
        backend "local" {}
      }
      EOF
    - gitlab-tofu init

gitlab-tofu-init-with-prepared-registry-token:
  extends:
    - .gitlab-tofu-test
  stage: test
  variables:
    OPENTOFU_VERSION: $LATEST_OPENTOFU_VERSION
  script:
    - apk add --update $PKG
    - |
      cat <<'EOF' > test.sh
      set -x
      export TF_TOKEN_gitlab_com=mysecrettoken
      . $(which gitlab-tofu)
      terraform_authenticate_private_registry
      test "$TF_TOKEN_gitlab_com" = "mysecrettoken"
      EOF
    - $SHELL test.sh
  parallel:
    matrix:
      - SHELL: "bash"
        PKG: "bash"
      - SHELL: "zsh"
        PKG: "zsh"
      - SHELL: "ksh"
        PKG: "loksh"

gitlab-tofu-init-without-prepared-registry-token:
  extends:
    - .gitlab-tofu-test
  stage: test
  variables:
    OPENTOFU_VERSION: $LATEST_OPENTOFU_VERSION
  script:
    - apk add --update $PKG
    - |
      cat <<'EOF' > test.sh
      set -x
      . $(which gitlab-tofu)
      terraform_authenticate_private_registry
      test -n "$TF_TOKEN_gitlab_com"
      EOF
    - $SHELL test.sh
  parallel:
    matrix:
      - SHELL: "bash"
        PKG: "bash"
      - SHELL: "zsh"
        PKG: "zsh"
      - SHELL: "ksh"
        PKG: "loksh"

gitlab-tofu-fmt:
  extends:
    - .gitlab-tofu-test
    - .opentofu-versions
  stage: test
  script:
    - gitlab-tofu fmt

gitlab-tofu-validate:
  extends:
    - .gitlab-tofu-test
    - .opentofu-versions
  stage: test
  script:
    - gitlab-tofu validate

gitlab-tofu-plan:
  extends:
    - .gitlab-tofu-test
    - .opentofu-versions
  stage: test
  variables:
    TF_PLAN_CACHE: $OPENTOFU_VERSION-plan.cache
  script:
    - gitlab-tofu plan
    - if [[ ! -f "$OPENTOFU_VERSION-plan.cache" ]]; then echo "expected to find a plan.cache file"; exit 1; fi
    - gitlab-tofu plan-json
    - if [[ ! -f "plan.json" ]]; then echo "expected to find a plan.json file"; exit 1; fi
  artifacts:
    paths:
      - "$TEST_PROJECT_DIR/*-plan.cache"

gitlab-tofu-apply:
  extends:
    - .gitlab-tofu-test
    - .opentofu-versions
  stage: test
  variables:
    TF_PLAN_CACHE: $OPENTOFU_VERSION-plan.cache
  before_script:
    - !reference [.gitlab-tofu-test, before_script]
    - gitlab-tofu plan
  script:
    - gitlab-tofu apply

gitlab-tofu-destroy:
  extends:
    - .gitlab-tofu-test
    - .opentofu-versions
  stage: test
  before_script:
    - !reference [.gitlab-tofu-test, before_script]
    - gitlab-tofu plan
    - gitlab-tofu apply
  script:
    - gitlab-tofu destroy

gitlab-tofu-source-script:
  extends:
    - .gitlab-tofu-test
  stage: test
  variables:
    OPENTOFU_VERSION: $LATEST_OPENTOFU_VERSION
  before_script:
    - !reference [.gitlab-tofu-test-base, before_script]
    - apk add --update $PKG
  script:
    - |
      cat <<'EOF' > test.sh
      set -x
      test -z "$TF_GITLAB_SOURCED"
      . $(which gitlab-tofu)
      test $TF_GITLAB_SOURCED
      EOF
    - |
      mkdir /usr/local/sbin
      cat <<'EOF' > /usr/local/sbin/terraform
      #/!usr/bin/env sh -e
      echo "Called Terraform, but shouldn't have!!"
      false
      EOF
      chmod +x /usr/local/sbin/terraform
    - $SHELL test.sh
  parallel:
    matrix:
      - SHELL: "bash"
        PKG: "bash"
      - SHELL: "zsh"
        PKG: "zsh"
      - SHELL: "ksh"
        PKG: "loksh"

gitlab-tofu-without-implicit-init:
  extends:
    - .gitlab-tofu-test
  stage: test
  cache:
  variables:
    OPENTOFU_VERSION: $LATEST_OPENTOFU_VERSION
    STATE_NAME: $CI_JOB_NAME
  script:
    - export TF_IMPLICIT_INIT=false
    - FAILED=false
    - gitlab-tofu $CMD -no-color >/tmp/output.txt 2>&1 || FAILED=true
    - cat /tmp/output.txt
    - test $FAILED = true
    - 'cat /tmp/output.txt | grep "$ERROR"'
  parallel:
    matrix:
      - CMD: apply
        ERROR: 'Error: Failed to load "plan.cache" as a plan'
      - CMD: destroy
        ERROR: 'Error: Backend initialization required, please run "tofu init"'
      - CMD: plan
        ERROR: 'Error: Backend initialization required, please run "tofu init"'
      - CMD: validate
        ERROR: 'This module is not yet installed. Run "tofu init" to install all modules'

gitlab-tofu-no-wrapper:
  extends:
    - .gitlab-tofu-test
  stage: test
  cache:
  variables:
    OPENTOFU_VERSION: $LATEST_OPENTOFU_VERSION
    STATE_NAME: $CI_JOB_NAME
  script:
    # NOTE: running `gitlab-tofu apply` wouldn't fail
    #       because of the implicit `terraform init`.
    - FAILED=false
    - gitlab-tofu -- apply -no-color >/tmp/output.txt 2>&1 || FAILED=true
    - cat /tmp/output.txt
    - test $FAILED = true
    - 'cat /tmp/output.txt | grep "Error: Backend initialization required, please run \"tofu init\""'
