version: 2.1

orbs:
  go: circleci/go@1.7.1
  docker: circleci/docker@2.1.2
  cloudsmith: cloudsmith/cloudsmith@1.0.5

parameters:
  cache-key:
    type: integer
    default: 1639697695
    description: Change to force cache reset `pwsh > Get-Date -UFormat %s`
  gover:
    type: string
    default: "1.18" # https://circleci.com/developer/images/image/cimg/go#image-tags
    description: Go Version to use

jobs:

  build:

    docker:
      - image: cimg/go:<< pipeline.parameters.gover >>
    resource_class: 2xlarge

    environment: # environment variables for the build itself
      TEST_RESULTS: /tmp/test-results

    steps:
      - checkout

      - restore_cache: # restores saved cache if no changes are detected since last run
          keys:
            - linux-go-{{ checksum "go.sum" }}-<< pipeline.parameters.cache-key >>

      - run:
          name: Install goreleaser
          command: go install github.com/goreleaser/goreleaser@latest

      - run: mkdir -p "$TEST_RESULTS"

      - run:
          name: Run unit tests

          # store the results of our tests in the $TEST_RESULTS directory
          command: gotestsum --junitfile ${TEST_RESULTS}/gotestsum-report.xml -- $PACKAGE_NAMES

      - store_test_results: # upload test results for display in Test Summary
          path: /tmp/test-results

      - run:
          name: Build binaries
          command: goreleaser build --snapshot

      - run:
          name: Enforce Go Formatted Code
          command: "[ `go fmt ./... | wc -l` -eq 0 ]"

      - save_cache: # restores saved cache if no changes are detected since last run
          key: linux-go-{{ checksum "go.sum" }}-<< pipeline.parameters.cache-key >>
          paths:
            - /home/circleci/go/pkg/mod

  integration-tests:
    docker:
      - image: cimg/go:<< pipeline.parameters.gover >>

    environment: # environment variables for the build itself
      TEST_RESULTS: /tmp/test-results
      GOTESTSUM_FORMAT: testname

      BIND_DOMAIN: example.com

      # FYI: Hexonet provides these credentials for use for public testing. They give access to a test area, not a real system. It is not a security issue to expose them.
      #
      # FYI: The domain name name was selected at random. If it stops working, this command will list domains to choose from:
      # echo '{ "hexo": { "apientity": "OTE", "apilogin": "test.user", "apipassword": "test.passw0rd" } }' > hexo-creds.json ; dnscontrol  get-zones --creds hexo-creds.json --format=nameonly hexo HEXONET all
      HEXONET_DOMAIN: a-b-c-music.com
      HEXONET_ENTITY: OTE
      HEXONET_PW: test.passw0rd
      HEXONET_UID: test.user

      AZURE_DNS_RESOURCE_GROUP: DNSControl

      GCLOUD_EMAIL: dnscontrol@dnscontrol-dev.iam.gserviceaccount.com
      GCLOUD_PROJECT: dnscontrol-dev
      GCLOUD_TYPE: service_account

      NAMEDOTCOM_URL: api.name.com
      NAMEDOTCOM_USER: dnscontroltest

    parameters:
      provider:
        type: string

    steps:
      - run:
          name: Test << parameters.provider >> set
          command: |
            if [ -z "$<< parameters.provider >>_DOMAIN" ] ; then
              echo "Skip test for << parameters.provider >> provider"
              circleci-agent step halt
            fi

      - checkout

      - run: mkdir -p "$TEST_RESULTS"

      - restore_cache: # restores saved cache if no changes are detected since last run
          keys:
            - linux-go-{{ checksum "go.sum" }}-<< pipeline.parameters.cache-key >>

      - run:
          name: Run integration tests for << parameters.provider >> provider
          working_directory: integrationTest
          no_output_timeout: 32m
          command: |
            if [ -n "$<< parameters.provider >>_DOMAIN" ] ; then
              gotestsum --junitfile ${TEST_RESULTS}/gotestsum-report.xml -- -timeout 30m -v -verbose -provider << parameters.provider >> -cfworkers=false
            else
              echo "Skip test for << parameters.provider >> provider"
            fi

      - store_test_results: # upload test results for display in Test Summary
          path: /tmp/test-results

  release:
    docker:
      - image: cimg/go:<< pipeline.parameters.gover >>
    resource_class: 2xlarge

    steps:
      - checkout

      - setup_remote_docker:
          version: 20.10.11
          docker_layer_caching: true

      - docker/check:
          docker-username: DOCKERHUB_USERNAME
          docker-password: DOCKERHUB_ACCESS_TOKEN

      - restore_cache: # restores saved cache if no changes are detected since last run
          keys:
            - linux-go-{{ checksum "go.sum" }}-<< pipeline.parameters.cache-key >>

      - run:
          name: Install goreleaser
          command: go install github.com/goreleaser/goreleaser@latest

      - run: goreleaser release

      - store_artifacts:
          path: dist

      - persist_to_workspace:
          root: dist
          paths:
            - '*.rpm'
            - '*.deb'

  upload:
    docker:
    - image: cimg/python:3.10

    parameters:
      arch:
        type: enum
        enum: ["i386", "amd64", "arm64", "x86_64"]
      format:
        type: enum
        enum: ["deb", "rpm"]
      distro:
        type: string


    steps:

    - attach_workspace:
        at: .

    - cloudsmith/ensure-api-key
    - cloudsmith/install-cli
    - cloudsmith/publish:
        cloudsmith-repository: stackoverflow/dnscontrol
        package-format: << parameters.format >>
                      # dnscontrol-3.18.2-next.arm64.deb
        package-path: dnscontrol-*.<< parameters.arch >>.<< parameters.format >>
        package-distribution: '<< parameters.distro >>'

workflows:
  version: 2
  build:
    jobs:
      - build:
          filters:  # required since `release` has tag filters AND requires `build`
            tags:
              only: /.*/

      - integration-tests:
          requires: [build]
          context: DNSProviders
          matrix:
            parameters:
              provider:
                # Providers that don't require secrets: (alphabetical)
                - BIND
                - HEXONET
                # Providers designated "officially supported": (alphabetical)
                - AZURE_DNS
                - CLOUDFLAREAPI
                - GCLOUD
                - NAMEDOTCOM
                - ROUTE53
                # All others: (alphabetical)
                - CLOUDNS
                - DIGITALOCEAN
                - GANDI_V5
                - HEDNS
                - INWX
                - POWERDNS
          filters:
            branches:
              ignore: [master, main]

      - release:
          requires: [build]
          context: [DNSControl]
          # Only run this job on git tag pushes
          filters:
            branches:
              ignore: /.*/
            tags:
              only: /v[0-9]+(\.[0-9]+)*(-.*)*/

      - upload:
          name: upload dnscontrol_<< matrix.arch >>.rpm
          requires: [release]
          context: [StackExchange]
          format: rpm
          distro: fedora/25
          matrix:
            parameters:
              arch: ["i386", "x86_64", "arm64"]
          # Only run this job on git tag pushes
          filters:
            branches:
              ignore: /.*/
            tags:
              only: /v[0-9]+(\.[0-9]+)*(-.*)*/

      - upload:
          name: upload dnscontrol_<< matrix.arch >>.deb
          requires: [release]
          context: [StackExchange]
          format: deb
          distro: debian/buster
          matrix:
            parameters:
              arch: ["i386", "amd64", "arm64"]
          # Only run this job on git tag pushes
          filters:
            branches:
              ignore: /.*/
            tags:
              only: /v[0-9]+(\.[0-9]+)*(-.*)*/

