# This is the Azure Pipelines configuration is also used to create the
# precompiled release archives that are made available at <https://rakudo.org>.
#
# To trigger a build, go to <https://dev.azure.com/infra0037/raku/...> and
# manually start a run of this pipeline.
#
# The following pipeline variables are required:
#
# BUILD_PRECOMP_RELEASE: Set this to "yes".
# RELEASE_URL: Release archive to build. e.g. "https://rakudo.org/dl/rakudo/rakudo-2020.05.tar.gz"
# VERSION: The version that you are building. e.g. "2020.05"
# REVISION: Usually "01"
#

trigger:
- master

pr:
- master

variables:
  # Turn this Powershell console into a developer powershell console.
  # https://intellitect.com/enter-vsdevshell-powershell/
  PWSH_DEV: |
    $installPath = &"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -latest -property installationpath
    $devShell    = &"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -latest -find **\Microsoft.VisualStudio.DevShell.dll
    Import-Module $devShell
    Enter-VsDevShell -VsInstallPath $installPath -SkipAutomaticLocation -DevCmdArguments "-arch=amd64"
  RAKUDO_CHECKOUT_TYPE: "rev-$(Build.SourceVersion)-selfrepo"
  NQP_CHECKOUT_TYPE: downstream
  MOAR_CHECKOUT_TYPE: downstream

