version: 2.1

checkout-linux: &checkout-linux
  attach_workspace:
    at: /root

jobs:
  persist-checkout:
    docker:
      - image: python
    steps:
      - checkout
      - run:
          name: clean up git
          command: |
            rm -rf .git
      - persist_to_workspace:
          root: /root
          paths:
            - project

  unit-test:
    docker:
      - image: textile/builder:1.13.1
    steps:
      - *checkout-linux
      - restore_cache:
          key: go-mod-v1-{{ checksum "go.sum" }}-{{ arch }}
      - run:
          name: cache mods
          command: |
            go mod download
      - save_cache:
          key: go-mod-v1-{{ checksum "go.sum" }}-{{ arch }}
          paths:
            - /go/pkg/mod
      - run:
          name: build the binary
          command: |
            go build -i ./cmd/textile
      - run:
          name: run tests
          command: |
            ./test_compile

  build-cli-linux:
    docker:
      - image: textile/builder:1.13.1
    steps:
      - *checkout-linux
      - restore_cache:
          key: go-mod-v1-{{ checksum "go.sum" }}-{{ arch }}
      - run:
          name: install gox
          command: |
            go get github.com/mitchellh/gox
      - run:
          name: compile
          command: |
            COMMIT=$(echo $CIRCLE_SHA1 | cut -c -7)
            SUMMARY=$CIRCLE_SHA1
            if [ "${CIRCLE_TAG}" != "" ]; then
                SUMMARY=${CIRCLE_TAG}
            fi
            DATE=$(date --iso-8601=seconds)
            FLAGS="-X github.com/textileio/go-textile/common.GitSummary=${SUMMARY} -X github.com/textileio/go-textile/common.BuildDate=${DATE} -X github.com/textileio/go-textile/common.GitCommit=${COMMIT} -X github.com/textileio/go-textile/common.GitBranch=${CIRCLE_BRANCH} -X github.com/textileio/go-textile/common.GitState=clean"
            gox -ldflags="-w $FLAGS" -osarch="linux/amd64 linux/386 linux/arm" -output="{{.OS}}-{{.Arch}}" ./cmd/textile
      - run:
          name: collect artifacts
          command: |
            VERSION=$(echo $CIRCLE_SHA1 | cut -c -7)
            if [ "${CIRCLE_TAG}" != "" ]; then
                VERSION=${CIRCLE_TAG}
            fi
            OUT=~/dist/cli
            mkdir -p ${OUT}
            mkdir -p tmp
            cp LICENSE tmp/
            cp dist/README.md tmp/
            cp dist/install tmp/
            cd tmp
            declare -a arr=("linux-amd64" "linux-386" "linux-arm")
            for i in "${arr[@]}"
            do
                OSARCH=${i%.*}
                EXT=$([[ "$i" = *.* ]] && echo ".${i##*.}" || echo '')
                cp ../${i} textile${EXT}
                if [ "${EXT}" == ".exe" ]; then
                    zip go-textile_${VERSION}_${OSARCH}.zip LICENSE README.md install textile${EXT}
                    mv go-textile_${VERSION}_${OSARCH}.zip ${OUT}/
                else
                    tar -czvf go-textile_${VERSION}_${OSARCH}.tar.gz LICENSE README.md install textile${EXT}
                    mv go-textile_${VERSION}_${OSARCH}.tar.gz ${OUT}/
                fi
            done
            cd .. && rm -rf tmp
      - persist_to_workspace:
          root: ~/dist
          paths:
            - cli
      - store_artifacts:
          path: ~/dist/cli

  build-cli-darwin-windows:
    macos:
      xcode: '10.2.1'
    environment:
      GOPATH: /Users/distiller/go
      GOROOT: /usr/local/go
    steps:
      - checkout
      - run:
          name: install golang
          command: |
            curl -L -o go1.13.1.darwin-amd64.tar.gz https://dl.google.com/go/go1.13.1.darwin-amd64.tar.gz
            sudo tar -C /usr/local -xzf go1.13.1.darwin-amd64.tar.gz
      - restore_cache:
          key: go-mod-v1-{{ checksum "go.sum" }}-{{ arch }}
      - run:
          name: cache mods
          command: |
            export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
            go mod download
      - save_cache:
          key: go-mod-v1-{{ checksum "go.sum" }}-{{ arch }}
          paths:
            - ~/go/pkg/mod
      - run:
          name: install gox
          command: |
            export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
            go get github.com/mitchellh/gox
      - run:
          name: install mingw-w64
          command: |
            brew install mingw-w64
      - run:
          name: cross-compile
          command: |
            export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
            COMMIT=$(echo $CIRCLE_SHA1 | cut -c -7)
            SUMMARY=$CIRCLE_SHA1
            if [ "${CIRCLE_TAG}" != "" ]; then
                SUMMARY=${CIRCLE_TAG}
            fi
            DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
            FLAGS="-X github.com/textileio/go-textile/common.GitSummary=${SUMMARY} -X github.com/textileio/go-textile/common.BuildDate=${DATE} -X github.com/textileio/go-textile/common.GitCommit=${COMMIT} -X github.com/textileio/go-textile/common.GitBranch=${CIRCLE_BRANCH} -X github.com/textileio/go-textile/common.GitState=clean"
            gox -ldflags="-w $FLAGS" -osarch="darwin/amd64" -output="{{.OS}}-{{.Arch}}" ./cmd/textile
            CC="x86_64-w64-mingw32-gcc" CXX="x86_64-w64-mingw32-g++" gox -ldflags="-w $FLAGS" -cgo -osarch="windows/amd64" -output="{{.OS}}-{{.Arch}}" ./cmd/textile
      - run:
          name: collect artifacts
          command: |
            VERSION=$(echo $CIRCLE_SHA1 | cut -c -7)
            if [ "${CIRCLE_TAG}" != "" ]; then
                VERSION=${CIRCLE_TAG}
            fi
            OUT=~/dist/cli
            mkdir -p ${OUT}
            mkdir -p tmp
            cp LICENSE tmp/
            cp dist/README.md tmp/
            cp dist/install tmp/
            cd tmp
            declare -a arr=("darwin-amd64" "windows-amd64.exe")
            for i in "${arr[@]}"
            do
                OSARCH=${i%.*}
                EXT=$([[ "$i" = *.* ]] && echo ".${i##*.}" || echo '')
                cp ../${i} textile${EXT}
                if [ "${EXT}" == ".exe" ]; then
                    zip go-textile_${VERSION}_${OSARCH}.zip LICENSE README.md install textile${EXT}
                    mv go-textile_${VERSION}_${OSARCH}.zip ${OUT}/
                else
                    tar -czvf go-textile_${VERSION}_${OSARCH}.tar.gz LICENSE README.md install textile${EXT}
                    mv go-textile_${VERSION}_${OSARCH}.tar.gz ${OUT}/
                fi
            done
            cd .. && rm -rf tmp
      - persist_to_workspace:
          root: ~/dist
          paths:
            - cli
      - store_artifacts:
          path: ~/dist/cli

  build-ios-framework:
    macos:
      xcode: '10.2.1'
    environment:
      GOPATH: /Users/distiller/go
      GOROOT: /Users/distiller/gosrc/go
    steps:
      - checkout
      - run:
          name: install golang
          command: |
            export GOROOT=/usr/local/go
            export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
            curl -L -o go1.13.1.darwin-amd64.tar.gz https://dl.google.com/go/go1.13.1.darwin-amd64.tar.gz
            sudo tar -C /usr/local -xzf go1.13.1.darwin-amd64.tar.gz
            cd ~ && mkdir gosrc && cd gosrc
            git clone https://github.com/textileio/go.git && cd go
            git checkout sander/ptrace-hackery
            cd src && ./all.bash
      - restore_cache:
          key: go-mod-v1-{{ checksum "go.sum" }}-{{ arch }}
      - run:
          name: cache mods
          command: |
            export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
            go mod download
      - save_cache:
          key: go-mod-v1-{{ checksum "go.sum" }}-{{ arch }}
          paths:
            - ~/go/pkg/mod
      - run:
          name: install protobuf
          command: |
            brew install protobuf
      - run:
          name: build ios framework
          command: |
            export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
            go mod vendor
            mkdir -p ~/go/src/github.com/textileio
            cd ~ && mv project go/src/github.com/textileio/go-textile
            cd ~/go/src/github.com/textileio/go-textile
            export GO111MODULE=off
            go get golang.org/x/mobile/cmd/...
            COMMIT=$(echo $CIRCLE_SHA1 | cut -c -7)
            SUMMARY=$CIRCLE_SHA1
            if [ "${CIRCLE_TAG}" != "" ]; then
                SUMMARY=${CIRCLE_TAG}
            fi
            DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
            FLAGS="-X github.com/textileio/go-textile/common.GitSummary=${SUMMARY} -X github.com/textileio/go-textile/common.BuildDate=${DATE} -X github.com/textileio/go-textile/common.GitCommit=${COMMIT} -X github.com/textileio/go-textile/common.GitBranch=${CIRCLE_BRANCH} -X github.com/textileio/go-textile/common.GitState=clean"
            gomobile bind -v -ldflags="-w $FLAGS" -target=ios github.com/textileio/go-textile/mobile github.com/textileio/go-textile/core
      - run:
          name: build obj c protobuf bindings
          command: |
            cd ~/go/src/github.com/textileio/go-textile
            mkdir protos
            protoc --proto_path=./pb/protos --objc_out=./protos ./pb/protos/*
      - run:
          name: collect artifacts
          command: |
            VERSION=$(echo $CIRCLE_SHA1 | cut -c -7)
            if [ "${CIRCLE_TAG}" != "" ]; then
                VERSION=${CIRCLE_TAG}
            fi
            OUT=~/dist/ios_framework
            mkdir -p ${OUT}
            cd ~/go/src/github.com/textileio/go-textile
            tar -czvf go-textile_${VERSION}_ios-framework.tar.gz Mobile.framework protos
            mv go-textile_${VERSION}_ios-framework.tar.gz ${OUT}/
      - persist_to_workspace:
          root: ~/dist
          paths:
            - ios_framework
      - store_artifacts:
          path: ~/dist/ios_framework

  build-android-aar:
    docker:
      - image: circleci/android:api-28-ndk
    environment:
      GOROOT: /usr/local/go
      GOPATH: /home/circleci/go
    steps:
      - checkout
      - run:
          name: install golang
          command: |
            wget https://dl.google.com/go/go1.13.1.linux-amd64.tar.gz
            sudo tar -C /usr/local -xzf go1.13.1.linux-amd64.tar.gz
            mkdir -p $GOPATH/bin
      - run:
          name: install protobuf
          command: |
            curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v3.6.1/protoc-3.6.1-linux-x86_64.zip
            unzip protoc-3.6.1-linux-x86_64.zip -d protoc3
            sudo mv protoc3/bin/* /usr/local/bin/
            sudo mv protoc3/include/* /usr/local/include/
      - restore_cache:
          key: go-mod-v1-android-{{ checksum "go.sum" }}-{{ arch }}
      - run:
          name: cache mods
          command: |
            export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
            go mod download
      - save_cache:
          key: go-mod-v1-android-{{ checksum "go.sum" }}-{{ arch }}
          paths:
            - /go/pkg/mod
      - run:
          name: install tools
          command: |
            sdkmanager --licenses
            echo y | sdkmanager "build-tools;28.0.3"
            echo y | sdkmanager "platforms;android-28"
            sdkmanager 'ndk-bundle'
      - run:
          name: build android framework
          command: |
            export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
            go mod vendor
            mkdir -p ~/go/src/github.com/textileio
            cd ~ && mv project go/src/github.com/textileio/go-textile
            cd ~/go/src/github.com/textileio/go-textile
            export GO111MODULE=off
            go get golang.org/x/mobile/cmd/...
            COMMIT=$(echo $CIRCLE_SHA1 | cut -c -7)
            SUMMARY=$CIRCLE_SHA1
            if [ "${CIRCLE_TAG}" != "" ]; then
                SUMMARY=${CIRCLE_TAG}
            fi
            DATE=$(date --iso-8601=seconds)
            FLAGS="-X github.com/textileio/go-textile/common.GitSummary=${SUMMARY} -X github.com/textileio/go-textile/common.BuildDate=${DATE} -X github.com/textileio/go-textile/common.GitCommit=${COMMIT} -X github.com/textileio/go-textile/common.GitBranch=${CIRCLE_BRANCH} -X github.com/textileio/go-textile/common.GitState=clean"
            gomobile bind -v -ldflags="-w $FLAGS" -target=android -o=mobile.aar github.com/textileio/go-textile/mobile github.com/textileio/go-textile/core
      - run:
          name: build java protobuf bindings
          command: |
            cd ~/go/src/github.com/textileio/go-textile
            mkdir protos
            protoc --proto_path=./pb/protos --java_out=./protos ./pb/protos/*
      - run:
          name: collect artifacts
          command: |
            VERSION=$(echo $CIRCLE_SHA1 | cut -c -7)
            if [ "${CIRCLE_TAG}" != "" ]; then
                VERSION=${CIRCLE_TAG}
            fi
            OUT=~/dist/android_aar
            mkdir -p ${OUT}
            cd ~/go/src/github.com/textileio/go-textile
            tar -czvf go-textile_${VERSION}_android-aar.tar.gz mobile.aar protos
            mv go-textile_${VERSION}_android-aar.tar.gz ${OUT}/
      - persist_to_workspace:
          root: ~/go/src/github.com/textileio/go-textile
          paths:
            - mobile.aar
            - protos
      - persist_to_workspace:
          root: ~/dist
          paths:
            - android_aar
      - store_artifacts:
          path: ~/dist/android_aar

  build-js-types:
    docker:
      - image: circleci/node:10.15.3
    steps:
      - checkout
      - run:
          name: install @textile/protobufjs
          command: |
            npm install @textile/protobufjs@6.8.13
      - run:
          name: build js types
          command: |
            mkdir js-types
            ./node_modules/@textile/protobufjs/bin/pbjs -t static-module -w es6 -o js-types/index.js ./pb/protos/*
            ./node_modules/@textile/protobufjs/bin/pbts -o js-types/index.d.ts js-types/index.js
      - run:
          name: collect artifacts
          command: |
            VERSION=$(echo $CIRCLE_SHA1 | cut -c -7)
            if [ "${CIRCLE_TAG}" != "" ]; then
                VERSION=${CIRCLE_TAG}
            fi
            OUT=~/dist/js_types
            mkdir -p ${OUT}
            tar -czvf go-textile_${VERSION}_js-types.tar.gz js-types
            mv go-textile_${VERSION}_js-types.tar.gz ${OUT}/
      - persist_to_workspace:
          root: ./
          paths:
            - js-types
      - persist_to_workspace:
          root: ~/dist
          paths:
            - js_types
      - store_artifacts:
          path: ~/dist/js_types

  release:
    docker:
      - image: cibuilds/github:0.10
    steps:
      - *checkout-linux
      - deploy:
          name: release all
          command: |
            mkdir -p ~/dist
            mv ~/cli/* ~/dist/
            mv ~/ios_framework/* ~/dist/
            mv ~/android_aar/* ~/dist/
            mv ~/js_types/* ~/dist/
            PRE=$(echo "${CIRCLE_TAG}" | grep "rc" || true)
            if [ "${PRE}" != "" ]; then
                ghr -prerelease -t ${GITHUB_TOKEN} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} -c ${CIRCLE_SHA1} -delete ${CIRCLE_TAG} ~/dist/
            else
                ghr -t ${GITHUB_TOKEN} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} -c ${CIRCLE_SHA1} -delete ${CIRCLE_TAG} ~/dist/
            fi

  publish-cocoapod:
    macos:
      xcode: '10.2.1'
    steps:
      - checkout
      - run:
          name: Fetch CocoaPods Specs
          command: |
            curl https://cocoapods-specs.circleci.com/fetch-cocoapods-repo-from-s3.sh | bash -s cf
      - run:
          name: update podspec
          working_directory: release
          command: |
            VERSION=$(echo $CIRCLE_SHA1 | cut -c -7)
            if [ "${CIRCLE_TAG}" != "" ]; then
                VERSION=${CIRCLE_TAG}
                VERSION=$(echo $VERSION | cut -c 2-)
            fi
            sed -i.bak "s/<version>/${VERSION}/g" TextileCore.podspec
            pod trunk push TextileCore.podspec --allow-warnings

  publish-aar:
    docker:
      - image: circleci/android:api-28-ndk
    steps:
      - checkout
      - attach_workspace:
          at: ~/
      - run:
          name: publish artifacts
          working_directory: release
          command: |
            VERSION=$(echo $CIRCLE_SHA1 | cut -c -7)
            if [ "${CIRCLE_TAG}" != "" ]; then
                VERSION=${CIRCLE_TAG}
                VERSION=$(echo $VERSION | cut -c 2-)
            fi
            sed "s/<VERSION>/${VERSION}/g" mobile-template.pom > mobile-${VERSION}.pom
            cp ~/mobile.aar mobile-${VERSION}.aar
            curl -i -X PUT -u ${BINTRAY_USERNAME}:${BINTRAY_API_KEY} -T mobile-${VERSION}.pom https://api.bintray.com/maven/textile/maven/mobile/io/textile/mobile/${VERSION}/mobile-${VERSION}.pom;publish=1
            curl -i -X PUT -u ${BINTRAY_USERNAME}:${BINTRAY_API_KEY} -T mobile-${VERSION}.aar https://api.bintray.com/maven/textile/maven/mobile/io/textile/mobile/${VERSION}/mobile-${VERSION}.aar;publish=1
            curl -i -X POST -u ${BINTRAY_USERNAME}:${BINTRAY_API_KEY} https://api.bintray.com/content/textile/maven/mobile/${VERSION}/publish

  publish-pb:
    docker:
      - image: circleci/android:api-28-ndk
    steps:
      - checkout
      - attach_workspace:
          at: ~/
      - run:
          name: publish artifacts
          working_directory: release/PBProject
          command: |
            VERSION=$(echo $CIRCLE_SHA1 | cut -c -7)
            if [ "${CIRCLE_TAG}" != "" ]; then
                VERSION=${CIRCLE_TAG}
                VERSION=$(echo $VERSION | cut -c 2-)
            fi
            mkdir -p pb/src/main/java
            cp -r ~/protos/* pb/src/main/java/
            sed -i.bak "s/<version>/${VERSION}/g" pb/build.gradle
            ./gradlew pb:install
            ./gradlew pb:bintrayUpload

  publish-js-types:
    docker:
      - image: circleci/node:10.15.3
    steps:
      - checkout
      - attach_workspace:
          at: ~/
      - run:
          name: authenticate with registry
          working_directory: release/@textile/js-types
          command: echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ./.npmrc
      - run:
          name: publish artifacts
          working_directory: release/@textile/js-types
          command: |
            VERSION=$(echo $CIRCLE_SHA1 | cut -c -7)
            if [ "${CIRCLE_TAG}" != "" ]; then
                VERSION=${CIRCLE_TAG}
                VERSION=$(echo $VERSION | cut -c 2-)
            fi
            cp ~/js-types/* dist/
            sed -i.bak "s/<version>/${VERSION}/g" package.json
            npm publish --access=public

workflows:
  version: 2
  go-textile:
    jobs:
      - persist-checkout:
          filters:
            tags:
              only: /.*/
      - unit-test:
          requires:
            - persist-checkout
          filters:
            tags:
              only: /.*/
      - build-cli-darwin-windows:
          requires:
            - unit-test
          filters:
            branches:
              only: master
            tags:
              only: /.*/
      - build-cli-linux:
          requires:
            - unit-test
          filters:
            branches:
              only: master
            tags:
              only: /.*/
      - build-ios-framework:
          requires:
            - unit-test
          filters:
            branches:
              only: master
            tags:
              only: /.*/
      - build-android-aar:
          requires:
            - unit-test
          filters:
            branches:
              only: master
            tags:
              only: /.*/
      - build-js-types:
          requires:
            - unit-test
          filters:
            branches:
              only: master
            tags:
              only: /.*/
      - release:
          requires:
            - build-cli-darwin-windows
            - build-cli-linux
            - build-ios-framework
            - build-android-aar
            - build-js-types
          filters:
            branches:
              ignore: /.*/
            tags:
              only: /^v.*/
      - publish-cocoapod:
          requires:
            - release
          filters:
            branches:
              ignore: /.*/
            tags:
              only: /^v.*/
      - publish-aar:
          requires:
            - release
          filters:
            branches:
              ignore: /.*/
            tags:
              only: /^v.*/
      - publish-pb:
          requires:
            - release
          filters:
            branches:
              ignore: /.*/
            tags:
              only: /^v.*/
      - publish-js-types:
          requires:
            - release
          filters:
            branches:
              ignore: /.*/
            tags:
              only: /^v.*/

