---
version: '3'

env:
  RELEASE_ANSIBLE:
    sh: |
      if [[ '{{.REPOSITORY_TYPE}}' == 'ansible' ]] && [[ '{{.REPOSITORY_SUBTYPE}}' == 'role' ]]; then
        echo 'release'
      fi
  RELEASE_DOCKER:
    sh: |
      if [ -f Dockerfile ] && ([[ '{{.REPOSITORY_TYPE}}' == 'docker' ]] || [[ "$(jq -r '.blueprint.dockerPublish' package.json)" == 'true' ]]); then
        echo 'release'
      fi
  RELEASE_GO:
    sh: |
      if [[ '{{.REPOSITORY_TYPE}}' == 'go' ]] && [[ '{{.REPOSITORY_SUBTYPE}}' == 'cli' ]]; then
        echo 'release'
      fi
  RELEASE_NPM:
    sh: |
      if [[ '{{.REPOSITORY_TYPE}}' == 'npm' ]] || [[ "$(jq -r '.blueprint.npmPublish' package.json)" == 'true' ]]; then
        echo 'release'
      fi
  RELEASE_PACKER:
    sh: |
      if [[ '{{.REPOSITORY_TYPE}}' == 'packer' ]]; then
        echo 'release'
      fi
  RELEASE_PYTHON:
    sh: |
      if [[ '{{.REPOSITORY_TYPE}}' == 'python' ]] || [[ "$(jq -r '.blueprint.pythonPublish' package.json)" == 'true' ]]; then
        echo 'release'
      fi
  SNAP_PACKAGE:
    sh: jq -r '.blueprint.snapPackage' package.json

