# job templates

.mobile_publish:
  image: 'europe-north1-docker.pkg.dev/holi-shared/docker/holi-docker/node-expo-eas'
  variables:
    ENVIRONMENT_FILE: '' # must be overridden by jobs extending .mobile_publish
    EXPO_PUBLISH_RELEASE_CHANNEL: $CI_COMMIT_REF_SLUG
    USE_PRODUCTION_RELEASE_CHANNEL_FROM_EAS_JSON: 'false'
    NODE_OPTIONS: '--max_old_space_size=4096' # helps against OOM errors
  cache: !reference [.yarn-cache-readonly]
  dependencies: [] # explicitly disable artifact usage
  script:
    - corepack enable
    - yarn install --immutable --immutable-cache
    - 'echo "Loading environment from \"${ENVIRONMENT_FILE}\""'
    - '. ${ENVIRONMENT_FILE}'
    - 'cd apps/mobile'
    - >
      if [ "$USE_PRODUCTION_RELEASE_CHANNEL_FROM_EAS_JSON" == "true" ]; then
        export EXPO_PUBLISH_RELEASE_CHANNEL=$(jq -r .build.production.channel eas.json)
        echo "Using production channel: $EXPO_PUBLISH_RELEASE_CHANNEL"
      fi
    - 'eas update --channel=${EXPO_PUBLISH_RELEASE_CHANNEL} --auto'
  interruptible: true
  tags:
    - 4cpu-16gb

.mobile_build:
  image: 'europe-north1-docker.pkg.dev/holi-shared/docker/holi-docker/node-expo-eas'
  variables:
    ENVIRONMENT_FILE: '' # must be overridden by jobs extending .mobile_build
    BUILD_PROFILE: preview
    BUILD_PLATFORM: changeme
    KEEP_ARTIFACTS: 'false'
    CHECK_VERSION_RELEASED: 'false'
    CI_ARTIFACTS_ENVIRONMENT_NAME: $CI_COMMIT_REF_SLUG
  cache: !reference [.yarn-cache-readonly]
  dependencies: [] # explicitly disable artifact usage
  script:
    - terraform/environments/scripts/build-mobile.sh ./"$ENVIRONMENT_FILE" "$BUILD_PROFILE" "$BUILD_PLATFORM" "$CHECK_VERSION_RELEASED" "$CI_COMMIT_SHA" "$CI_ARTIFACTS_ENVIRONMENT_NAME" "$KEEP_ARTIFACTS"
  interruptible: true

.mobile_e2e:
  image: 'europe-north1-docker.pkg.dev/holi-shared/docker/holi-docker/node-expo-eas'
  cache: !reference [.yarn-cache-readonly]
  dependencies: [] # explicitly disable artifact usage
  variables:
    BUILD_PLATFORM: changeme
    TEST_SUITES: changeme
    ENVIRONMENT_FILE: .env.staging
  script:
    - 'echo "Loading environment from \"${ENVIRONMENT_FILE}\""'
    - '. ${ENVIRONMENT_FILE}'
    - 'cd apps/mobile'
    - corepack enable
    - yarn install --immutable --immutable-cache
    - 'export EAS_APK_URL=$(eas build:list --gitCommitHash ${CI_COMMIT_SHA} --json --non-interactive --platform $BUILD_PLATFORM --limit=1 | jq -r ".[0].artifacts.buildUrl")' # extracts build URL from EAS
    - 'export EAS_APK_FILE=$(basename $EAS_APK_URL)'
    - 'curl -L -s -o ../../e2e/mobile/$EAS_APK_FILE $EAS_APK_URL' # download .apk from EAS
    - 'cd ../../e2e/mobile'
    - 'export BROWSERSTACK_UPLOAD_RESPONSE=$(curl -s -u "${BROWSERSTACK_USERNAME}:${BROWSERSTACK_ACCESS_KEY}" -X POST "https://api-cloud.browserstack.com/app-automate/upload" -F "file=@${EAS_APK_FILE}" -F "ios_keychain_support=true")'
    - 'export BROWSERSTACK_APP_URL=$(echo "${BROWSERSTACK_UPLOAD_RESPONSE}" | jq -r ".app_url")'
    - 'APPIUM_PLATFORM=$BUILD_PLATFORM yarn run jest --testPathPattern=/$TEST_SUITES/ --runInBand'
  interruptible: true
  timeout: 2 hours
  tags:
    - 4cpu-4gb