stages:
- stage: Test
  condition: ne( variables['BUILD_PRECOMP_RELEASE'], 'yes' )
  jobs:
    # Keep the job and matrix entry names as short as possible as the webinterface
    # leaves little space for the name.
    - job: T
      strategy:
       matrix:
         Win_MVM:
           IMAGE_NAME: 'windows-2019'
           RAKUDO_OPTIONS: ''
           NQP_OPTIONS: '--backends=moar'
           MOAR_OPTIONS: ''
         Win_JVM:
           IMAGE_NAME: 'windows-2019'
           BACKEND: 'JVM'
           MOAR_CHECKOUT_TYPE: 'none'
           RAKUDO_OPTIONS: ''
           NQP_OPTIONS: '--backends=jvm'
           MOAR_OPTIONS: ''
         Win_MVM_relocatable:
           IMAGE_NAME: 'windows-2019'
           RELOCATABLE: 'yes'
           RAKUDO_OPTIONS: '--relocatable'
           NQP_OPTIONS: '--backends=moar --relocatable'
           MOAR_OPTIONS: '--relocatable'

         Mac_MVM:
           IMAGE_NAME: 'macOS-12'
           RAKUDO_OPTIONS: ''
           NQP_OPTIONS: '--backends=moar'
           MOAR_OPTIONS: ''
         Mac_JVM:
           IMAGE_NAME: 'macOS-12'
           BACKEND: 'JVM'
           MOAR_CHECKOUT_TYPE: 'none'
           RAKUDO_OPTIONS: ''
           NQP_OPTIONS: '--backends=jvm'
           MOAR_OPTIONS: ''
         Mac_MVM_reloc:
           IMAGE_NAME: 'macOS-12'
           RELOCATABLE: 'yes'
           RAKUDO_OPTIONS: '--relocatable'
           NQP_OPTIONS: '--backends=moar --relocatable'
           MOAR_OPTIONS: '--relocatable'

         Lin_MVM:
           IMAGE_NAME: 'ubuntu-20.04'
           RAKUDO_OPTIONS: ''
           NQP_OPTIONS: '--backends=moar'
           MOAR_OPTIONS: ''
         Lin_JVM:
           IMAGE_NAME: 'ubuntu-20.04'
           BACKEND: 'JVM'
           MOAR_CHECKOUT_TYPE: 'none'
           RAKUDO_OPTIONS: ''
           NQP_OPTIONS: '--backends=jvm'
           MOAR_OPTIONS: ''
         Lin_MVM_reloc:
           IMAGE_NAME: 'ubuntu-20.04'
           RELOCATABLE: 'yes'
           RAKUDO_OPTIONS: '--relocatable'
           NQP_OPTIONS: '--backends=moar --relocatable'
           MOAR_OPTIONS: '--relocatable'

         Lin_MVM_spec:
           IMAGE_NAME: 'ubuntu-20.04'
           SPECTEST_ONLY: 'yes'
           RAKUDO_OPTIONS: ''
           NQP_OPTIONS: '--backends=moar'
           MOAR_OPTIONS: ''

      pool:
        vmImage: $(IMAGE_NAME)
      workspace:
        clean: all
      timeoutInMinutes: 180
      steps:

        - pwsh: |
            # Windows has a maximum PATH variable length of 2048 (depending on
            # how it's accessed). The length of PATH in AzureCI is already
            # really tight. We'll run into the limit when we add Java and the
            # MS BuildTools to the path.
            # To work around this, we remove a bunch of stuff we won't need
            # from PATH here.
            $shortened_path = "$(PATH)" -replace ';[^;]*(SeleniumWebDrivers|SQL Server|Mercurial|Amazon|mysql|\\sbt\\|NSIS|Windows Performance Toolkit|php|Subversion)[^;]*(?=(;|$))', ''
            echo "##vso[task.setvariable variable=PATH]$shortened_path"
          displayName: "Shorten PATH on Windows"
          condition: eq( variables['Agent.OS'], 'Windows_NT' )

        - script: |
            echo "##vso[task.setvariable variable=JAVA_HOME]$(JAVA_HOME_11_X64)"
            echo "##vso[task.setvariable variable=PATH]$(JAVA_HOME_11_X64)/bin:$(PATH)"
          displayName: "Set java version (non-Windows)"
          condition: and(succeeded(), eq( variables['BACKEND'], 'JVM'), ne( variables['Agent.OS'], 'Windows_NT' ) )
        - pwsh: |
            echo "##vso[task.setvariable variable=JAVA_HOME]$(JAVA_HOME_11_X64)"
            echo "##vso[task.setvariable variable=PATH]$(JAVA_HOME_11_X64)\bin;$(PATH)"
          displayName: "Set java version (Windows)"
          condition: and(succeeded(), eq( variables['BACKEND'], 'JVM'), eq( variables['Agent.OS'], 'Windows_NT' ) )

        - checkout: self
          path: selfrepo
          displayName: Checkout script repo

        - script: perl selfrepo/tools/build/checkout-repos-for-test.pl $(RAKUDO_CHECKOUT_TYPE) $(NQP_CHECKOUT_TYPE) $(MOAR_CHECKOUT_TYPE)
          workingDirectory: $(Pipeline.Workspace)
          condition: and(succeeded(), ne(variables['BACKEND'], 'JVM'))
          displayName: Checkout repositories (MoarVM)
        - script: perl selfrepo/tools/build/checkout-repos-for-test.pl $(RAKUDO_CHECKOUT_TYPE) $(NQP_CHECKOUT_TYPE) none
          workingDirectory: $(Pipeline.Workspace)
          condition: and(succeeded(), eq(variables['BACKEND'], 'JVM'))
          displayName: Checkout repositories (JVM)

        # Build MoarVM
        - script: |
            perl Configure.pl --prefix=../install $(MOAR_OPTIONS)
            make install
          workingDirectory: '$(Pipeline.Workspace)/MoarVM'
          condition: and(succeeded(), ne( variables['Agent.OS'], 'Windows_NT' ), ne( variables['BACKEND'], 'JVM') )
          displayName: Build MoarVM
        - pwsh: |
            ${{ variables.PWSH_DEV }}
            perl Configure.pl --prefix=..\install $(MOAR_OPTIONS)
            nmake install
          failOnStderr: false
          workingDirectory: '$(Pipeline.Workspace)/MoarVM'
          condition: and(succeeded(), eq( variables['Agent.OS'], 'Windows_NT' ), ne( variables['BACKEND'], 'JVM') )
          displayName: Build MoarVM (Windows)

        # Build NQP
        - script: |
            perl Configure.pl --prefix=../install $(NQP_OPTIONS)
            make install
          workingDirectory: '$(Pipeline.Workspace)/nqp'
          condition: and(succeeded(), ne( variables['Agent.OS'], 'Windows_NT' ))
          displayName: Build NQP
        - pwsh: |
            ${{ variables.PWSH_DEV }}
            perl Configure.pl --prefix=..\install $(NQP_OPTIONS)
            nmake install
          failOnStderr: false
          workingDirectory: '$(Pipeline.Workspace)/nqp'
          condition: and(succeeded(), eq( variables['Agent.OS'], 'Windows_NT' ))
          displayName: Build NQP (Windows)

        # Build Rakudo
        - script: |
            perl Configure.pl --prefix=../install $(RAKUDO_OPTIONS)
            make install
          workingDirectory: '$(Pipeline.Workspace)/rakudo'
          condition: and(succeeded(), ne( variables['Agent.OS'], 'Windows_NT' ))
          displayName: Build Rakudo
        - pwsh: |
            ${{ variables.PWSH_DEV }}
            perl Configure.pl --prefix=..\install $(RAKUDO_OPTIONS)
            nmake install
          failOnStderr: false
          workingDirectory: '$(Pipeline.Workspace)/rakudo'
          condition: and(succeeded(), eq( variables['Agent.OS'], 'Windows_NT' ))
          displayName: Build Rakudo (Windows)

        # TODO: Should use "install moved" instead of "install-moved". But `prove` currently fails with an executable path that contains a space.
        - script: mv install install-moved
          workingDirectory: $(Pipeline.Workspace)
          condition: and(succeeded(), eq( variables['RELOCATABLE'], 'yes' ), ne( variables['Agent.OS'], 'Windows_NT' ) )
          displayName: Move installation
        - pwsh: mv install install-moved
          workingDirectory: $(Pipeline.Workspace)
          condition: and(succeeded(), eq( variables['RELOCATABLE'], 'yes' ), eq( variables['Agent.OS'], 'Windows_NT' ) )
          displayName: Move installation (Windows)

        # Test Rakudo
        - script: prove -e ../install/bin/perl6 -vlr t
          workingDirectory: '$(Pipeline.Workspace)/rakudo'
          condition: and(succeeded(), ne( variables['RELOCATABLE'], 'yes' ), ne( variables['BACKEND'], 'JVM'), ne( variables['Agent.OS'], 'Windows_NT' ), ne( variables['SPECTEST_ONLY'], 'yes' ) )
          displayName: Test Rakudo
        - pwsh: |
            ${{ variables.PWSH_DEV }}
            prove -e ..\install\bin\perl6 -vlr t
          workingDirectory: '$(Pipeline.Workspace)/rakudo'
          condition: and(succeeded(), ne( variables['RELOCATABLE'], 'yes' ), ne( variables['BACKEND'], 'JVM'), eq( variables['Agent.OS'], 'Windows_NT' ) )
          displayName: Test Rakudo (Windows)
        - script: prove -e ../install-moved/bin/perl6 -vlr t
          workingDirectory: '$(Pipeline.Workspace)/rakudo'
          condition: and(succeeded(), eq( variables['RELOCATABLE'], 'yes' ), ne( variables['BACKEND'], 'JVM'), ne( variables['Agent.OS'], 'Windows_NT' ) )
          displayName: Test Rakudo (relocated)
        - pwsh: |
            ${{ variables.PWSH_DEV }}
            prove -e ..\install-moved\bin\perl6 -vlr t
          workingDirectory: '$(Pipeline.Workspace)/rakudo'
          condition: and(succeeded(), eq( variables['RELOCATABLE'], 'yes' ), ne( variables['BACKEND'], 'JVM'), eq( variables['Agent.OS'], 'Windows_NT' ) )
          displayName: Test Rakudo (relocated, Windows)

        # Run spectest
        - script: make TEST_JOBS=2 m-spectest
          workingDirectory: '$(Pipeline.Workspace)/rakudo'
          condition: and(succeeded(), ne( variables['RELOCATABLE'], 'yes' ), ne( variables['BACKEND'], 'JVM'), ne( variables['Agent.OS'], 'Windows_NT' ), eq( variables['SPECTEST_ONLY'], 'yes' ) )
          displayName: Run spectest

        - publish: $(Pipeline.Workspace)/install-moved
          condition: and(succeeded(), eq( variables['RELOCATABLE'], 'yes' ), ne( variables['BACKEND'], 'JVM') )
          displayName: Publish build artifact