tasks:
  add-channel:
    deps:
      - add-channel:ansible
      - add-channel:docker
      - add-channel:npm
      - add-channel:packer
      - add-channel:python
      - add-channel:snap
    summary: |
      Must return a parseable JSON string that resembles the following format:

      ```json
      {
        type: 'patch',
        channel: 'master',
        gitHead: 'c7dbb1e87ebff9b177bdb52a326f5b8373b79442',
        version: '1.1.26',
        gitTag: 'v1.1.26',
        name: 'GitLab release',
        notes: '## [1.1.26](https://gitlab.com/megabyte-labs/npm/configs/release/compare/v1.1.25...v1.1.26) (2022-04-07)\n' +
          '\n' +
          '\n' +
          '\n',
        url: 'https://gitlab.com/megabyte-labs%2Fnpm%2Fconfigs%2Frelease/-/releases/v1.1.26',
        pluginName: '@semantic-release/gitlab'
      }
      ```

  add-channel:ansible:
    vars:
      GALAXY_URL:
        sh: |
          if [ -n "$RELEASE_ANSIBLE" ]; then
            echo "https://galaxy.ansible.com/{{.GALAXY_NAMESPACE}}/{{.GALAXY_ROLE_NAME}}"
          fi
    cmds:
      - |
        echo '{"name": "Ansible Galaxy role", "url": "{{.GALAXY_URL}}"}'
    status:
      - '[ -z "$RELEASE_ANSIBLE" ]'

  add-channel:docker:
    vars:
      DOCKERHUB_URL:
        sh: |
          if [ -n "$RELEASE_DOCKER" ]; then
            echo "https://hub.docker.com/r/{{.DOCKERHUB_PROFILE}}/$(jq -r '.blueprint.slug' package.json)"
          fi
    cmds:
      - |
        echo '{"name": "DockerHub", "url": "{{.DOCKERHUB_URL}}"}'
    status:
      - '[ -z "$RELEASE_DOCKER" ]'

  add-channel:npm:
    cmds:
      - |
        echo '{"name": "Testing", "url": "https://megabyte.space"}'
    status:
      - '[ -z "$RELEASE_NPM" ]'

  add-channel:packer:
    vars:
      VAGRANTUP_URL:
        sh: |
          if [ -n "$RELEASE_PACKER" ]; then
            BASENAME="$(jq -r '.variables.box_basename' template.json)"
            VAGRANTUP_USER="$(jq -r '.variables.vagrantup_user' template.json)"
            if [ "$BASENAME" != 'null' ] && [ "$BASENAME" != 'null' ]; then
              echo "https://app.vagrantup.com/$VAGRANTUP_USER/boxes/$BASENAME"
            else
              echo "https://megabyte.space"
            fi
          fi
    cmds:
      - |
        echo '{"name": "VagrantUp box", "url": "{{.VAGRANTUP_URL}}"}'
    status:
      - '[ -z "$RELEASE_PACKER" ]'

  add-channel:python:
    vars:
      PYPI_URL:
        sh: |
          if [ -n "$RELEASE_PYTHON" ]; then
            PKG_NAME="$(jq -r '.blueprint.customPyPiPackageName' package.json)"
            if [ "$PKG_NAME" == 'null' ]; then
              PKG_NAME="$(jq -r '.blueprint.customPackageName' package.json)"
            fi
            if [ "$PKG_NAME" == 'null' ]; then
              PKG_NAME="$(jq -r '.name' package.json)"
            fi
            echo "https://pypi.org/project/$PKG_NAME"
          fi
    cmds:
      - |
        echo '{"name": "pip package", "url": "{{.PYPI_URL}}"}'
    status:
      - '[ -z "$RELEASE_PYTHON" ]'

  add-channel:snap:
    vars:
      SNAP_PACKAGE:
        sh: echo "$SNAP_PACKAGE"
    cmds:
      - |
        echo '{"name": "Snap", "url": "https://snapcraft.io/{{.SNAP_PACKAGE}}"}'
    status:
      - '[ "$SNAP_PACKAGE" == "null" ]'

  # eslint-disable max-len
  analyze:
    summary: |
      | Command property | Description                                                                                                                                                |
      |------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------|
      | `exit code`      | Any non `0` code is considered as an unexpected error and will stop the `semantic-release` execution with an error.                                        |
      | `stdout`         | Only the release type (`major`, `minor` or `patch` etc..) can be written to `stdout`. If no release has to be done the command must not write to `stdout`. |
      | `stderr`         | Can be used for logging.                                                                                                                                   |
    cmds:
      - |
        if [ "$FORCE_SEMANTIC_RELEASE" == 'true' ]; then
          echo 'patch'
        fi

  # eslint-enable max-len
  build:
    deps:
      - build:ansible
      - build:docker
      - build:go
      - build:npm
      - build:packer
      - build:python

  build:ansible:
    cmds:
      - task: :build
    status:
      - '[ -z "$RELEASE_ANSIBLE" ]'

  build:docker:
    cmds:
      - task: :build
    status:
      - '[ -z "$RELEASE_DOCKER" ]'

  build:go:
    cmds:
      - task: build:go:continue
    status:
      - '[ -z "$RELEASE_GO" ]'

  build:go:continue:
    deps:
      - build:go:deps
    cmds:
      - task: :build

  build:go:deps:
    deps:
      - :docker:login
      - :install:go:goreleaser
      - :install:go:nfpm
      - :install:software:go
      - :install:software:snapcraft

  build:npm:
    deps:
      - build:npm:deps
    cmds:
      - task: :build
    status:
      - '[ -z "$RELEASE_NPM" ]'

  build:npm:deps:
    deps:
      - build:npm:deps:go

  build:npm:deps:go:
    cmds:
      - task: build:go:deps
    status:
      - '[ "{{.REPOSITORY_SUBTYPE}}" != "cli" ]'

  build:packer:
    cmds:
      - task: :build
    status:
      - '[ -z "$RELEASE_PACKER" ]'

  build:python:
    cmds:
      - task: :build
    status:
      - '[ -z "$RELEASE_PYTHON" ]'

  fail:
    deps:
      - :install:software:jq
    env:
      ARTIFACTS_JSON:
        sh: jq -r '.' build/artifacts.json || echo null
      METADATA_JSON:
        sh: jq -r '.' build/metadata.json || echo null
      PACKAGE_JSON:
        sh: jq -r '.' package.json
      RELEASE_JSON:
        sh: jq -r '.' .release.json || echo null
      TMP:
        sh: mktemp
      VARIABLES_JSON:
        sh: jq -r '.' .variables.json
    cmds:
      - jq -n --arg artifacts "$ARTIFACTS_JSON" --arg metadata "$METADATA_JSON" --arg pkg "$PACKAGE_JSON" --arg release "$RELEASE_JSON" --arg vars "$VARIABLES_JSON" --arg job "$CI_JOB_ID"
        '.["package.json"] = $pkg | .[".release.json"] = $release | .["build/artifacts.json"] = $artifacts | .["build/metadata.json"] = $metadata | .[".variables.json"] = $vars | .CI_JOB_ID = $job' > "$TMP"
      - >
        curl -X POST -H "Content-Type: application/json" -d "$(cat "$TMP")"
        "https://maker.ifttt.com/trigger/SemanticReleaseFail/json/with/key/$IFTTT_WEBHOOK_TOKEN"
    status:
      - '[ -z "$IFTTT_WEBHOOK_TOKEN" ]'

  notes:
    cmds:
      - task: notes:introduction
      - task: notes:project-specific

  notes:ansible:
    vars:
      PKG_NAME:
        sh: |
          if [ -n "$RELEASE_ANSIBLE" ]; then
            echo "{{.GALAXY_NAMESPACE}}.{{.GALAXY_ROLE_NAME}}"
          fi
      VERSION:
        sh: jq -r '.version' package.json
    cmds:
      - echo -e '```shell\nansible-galaxy install {{.PKG_NAME}},v{{.VERSION}}\n```\n'
    status:
      - '[ -z "$RELEASE_ANSIBLE" ]'

  notes:docker:
    vars:
      IMAGE:
        sh: |
          if [ -n "$RELEASE_DOCKER" ]; then
            echo "{{.DOCKERHUB_PROFILE}}/$(jq -r '.blueprint.slug' package.json)"
          fi
      VERSION:
        sh: jq -r '.version' package.json
    cmds:
      - echo -e '```shell\ndocker pull {{.IMAGE}}:{{.VERSION}}\n```\n'
    status:
      - '[ -z "$RELEASE_DOCKER" ]'

  notes:go:
    vars:
      GITHUB_GO_URL:
        sh: jq -r '.blueprint.repository.github' package.json | sed 's/https:\/\///'
      VERSION:
        sh: jq -r '.version' package.json
    cmds:
      - echo -e '```shell\ngo install {{.GITHUB_GO_URL}}@v{{.VERSION}}\n```\n'
    status:
      - '[ -z "$RELEASE_GO" ]'

  notes:introduction:
    cmds:
      - echo -e 'Grab this version by running:\n\n'

  notes:npm:
    vars:
      FLAG:
        sh: |
          if [ '{{.REPOSITORY_SUBTYPE}}' == 'cli' ]; then
            echo ' -g'
          elif [ '{{.REPOSITORY_SUBTYPE}}' == 'config' ] || [ '{{.REPOSITORY_SUBTYPE}}' == 'plugin' ]; then
            echo ' --save-dev'
          else
            echo ' --save'
          fi
      PKG_NAME:
        sh: jq -r '.name' package.json
      VERSION:
        sh: jq -r '.version' package.json
    cmds:
      - echo -e '```shell\nnpm i{{.FLAG}} {{.PKG_NAME}}@{{.VERSION}}\n```\n'
    status:
      - '[ -z "$RELEASE_NPM" ]'

  notes:packer:
    vars:
      VAGRANTUP_BOX:
        sh: |
          if [ -n "$RELEASE_PACKER" ]; then
            BASENAME="$(jq -r '.variables.box_basename' template.json)"
            VAGRANTUP_USER="$(jq -r '.variables.vagrantup_user' template.json)"
            if [ "$BASENAME" != 'null' ] && [ "$BASENAME" != 'null' ]; then
              echo "$VAGRANTUP_USER/$BASENAME"
            fi
          fi
      VERSION:
        sh: jq -r '.version' package.json
    cmds:
      - echo -e '```shell\nvagrant init --box-version '{{.VERSION}}' {{.VAGRANTUP_BOX}} && vagrant up\n```\n'
    status:
      - '[ -z "$RELEASE_PACKER" ]'

  notes:project-specific:
    deps:
      - notes:ansible
      - notes:docker
      - notes:go
      - notes:npm
      - notes:packer
      - notes:python

  notes:python:
    vars:
      PKG_NAME:
        sh: |
          if [ -n "$RELEASE_PYTHON" ]; then
            PKG_NAME="$(jq -r '.blueprint.customPyPiPackageName' package.json)"
            if [ "$PKG_NAME" == 'null' ]; then
              PKG_NAME="$(jq -r '.blueprint.customPackageName' package.json)"
            fi
            if [ "$PKG_NAME" == 'null' ]; then
              PKG_NAME="$(jq -r '.name' package.json)"
            fi
            echo "$PKG_NAME"
          fi
      VERSION:
        sh: jq -r '.version' package.json
    cmds:
      - echo -e '```shell\npip3 install {{.PKG_NAME}}=={{.VERSION}}\n```\n'
    status:
      - '[ -z "$RELEASE_PYTHON" ]'

  prepare:
    deps:
      - prepare:ansible
      - prepare:docker
      - prepare:go
      - prepare:npm
      - prepare:packer
      - prepare:python
    summary: |
      | Command property | Description                                                                                                         |
      |------------------|---------------------------------------------------------------------------------------------------------------------|
      | `exit code`      | Any non `0` code is considered as an unexpected error and will stop the `semantic-release` execution with an error. |
      | `stdout`         | Can be used for logging.                                                                                            |
      | `stderr`         | Can be used for logging.                                                                                            |

  prepare:ansible:
    cmds:
      - task: :ansible:prepare
    status:
      - '[ -z "$RELEASE_ANSIBLE" ]'

  prepare:docker:
    cmds:
      - task: :docker:prepare
    status:
      - '[ -z "$RELEASE_DOCKER" ]'

  prepare:go:
    cmds:
      - task: :go:prepare
    status:
      - '[ -z "$RELEASE_GO" ]'

  prepare:npm:
    cmds:
      - task: :npm:prepare
    status:
      - '[ -z "$RELEASE_NPM" ]'

  prepare:packer:
    cmds:
      - task: :packer:prepare
    status:
      - '[ -z "$RELEASE_PACKER" ]'

  prepare:python:
    cmds:
      - task: :python:prepare
    status:
      - '[ -z "$RELEASE_PYTHON" ]'

  publish:
    deps:
      - publish:ansible
      - publish:docker
      - publish:go
      - publish:npm
      - publish:packer
      - publish:python

  publish:ansible:
    cmds:
      - task: :ansible:publish
    status:
      - '[ -z "$RELEASE_ANSIBLE" ]'

  publish:docker:
    cmds:
      - task: :docker:publish
    status:
      - '[ -z "$RELEASE_DOCKER" ]'

  publish:go:
    cmds:
      - task: :go:publish
    status:
      - '[ -z "$RELEASE_GO" ]'

  publish:npm:
    summary: |
      Modify the dist tag used (shown in release notes) by modifying `package.json` with the following:

      ```
      {
        "publishConfig": {
        "registry": "https://registry.npmjs.org/",
        "tag": "latest"
      }
      ```
    cmds:
      - task: publish:npm:tasks
    status:
      - '[ -z "$RELEASE_NPM" ]'

  publish:npm:latest:
    vars:
      PKG_NAME:
        sh: jq -r '.name' package.json
      VERSION:
        sh: jq -r '.version' package.json
    cmds:
      - npm config set -- 'https://registry.npmjs.org/:_authToken' '${NPM_TOKEN}'
      - npm dist-tag add {{.PKG_NAME}}@{{.VERSION}} latest &> /dev/null

  publish:npm:tasks:
    deps:
      - publish:npm:latest
      - :npm:publish:gitlab

  publish:packer:
    cmds:
      - task: :packer:publish
    status:
      - '[ -z "$RELEASE_PACKER" ]'

  publish:python:
    cmds:
      - task: :python:publish
    status:
      - '[ -z "$RELEASE_PYTHON" ]'

  success:
    deps:
      - :install:software:jq
    summary: |
      | Command property | Description                                                                                                         |
      |------------------|---------------------------------------------------------------------------------------------------------------------|
      | `exit code`      | Any non `0` code is considered as an unexpected error and will stop the `semantic-release` execution with an error. |
      | `stdout`         | Can be used for logging.                                                                                            |
      | `stderr`         | Can be used for logging.                                                                                            |
    env:
      PACKAGE_JSON:
        sh: jq -r '.' package.json
      RELEASE_JSON:
        sh: jq -r '.' .release.json
      TMP:
        sh: mktemp
      VARIABLES_JSON:
        sh: jq -r '.' .variables.json
    cmds:
      - jq -n --arg pkg "$PACKAGE_JSON" --arg release "$RELEASE_JSON" --arg vars "$VARIABLES_JSON"
        '.["package.json"] = $pkg | .[".release.json"] = $release | .[".variables.json"] = $vars' > "$TMP"
      - >
        curl -X POST -H "Content-Type: application/json" -d "$(cat "$TMP")"
        "https://maker.ifttt.com/trigger/SemanticRelease/json/with/key/$IFTTT_WEBHOOK_TOKEN"
    status:
      - '[ -z "$IFTTT_WEBHOOK_TOKEN" ]'

  verify:conditions:
    deps:
      - verify:conditions:ansible
      - verify:conditions:docker
      - verify:conditions:go
      - verify:conditions:npm
      - verify:conditions:packer
      - verify:conditions:python
    summary: |
      | Command property | Description                                                              |
      |------------------|--------------------------------------------------------------------------|
      | `exit code`      | `0` if the verification is successful, or any other exit code otherwise. |
      | `stdout`         | Write only the reason for the verification to fail.                      |
      | `stderr`         | Can be used for logging.                                                 |

  verify:conditions:ansible:
    cmds:
      - task: :ansible:verify
    status:
      - '[ -z "$RELEASE_ANSIBLE" ]'

  verify:conditions:docker:
    cmds:
      - task: :docker:verify
    status:
      - '[ -z "$RELEASE_DOCKER" ]'

  verify:conditions:go:
    cmds:
      - task: :go:verify
    status:
      - '[ -z "$RELEASE_GO" ]'

  verify:conditions:npm:
    cmds:
      - task: :npm:verify
    status:
      - '[ -z "$RELEASE_NPM" ]'

  verify:conditions:packer:
    cmds:
      - task: :packer:verify
    status:
      - '[ -z "$RELEASE_PACKER" ]'

  verify:conditions:python:
    cmds:
      - task: :python:verify
    status:
      - '[ -z "$RELEASE_PYTHON" ]'

  verify:release:
    deps:
      - verify:release:ansible
      - verify:release:docker
      - verify:release:go
      - verify:release:npm
      - verify:release:packer
      - verify:release:python
    summary: |
      | Command property | Description                                                              |
      |------------------|--------------------------------------------------------------------------|
      | `exit code`      | `0` if the verification is successful, or any other exit code otherwise. |
      | `stdout`         | Only the reason for the verification to fail can be written to `stdout`. |
      | `stderr`         | Can be used for logging.                                                 |

  verify:release:ansible:
    cmds:
      - 'true'
    status:
      - '[ -z "$RELEASE_ANSIBLE" ]'

  verify:release:docker:
    cmds:
      - 'true'
    status:
      - '[ -z "$RELEASE_DOCKER" ]'

  verify:release:go:
    cmds:
      - 'true'
    status:
      - '[ -z "$RELEASE_GO" ]'

  verify:release:npm:
    cmds:
      - 'true'
    status:
      - '[ -z "$RELEASE_NPM" ]'

  verify:release:packer:
    cmds:
      - 'true'
    status:
      - '[ -z "$RELEASE_PACKER" ]'

  verify:release:python:
    cmds:
      - 'true'
    status:
      - '[ -z "$RELEASE_PYTHON" ]'