.mobile_e2e_android:
  extends: .mobile_e2e
  variables:
    BUILD_PLATFORM: android

.mobile_e2e_ios:
  extends: .mobile_e2e
  variables:
    BUILD_PLATFORM: ios

# end job templates

# pipeline in chronological order

## only for review environments

.rules_mobile_review:
  - !reference [.rule_templates, any_but_production_staging]
  - !reference [.rule_templates, skip_environment_for_mobile]

mobile_review_publish:
  extends: .mobile_publish
  needs: ['lint_compile_test']
  environment:
    name: mob-review/$CI_COMMIT_REF_SLUG
    url: https://expo.dev/accounts/holistic-foundation/projects/projectholi/channels/$CI_COMMIT_REF_SLUG
    on_stop: mobile_review_destroy
    auto_stop_in: 2 weeks
  variables:
    ENVIRONMENT_FILE: .env.staging
  allow_failure: false
  rules:
    - !reference [.rules_mobile_review]
    - !reference [.rule_templates, automatically_on_any_other]

mobile_review_destroy:
  needs: ['mobile_review_publish']
  variables:
    # has to be set to none for auto stop
    GIT_STRATEGY: none
  environment:
    name: mob-review/$CI_COMMIT_REF_SLUG
    action: stop
  dependencies: [] # explicitly disable artifact usage
  script:
    - echo "Nothing to do, you can't unpublish an expo release. This is only for cleaning up the gitlab environments"
  allow_failure: true # optional build step, won't block the pipeline
  interruptible: false
  rules:
    - !reference [.rule_templates, any_but_production_staging]
    - !reference [.rule_templates, skip_environment_for_mobile]
    - if: $CI_COMMIT_BRANCH
      when: manual

mobile_review_build_android:
  extends: .mobile_build
  needs: ['lint_compile_test']
  variables:
    BUILD_PLATFORM: android
    ENVIRONMENT_FILE: .env.staging
  allow_failure: true # optional build step, won't block the pipeline
  rules:
    - !reference [.rules_mobile_review]
    - !reference [.rule_templates, manually_on_any_other]

mobile_review_build_ios:
  extends: .mobile_build
  needs: ['lint_compile_test']
  allow_failure: true # optional build step, won't block the pipeline to succeed
  variables:
    BUILD_PLATFORM: ios
    ENVIRONMENT_FILE: .env.staging
  rules:
    - !reference [.rules_mobile_review]
    - !reference [.rule_templates, manually_on_any_other]

mobile_review_e2e_android:
  extends: .mobile_e2e_android
  needs: ['mobile_review_build_android'] # e2e only runs if build succeeded
  allow_failure: true # optional build step, won't block the pipeline to succeed
  variables:
    TEST_SUITES: (smoke|journey)
  rules:
    - !reference [.rules_mobile_review]
    - !reference [.rule_templates, automatically_on_any_other]

mobile_review_e2e_ios:
  extends: .mobile_e2e_ios
  needs: ['mobile_review_build_ios'] # e2e only runs if build succeeded
  allow_failure: true # optional build step, won't block the pipeline to succeed
  variables:
    TEST_SUITES: (smoke|journey)
  rules:
    - !reference [.rules_mobile_review]
    - !reference [.rule_templates, automatically_on_any_other]

## staging environment

mobile_staging_publish:
  extends: .mobile_publish
  needs: ['lint_compile_test']
  environment:
    name: mob-staging
    deployment_tier: staging
    url: https://expo.dev/accounts/holistic-foundation/projects/projectholi/channels/staging
  variables:
    ENVIRONMENT_FILE: .env.staging
    EXPO_PUBLISH_RELEASE_CHANNEL: staging
  rules:
    - !reference [.rule_templates, automatically_on_staging]

mobile_staging_build_android:
  extends: .mobile_build
  needs: ['lint_compile_test']
  allow_failure: true # optional build step, won't block the pipeline to succeed
  variables:
    ENVIRONMENT_FILE: .env.staging
    KEEP_ARTIFACTS: 'true'
    BUILD_PLATFORM: 'android'
    CI_ARTIFACTS_ENVIRONMENT_NAME: staging
  artifacts:
    paths:
      - apps/mobile/artifacts_staging/
    expire_in: 1 week
  rules:
    - !reference [.rule_templates, automatically_on_scheduled_e2e_test_run]
    - !reference [.rule_templates, manually_on_staging]

