name: $(Build.SourceBranch)-$(date:yyyyMMdd)$(rev:.r)

# The Different jobs (lint, test, build to run)
jobs:
  - job: changelog
    steps:
      - bash: |
          git --no-pager diff --name-only HEAD $(git merge-base HEAD master) --exit-code CHANGELOG.md
        displayName: Changelog Updated

  - job: lint
    pool:
      vmImage: "macos-10.14"
    steps:
      - checkout: self
      - template: .azure/install-rust.yml
      - script: |
          rustup component add rustfmt
        displayName: Lint dependencies
      - script: cargo fmt --all -- --check
        displayName: Lint
    variables:
      rust_toolchain: '1.40.0'

  - job: clippy_lint
    pool:
      vmImage: "ubuntu-16.04"
    steps:
      - checkout: self
      - template: .azure/install-rust.yml
      - template: .azure/install-llvm.yml
      - template: .azure/install-sccache.yml
      - template: .azure/install-cmake.yml
      - script: |
          rustup component add rustfmt
          rustup component add clippy || cargo install --git https://github.com/rust-lang/rust-clippy/ --force clippy
        displayName: Lint dependencies with clippy
      - script: cargo clippy --workspace
        displayName: Clippy Lint
    variables:
      rust_toolchain: nightly-2019-12-19

  - job: Test
    strategy:
      matrix:
        linux:
          imageName: "ubuntu-16.04"
          rust_toolchain: nightly-2019-12-19
        mac:
          imageName: "macos-10.14"
          rust_toolchain: nightly-2019-12-19
          # By default schannel checks revocation of certificates unlike some other SSL
          # backends, but we've historically had problems on CI where a revocation
          # server goes down presumably. See #43333 for more info
          CARGO_HTTP_CHECK_REVOKE: false
        windows:
          imageName: "vs2017-win2016"
          rust_toolchain: '1.40.0'
    pool:
      vmImage: $(imageName)
    condition: in(variables['Build.SourceBranch'], 'refs/heads/master', 'refs/heads/staging', 'refs/heads/trying')
    steps:
      - checkout: self
      - template: .azure/install-rust.yml
      - template: .azure/install-llvm.yml
      - template: .azure/install-sccache.yml
      - template: .azure/install-cmake.yml
      - bash: |
          hostname
          uname -a
        displayName: System info (*nix)
        condition: and(succeeded(), not(eq(variables['Agent.OS'], 'Windows_NT')))
      - bash: |
          cat /proc/cpuinfo
          cat /proc/meminfo
        displayName: System info - Extended (Linux)
        condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
      - bash: |
          sysctl -a | grep machdep.cpu
        displayName: System info - Extended (Mac)
        condition: and(succeeded(), eq(variables['Agent.OS'], 'Darwin'))
      - bash: make test
        displayName: Tests (*nix)
        condition: and(succeeded(), not(eq(variables['Agent.OS'], 'Windows_NT')))
      - bash: make spectests-cranelift
        displayName: Tests (Windows)
        condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))

  - job: Check
    pool:
      vmImage: "ubuntu-16.04"
    variables:
      rust_toolchain: nightly-2019-12-19
    condition: in(variables['Build.SourceBranch'], 'refs/heads/master', 'refs/heads/staging', 'refs/heads/trying')
    steps:
      - checkout: self
      - template: .azure/install-rust.yml
      - template: .azure/install-llvm.yml
      - template: .azure/install-sccache.yml
      - template: .azure/install-cmake.yml
      - bash: make check
        displayName: Check with Flags
        condition: and(succeeded(), not(eq(variables['Agent.OS'], 'Windows_NT')))

  - job: Build_CLI
    strategy:
      matrix:
        linux:
          imageName: "ubuntu-16.04"
          rust_toolchain: nightly-2019-12-19
        mac:
          imageName: "macos-10.14"
          rust_toolchain: nightly-2019-12-19
          MACOSX_DEPLOYMENT_TARGET: 10.10
        windows:
          imageName: "vs2017-win2016"
          rust_toolchain: '1.40.0'
          # RUSTFLAGS: -Ctarget-feature=+crt-static
    pool:
      vmImage: $(imageName)
    condition: |
      or(
        in(variables['Build.SourceBranch'], 'refs/heads/master', 'refs/heads/staging', 'refs/heads/trying'),
        startsWith(variables['Build.SourceBranch'], 'refs/tags')
      )
    steps:
      - checkout: self
      - template: .azure/install-rust.yml
      - template: .azure/install-llvm.yml
      - template: .azure/install-sccache.yml
      - template: .azure/install-cmake.yml
      - template: .azure/install-innosetup.yml
      - bash: |
          mkdir -p artifacts
        displayName: Create Artifacts Dir
      - bash: make release
        displayName: Build (*nix)
        condition: and(succeeded(), not(eq(variables['Agent.OS'], 'Windows_NT')))
      - bash: sudo apt-get install musl-tools && make release-musl
        displayName: Build (Linux, x86_64-unknown-linux-musl)
        condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
      - bash: make release-llvm
        displayName: Build (Windows)
        condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
      - bash: |
          make build-wapm
        displayName: Build WAPM
        condition: |
          startsWith(variables['Build.SourceBranch'], 'refs/tags')
      - bash: |
          make build-install-package
          cp ./wasmer.tar.gz ./artifacts/$(./scripts/binary-name.sh)
        displayName: Build Distribution (*nix)
        condition: |
          and(
            succeeded(),
            startsWith(variables['Build.SourceBranch'], 'refs/tags'),
            not(eq(variables['Agent.OS'], 'Windows_NT'))
          )
      - bash: |
          cd ./src/installer
          iscc wasmer.iss
          cp WasmerInstaller.exe ../../artifacts/wasmer-windows.exe
        displayName: Build Distribution (Windows)
        condition: |
          and(
            succeeded(),
            startsWith(variables['Build.SourceBranch'], 'refs/tags'),
            eq(variables['Agent.OS'], 'Windows_NT')
          )
      - publish: $(System.DefaultWorkingDirectory)/artifacts
        artifact: cli-$(Agent.OS)

  - job: Build_Library
    strategy:
      matrix:
        linux:
          imageName: "ubuntu-16.04"
          rust_toolchain: nightly-2019-12-19
        mac:
          imageName: "macos-10.14"
          rust_toolchain: nightly-2019-12-19
          MACOSX_DEPLOYMENT_TARGET: 10.10
        windows:
          imageName: "vs2017-win2016"
          rust_toolchain: '1.40.0'
          # RUSTFLAGS: -Ctarget-feature=+crt-static
    pool:
      vmImage: $(imageName)
    condition: |
      or(
        in(variables['Build.SourceBranch'], 'refs/heads/master', 'refs/heads/staging', 'refs/heads/trying'),
        startsWith(variables['Build.SourceBranch'], 'refs/tags')
      )
    steps:
      - checkout: self
      - template: .azure/install-rust.yml
      - template: .azure/install-llvm.yml
      - template: .azure/install-sccache.yml
      - template: .azure/install-cmake.yml
      - bash: |
          mkdir -p artifacts
        displayName: Create Artifacts Dir
      - bash: |
          make test-capi
        displayName: Test c-api
        condition: and(succeeded(), not(eq(variables['Agent.OS'], 'Windows_NT')))
      - bash: |
          make capi
        displayName: Build c-api
      - bash: |
          make build-capi-package
          cp ./wasmer-c-api.tar.gz ./artifacts/$(./scripts/capi-name.sh)
        displayName: Build c-api artifacts (Unix)
        condition: |
          and(
            succeeded(),
            not(eq(variables['Agent.OS'], 'Windows_NT'))
          )
      - bash: |
          make build-capi-package
          cp ./wasmer-c-api.tar.gz ./artifacts/wasmer-c-api-windows.tar.gz
        displayName: Build c-api artifacts (Windows)
        condition: |
          and(
            succeeded(),
            eq(variables['Agent.OS'], 'Windows_NT')
          )
      - publish: $(System.DefaultWorkingDirectory)/artifacts
        artifact: library-$(Agent.OS)

  - job: Build_Docs
    pool:
      vmImage: "ubuntu-16.04"
    variables:
      rust_toolchain: nightly-2019-12-19
    condition: in(variables['Build.SourceBranch'], 'refs/heads/master', 'refs/heads/staging', 'refs/heads/trying')
    steps:
      - checkout: self
      - template: .azure/install-rust.yml
      - template: .azure/install-llvm.yml
      - template: .azure/install-sccache.yml
      - template: .azure/install-cmake.yml
      - bash: |
          sudo apt-get install doxygen graphviz
        displayName: Install doxygen
      - bash: |
          make docs
        displayName: Build docs
      - publish: $(System.DefaultWorkingDirectory)/api-docs
        artifact: api-docs
        displayName: Save Docs artifact

  - job: Publish
    dependsOn:
      - Build_CLI
      - Build_Library
    condition: |
      startsWith(variables['Build.SourceBranch'], 'refs/tags')
    steps:
      # - download: current
      - task: DownloadPipelineArtifact@1
        inputs:
          targetPath: $(Build.ArtifactStagingDirectory)
      - bash: |
          ls $ARTIFACT_STAGING_DIRECTORY
        displayName: List Artifacts
        env:
          ARTIFACT_STAGING_DIRECTORY: $(Build.ArtifactStagingDirectory)
      - script: VERSION_TAG=`git describe --tags` && echo "##vso[task.setvariable variable=VERSION_TAG]$VERSION_TAG"
        displayName: Set the tag name as an environment variable
      - task: GithubRelease@0
        displayName: "Create GitHub Release"
        condition: and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/tags'))
        continueOnError: true
        inputs:
          gitHubConnection: 'wasmer'
          repositoryName: 'wasmerio/wasmer'
          action: 'create'
          target: '$(Build.SourceVersion)'
          title: '$(VERSION_TAG)'
          addChangeLog: false
          tagSource: 'auto'
          # TODO: automate it all by getting the release notes from somewhere else and using the `releaseNotesFile` key
          isDraft: false
          isPreRelease: false
      - task: GithubRelease@0
        displayName: "Update GitHub Release with assets"
        condition: and(succeededOrFailed(), startsWith(variables['Build.SourceBranch'], 'refs/tags'))
        inputs:
          gitHubConnection: 'wasmer'
          repositoryName: 'wasmerio/wasmer'
          action: 'edit'
          target: '$(Build.SourceVersion)'
          title: '$(VERSION_TAG)'
          tag: $(VERSION_TAG)
          addChangeLog: false
          tagSource: 'auto'
          # TODO: automate it all by getting the release notes from somewhere else and using the `releaseNotesFile` key
          isDraft: false
          isPreRelease: false
          assets: '$(Build.ArtifactStagingDirectory)/**'
          assetUploadMode: 'replace' # Don't delete previously uploaded assets (default)

  - job: Publish_Docs
    dependsOn:
      - Build_Docs
    displayName: Deploy API Documentation to GitHub
    pool:
      vmImage: "ubuntu-16.04"
    condition: in(variables['Build.SourceBranch'], 'refs/heads/master')
    steps:
      - checkout: self
      - task: DownloadPipelineArtifact@2
        inputs:
          artifactName: api-docs
          targetPath: $(System.DefaultWorkingDirectory)/api-docs
      - bash: |
          git config --global user.email "bot@wasmer.io"
          git config --global user.name "wasmerbot"
          make docs-publish
        env:
          RUST_DOCS_DIR: $(Pipeline.Workspace)/api-docs
          GITHUB_DOCS_TOKEN: $(GITHUB_DOCS_TOKEN)
          SOURCE_VERSION: $(Build.SourceVersion)

# We only run the pipelines on PRs to Master
pr:
  - master

# Otherwise, we test in any of these branches (master or bors related)
trigger:
  - master
  - staging
  - trying
  - refs/tags/*