aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/action.yml
blob: 047280486870ffb307a687e13ec017a10b4f61e4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
name: Visual Studio shell
description: Set up Visual Studio paths and environment variables
inputs:
  arch:
    description: 'Target architecture'
    required: false
    default: 'x64'
runs:
  using: composite
  steps:
    - run: |
        function Locate-VSWhere {
            $path = Get-Command 'vswhere' -ErrorAction SilentlyContinue
            if ($path) {
                $path.Path
            } else {
                Join-Path ${env:ProgramFiles(x86)} 'Microsoft Visual Studio' 'Installer' 'vswhere'
            }
        }

        function Locate-VS {
            # vswhere doesn't search for Build Tools by default, God knows why.
            # https://github.com/microsoft/vswhere/issues/22
            $products = 'Community','Professional','Enterprise','BuildTools' | %{ "Microsoft.VisualStudio.Product.$_" }
            $vswhere = Locate-VSWhere
            & $vswhere -products $products -latest -format json | ConvertFrom-Json
        }

        function Import-PS {
            # VS 2019 includes Microsoft.VisualStudio.DevShell.dll, which does
            # what we want.
            #
            # It also includes Launch-VsDevShell.ps1, which sort of does the
            # same thing this function does, but it always sets up 32-bit
            # shell, which is stupid.  I use the same workaround as in
            # https://developercommunity.visualstudio.com/idea/943058/x64-developer-powershell-for-vs-2019.html

            param(
                [Parameter(Mandatory=$true)]
                [object] $info
            )

            $tools_path = Join-Path $info.installationPath 'Common7' 'Tools'
            $module_name = 'Microsoft.VisualStudio.DevShell.dll'
            $module_path = Join-Path $tools_path $module_name

            if (!(Test-Path $module_path -Type Leaf)) {
                $module_path = Join-Path $tools_path 'vsdevshell' $module_name
            }

            if (!(Test-Path $module_path -Type Leaf)) {
                throw "Couldn't find module '$module_name'"
            }

            Import-Module $module_path
            Enter-VsDevShell -VsInstanceId $info.instanceId -SkipAutomaticLocation -DevCmdArguments '-arch=${{ inputs.arch }} -no_logo'
        }

        function Import-CMD {
            # For Visual Studio 2017, there's no Microsoft.VisualStudio.DevShell.dll,
            # so we have to work around that.  One workaround I found here:
            # https://github.com/microsoft/vswhere/issues/150

            param(
                [Parameter(Mandatory=$true)]
                [object] $info
            )

            $tools_path = Join-Path $info.installationPath 'Common7' 'Tools'
            $script_name = 'VsDevCmd.bat'
            $script_path = Join-Path $tools_path $script_name

            if (!(Test-Path $script_path -Type Leaf)) {
                throw "Couldn't find script '$script_name'"
            }

            $json = $(& "${env:COMSPEC}" /s /c "`"$script_path`" -arch=${{ inputs.arch }} -no_logo && pwsh -Command `"Get-ChildItem env: | ConvertTo-Json`"")
            if ($LASTEXITCODE -ne 0) {
                throw $json
            } else {
                $json | ConvertFrom-Json | %{
                    $k, $v = $_.Key, $_.Value
                    Set-Content "env:$k" "$v"
                }
            }
        }

        if ('${{ runner.os }}' -ne 'Windows') {
            echo 'Not going to set up a Visual Studio shell on ${{ runner.os }}'
        } else {
            $old_values = @{}
            Get-ChildItem env: | %{ $old_values.Add($_.Name, $_.Value) }

            $info = Locate-VS
            try {
                Import-PS $info
            } catch {
                echo $_
                Import-CMD $info
            }

            $new_values = @{}
            Get-ChildItem env: | %{ $new_values.Add($_.Name, $_.Value) }

            # Some diagnostics as to which exact variables were modified follows:
            echo '----------------------------------------------------------------'
            echo 'New variables'
            echo '----------------------------------------------------------------'
            $new_values.GetEnumerator() | where { -not $old_values.ContainsKey($_.Name) } | Format-List

            echo '----------------------------------------------------------------'
            echo 'Modified variables'
            echo '----------------------------------------------------------------'
            $new_values.GetEnumerator() | where { $old_values.ContainsKey($_.Name) -and $old_values[$_.Name] -ne $_.Value } | Format-List

            # Update the current environment:
            Get-ChildItem env: | %{ echo "$($_.Name)=$($_.Value)" >> $env:GITHUB_ENV }
        }
      shell: pwsh
branding:
  icon: star
  color: green