mobile_staging_build_ios:
  extends: .mobile_build
  needs: ['lint_compile_test']
  allow_failure: true # optional build step, won't block the pipeline to succeed
  variables:
    ENVIRONMENT_FILE: .env.staging
    KEEP_ARTIFACTS: 'true'
    BUILD_PLATFORM: 'ios'
    CI_ARTIFACTS_ENVIRONMENT_NAME: staging
  artifacts:
    paths:
      - apps/mobile/artifacts_staging/
    expire_in: 1 week
  rules:
    - !reference [.rule_templates, automatically_on_scheduled_e2e_test_run]
    - !reference [.rule_templates, manually_on_staging]

mobile_staging_e2e_android:
  extends: .mobile_e2e_android
  needs: ['mobile_staging_build_android'] # e2e only runs if build succeeded
  allow_failure: true # optional build step, won't block the pipeline to succeed
  variables:
    TEST_SUITES: (smoke|journey)
  rules:
    - !reference [.rule_templates, automatically_on_scheduled_e2e_test_run]
    - !reference [.rule_templates, manually_on_staging]

mobile_staging_e2e_ios:
  extends: .mobile_e2e_ios
  needs: ['mobile_staging_build_ios'] # e2e only runs if build succeeded
  allow_failure: true # optional build step, won't block the pipeline to succeed
  variables:
    TEST_SUITES: (smoke|journey)
  rules:
    - !reference [.rule_templates, automatically_on_scheduled_e2e_test_run]
    - !reference [.rule_templates, manually_on_staging]

## production environment

mobile_release_candidate_publish:
  extends: .mobile_publish
  needs: ['lint_compile_test']
  allow_failure: false
  environment:
    name: mob-rc/${CI_COMMIT_BRANCH}
    deployment_tier: production
    url: https://expo.dev/accounts/holistic-foundation/projects/projectholi/channels/${CI_ENVIRONMENT_SLUG}
  variables:
    ENVIRONMENT_FILE: .env.staging
    EXPO_PUBLISH_RELEASE_CHANNEL: ${CI_ENVIRONMENT_SLUG}
  rules:
    - !reference [.rule_templates, only_on_production_release]
  after_script: |
    if [ $CI_JOB_STATUS == 'success' ]; then
      curl -X POST -H 'Content-Type: application/json' --data '{"channel": "#release-status", "branch": "'"$CI_COMMIT_REF_SLUG"'", "text":"The mobile release candidate \"'"$CI_COMMIT_BRANCH"'\" for release '$(git describe --tags --abbrev=0|sed "s|release/||")' has been updated to \"'"$CI_COMMIT_TITLE"'\" and is available for testing via:\n'"$CI_ENVIRONMENT_URL"'"}' "https://projectholi.rocket.chat/hooks/$ROCKETCHAT_HOOK_RELEASE_NOTIFIER"
    fi

mobile_release_publish:
  extends: .mobile_publish
  needs: ['mobile_release_candidate_publish']
  allow_failure: false
  environment:
    name: mob-production
    deployment_tier: production
    url: https://expo.dev/accounts/holistic-foundation/projects/projectholi/channels
  variables:
    ENVIRONMENT_FILE: .env.production
    USE_PRODUCTION_RELEASE_CHANNEL_FROM_EAS_JSON: 'true'
  rules:
    - !reference [.rule_templates, manually_on_production_release]
  after_script: |
    if [ $CI_JOB_STATUS == 'success' ]; then
      curl -X POST -H 'Content-Type: application/json' --data '{"channel": "#release-status", "branch": "'"$CI_COMMIT_REF_SLUG"'", "text":"The mobile release \"'"$CI_COMMIT_BRANCH"'\" for release '$(git describe --tags --abbrev=0|sed "s|release/||")' has been updated to \"'"$CI_COMMIT_TITLE"'\" and is published to the branch specific channel. You can find it at https://expo.dev/accounts/holistic-foundation/projects/projectholi/channels/\"'"$EXPO_PUBLISH_RELEASE_CHANNEL"'\" ."}' "https://projectholi.rocket.chat/hooks/$ROCKETCHAT_HOOK_RELEASE_NOTIFIER"
    fi

