10

I am using Azure Pipelines to build a Rakudo binary for Raku (previously aka Perl 6) in Windows.

This is my azure-pipelines.yml file:

jobs:
- job: Windows
  pool:
    vmImage: 'vs2017-win2016'
  steps:
    - bash: |
        mkdir -p $(Build.SourcesDirectory)/rakudo-win
        curl -L https://github.com/rakudo/rakudo/releases/download/2019.07.1/rakudo-2019.07.1.tar.gz | tar xz
        mv rakudo-2019.07.1 rakudo
        cd rakudo
        C:/Strawberry/perl/bin/perl Configure.pl --gen-moar --gen-nqp --backends=moar --prefix=$(Build.SourcesDirectory)/rakudo-win
        make
        make install

    - bash: |
        echo "##vso[task.prependpath]$(Build.SourcesDirectory)/rakudo-win/bin"

    - bash: |
        perl6 -v

The pipeline script builds perl6 binary fine inside $(Build.SourcesDirectory)/rakudo-win/bin folder. There is indeed perl6.exe inside $(Build.SourcesDirectory)/rakudo-win/bin. To make it available, I set the path by prepending it in the bash script. But when I try to run command perl6 -v, the build fails at this step.

I searched for similar issues in SO here, here, here.

Still I could not solve my issue. Any help how to make perl6 binary available at PATH?

EDITED

Next thing I did was create another .yml script as follows:

jobs:
- job: Windows
  pool:
    vmImage: 'vs2017-win2016'
  steps:
    - script: |
        call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
    - pwsh: |
        mkdir -p C:\rakudo-win
        Invoke-WebRequest -Uri "https://github.com/rakudo/rakudo/releases/download/2019.07.1/rakudo-2019.07.1.tar.gz" -OutFile "rakudo.tar.gz"
        tar -xvf .\rakudo.tar.gz
        cd rakudo-2019.07.1
        C:\Strawberry\perl\bin\perl Configure.pl --gen-moar --gen-nqp --backends=moar --prefix=C:\rakudo-win
        make
        make install
    - pwsh: |
        $oldpath = (Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH).path
        $newpath = "C:\rakudo-win\bin;$oldpath" 
        Set-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH -Value $newpath
    - script: |
        SET PATH=C:\rakudo-win\bin;%PATH%

    - script: |
        perl6 -v

and tried changing PATH twice once in powershell and another in cmdline. But still it throws following error:

'perl6' is not recognized as an internal or external command,
operable program or batch file.

Any help?

Suman Khanal
  • 3,079
  • 1
  • 17
  • 29
  • 1
    This is just a linear list of commands, why not use a batch file? – Holli Oct 06 '19 at 12:30
  • I'm not sure, but I think on Win, the directory MUST be `c:\rakudo`. At least that used to be the case. – Holli Oct 06 '19 at 12:33
  • Yes I can set the directory as `c:\rakudo`, in that case I need to have `C:\rakudo\bin` in `PATH`, so that I can use `perl6` in subsequent downstream `script`s. – Suman Khanal Oct 06 '19 at 13:35

3 Answers3

8

The best method I have found for setting the PATH for subsequent tasks in Azure Pipelines is by using the logging command syntax mentioned in the first of the three SO links you looked at. Since you are using PowerShell in your updated yaml pipeline, the command would be:

Write-Host "##vso[task.prependpath]$(Build.SourcesDirectory)/rakudo-win/bin"

Note that this only applies to subsequent tasks, if you try outputting the PATH variable in the current task it will not have updated.

shane_b
  • 81
  • 1
  • 2
3

In fact, you are very close to the correct solution. Your second powershell task has set the PATH successfully. You can add another separate task to print out the system PATH value to verify this.

- pwsh: |
    $NewPathInRegistry = (Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH).path
    Write-Host $NewPathInRegistry

enter image description here


To set the PATH programmatically, you can not use set command, this command can indeed set the environment variable PATH, but the disadvantage of set is the new PATH value is only available in the current command line terminal, it does not actually been added into the System Variable. That's why you were getting an unrecognized error in the next script step.

To permanently add the directory to environment variable PATH so that it can work for next others steps, you need use setx or add them into Registry by using reg add. But the usage of setx has limitation that the PATH value max to 1024 characters. So, here the best solution is updating PATH by modifying the Registry value.

BUT, updating Registry still has another issue, you must kill current process and run one new process to run perl6 so that it can read the new available Registry setting.

If run stop-process in Azure devops pipeline, it will make the task failed with exit code -1. This is the expected exit code, so you can set the continueOnError: true to step so that the next steps can continue.

Mengdi Liang
  • 17,577
  • 2
  • 28
  • 35
1

why not just do this:

- script: |
  PATH=$BUILD_SOURCESDIRECTORY/rakudo-win/bin:$PATH perl6 -v
4c74356b41
  • 69,186
  • 6
  • 100
  • 141
  • Once `perl6` is in PATH, I want to run these commands: git clone https://github.com/ugexe/zef.git, cd zef, perl6 -I. bin/zef install . – Suman Khanal Oct 06 '19 at 11:51
  • then you could set path with `export PATH=$BUILD_SOURCESDIRECTORY/rakudo-win/bin:$PATH` and run those commands – 4c74356b41 Oct 06 '19 at 16:20
  • 1
    Sorry its not working. The error that it throws with last script in my `.yml` is `/d/a/_temp/bd6b25db-74ec-40a1-90f3-0d0ef477f3df.sh: line 1: perl6: command not found`. – Suman Khanal Oct 15 '19 at 14:20