- stage: Build_Precomp_Release
  condition: eq( variables['BUILD_PRECOMP_RELEASE'], 'yes' )
  jobs:
    - job: linux
      displayName: Linux x86_64 build
      pool:
        vmImage: 'ubuntu-20.04'
      container:
        image: centos:7
        options: "--name raku-build-container -v /usr/bin/docker:/tmp/docker:ro"
      workspace:
        clean: all
      steps:
        - script: /tmp/docker exec -t -u 0 raku-build-container sh -c "yum -y update && yum -y install sudo"
          displayName: Set up sudo (see https://github.com/microsoft/azure-pipelines-agent/issues/2043)

        - checkout: self
          path: source
          displayName: Checkout repository

        - script: $(Agent.BuildDirectory)/source/tools/build/binary-release/build-linux.sh
          failOnStderr: false
          displayName: Run build script

        - publish: rakudo-linux.tar.gz
          artifact: rakudo-linux

    - job: macos
      displayName: MacOS x86_64 build
      pool:
        vmImage: 'macOS-12'
      workspace:
        clean: all
      steps:
        - checkout: self
          path: source

        - script: $(Agent.BuildDirectory)/source/tools/build/binary-release/build-macos.sh
          failOnStderr: false
          displayName: Run build script

        - publish: rakudo-macos.tar.gz
          artifact: rakudo-macos

    - job: windows
      displayName: Windows x86_64 build
      pool:
        vmImage: 'windows-2019'
      workspace:
        clean: all
      steps:
        - checkout: self
          path: source

        # Turn this Powershell console into a developer powershell console.
        # https://intellitect.com/enter-vsdevshell-powershell/
        - pwsh: |
            $installPath = &"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -latest -property installationpath
            $devShell    = &"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -latest -find **\Microsoft.VisualStudio.DevShell.dll
            Import-Module $devShell
            Enter-VsDevShell -VsInstallPath $installPath -SkipAutomaticLocation -DevCmdArguments "-arch=amd64"
            $(Agent.BuildDirectory)/source/tools/build/binary-release/build-windows.ps1
          failOnStderr: false
          displayName: Run build script

        - publish: rakudo-win.zip
          artifact: rakudo-win
          
        - publish: rakudo-win.msi
          artifact: rakudo-win-msi

    - job: zip
      displayName: Package results
      dependsOn:
      - linux
      - macos
      - windows
      pool:
        vmImage: 'ubuntu-20.04'
      workspace:
        clean: all
      steps:
      - checkout: none

      - download: current
        artifact: rakudo-linux
        displayName: Download Linux build artifacts

      - download: current
        artifact: rakudo-macos
        displayName: Download MacOS build artifacts

      - download: current
        artifact: rakudo-win
        displayName: Download Windows binary build
        
      - download: current
        artifact: rakudo-win-msi
        displayName: Download Windows msi

      - script: |
          OUT_DIR=rakudo-builds-$(VERSION)-$(REVISION)
          mkdir $OUT_DIR
          cp $(Pipeline.Workspace)/rakudo-linux/rakudo-linux.tar.gz $OUT_DIR/rakudo-moar-$(VERSION)-$(REVISION)-linux-x86_64-gcc.tar.gz
          cp $(Pipeline.Workspace)/rakudo-macos/rakudo-macos.tar.gz $OUT_DIR/rakudo-moar-$(VERSION)-$(REVISION)-macos-x86_64-clang.tar.gz
          cp $(Pipeline.Workspace)/rakudo-win/rakudo-win.zip        $OUT_DIR/rakudo-moar-$(VERSION)-$(REVISION)-win-x86_64-msvc.zip
          cp $(Pipeline.Workspace)/rakudo-win-msi/rakudo-win.msi    $OUT_DIR/rakudo-moar-$(VERSION)-$(REVISION)-win-x86_64-msvc.msi
          tar -czf rakudo-moar-builds-$(VERSION)-$(REVISION).tar.gz $OUT_DIR

      - publish: rakudo-moar-builds-$(VERSION)-$(REVISION).tar.gz
        artifact: build-result