mobile_release_build_android:
  extends: .mobile_build
  needs: ['lint_compile_test']
  allow_failure: false
  variables:
    ENVIRONMENT_FILE: .env.production
    KEEP_ARTIFACTS: 'true'
    BUILD_PROFILE: production
    BUILD_PLATFORM: 'android'
    CHECK_VERSION_RELEASED: 'true'
    CI_ARTIFACTS_ENVIRONMENT_NAME: production
  artifacts:
    paths:
      - apps/mobile/artifacts_production/
    expire_in: 1 week
  rules:
    - !reference [.rule_templates, only_on_production_release]

mobile_release_build_ios:
  extends: .mobile_build
  needs: ['lint_compile_test']
  allow_failure: false
  variables:
    ENVIRONMENT_FILE: .env.production
    KEEP_ARTIFACTS: 'true'
    BUILD_PROFILE: production
    BUILD_PLATFORM: 'ios'
    CHECK_VERSION_RELEASED: 'true'
    CI_ARTIFACTS_ENVIRONMENT_NAME: production
  artifacts:
    paths:
      - apps/mobile/artifacts_production/
    expire_in: 1 week
  rules:
    - !reference [.rule_templates, only_on_production_release]

mobile_release_submit_android:
  needs: ['mobile_release_build_android']
  image: 'europe-north1-docker.pkg.dev/holi-shared/docker/holi-docker/node-expo-eas'
  cache: !reference [.yarn-cache-readonly]
  dependencies: [] # explicitly disable artifact usage
  script:
    - source .env.production
    - cd apps/mobile
    - corepack enable
    - yarn install --immutable --immutable-cache
    - export BUILD_ID=$(eas build:list --gitCommitHash "${CI_COMMIT_SHA}" --json --non-interactive --platform android --buildProfile production --limit=1  2> /dev/null | jq -r ".[0].id")
    - eas submit -p android --profile production --id "$BUILD_ID" --verbose --non-interactive --wait
  rules:
    - !reference [.rule_templates, only_on_production_release]
  interruptible: false
  after_script: |
    if [ $CI_JOB_STATUS == 'success' ]; then
      curl -X POST -H 'Content-Type: application/json' --data '{"channel": "#release-status", "branch": "'$CI_COMMIT_REF_SLUG'", "text":"The Android app for the release candidate \"'$CI_COMMIT_BRANCH'\" for release '$(git describe --tags --abbrev=0|sed "s|release/||")' has been updated to \"'"$CI_COMMIT_TITLE"'\" and was submitted to the Play Store."}' https://projectholi.rocket.chat/hooks/$ROCKETCHAT_HOOK_RELEASE_NOTIFIER
    fi

mobile_release_submit_ios:
  needs: ['mobile_release_build_ios']
  image: 'europe-north1-docker.pkg.dev/holi-shared/docker/holi-docker/node-expo-eas'
  cache: !reference [.yarn-cache-readonly]
  dependencies: [] # explicitly disable artifact usage
  script:
    - source .env.production
    - cd apps/mobile
    - corepack enable
    - yarn install --immutable --immutable-cache
    - export BUILD_ID=$(eas build:list --gitCommitHash "${CI_COMMIT_SHA}" --json --non-interactive --platform ios --buildProfile production --limit=1  2> /dev/null | jq -r ".[0].id")
    - eas submit -p ios --profile production --id "$BUILD_ID" --verbose --non-interactive --wait
  rules:
    - !reference [.rule_templates, only_on_production_release]
  interruptible: false
  after_script: |
    if [ $CI_JOB_STATUS == 'success' ]; then
      curl -X POST -H 'Content-Type: application/json' --data '{"channel": "#release-status", "branch": "'$CI_COMMIT_REF_SLUG'", "text":"The IOS app for the release candidate \"'$CI_COMMIT_BRANCH'\" for release '$(git describe --tags --abbrev=0|sed "s|release/||")' has been updated to \"'"$CI_COMMIT_TITLE"'\" and was submitted to the App Store."}' https://projectholi.rocket.chat/hooks/$ROCKETCHAT_HOOK_RELEASE_NOTIFIER
    fi
