From 3223af928ba01b91837b37ef8257e1057fe91ab1 Mon Sep 17 00:00:00 2001 From: Egor Tensin Date: Fri, 13 Nov 2020 11:46:02 +0300 Subject: initial commit --- .gitattributes | 1 + .github/workflows/test.yml | 54 ++++++++++++++++++++ LICENSE.txt | 21 ++++++++ action.yml | 119 +++++++++++++++++++++++++++++++++++++++++++++ foo.cpp | 6 +++ 5 files changed, 201 insertions(+) create mode 100644 .gitattributes create mode 100644 .github/workflows/test.yml create mode 100644 LICENSE.txt create mode 100644 action.yml create mode 100644 foo.cpp diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..176a458 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..e5087e6 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,54 @@ +name: Test + +on: + push: + pull_request: + schedule: + # Weekly, at 5:45 AM on Friday (somewhat randomly chosen). + - cron: '45 6 * * 5' + workflow_dispatch: + +jobs: + test: + strategy: + fail-fast: false + matrix: + os: ['windows-2019', 'windows-2016'] + arch: ['x86', 'x64'] + + include: + # Prettier run names. + - os: windows-2019 + name: VS 2019 + - os: windows-2016 + name: VS 2017 + + runs-on: '${{ matrix.os }}' + + name: '${{ matrix.name }} / ${{ matrix.arch }}' + + defaults: + run: + shell: pwsh + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: cl.exe shouldn't be found + run: | + $(Get-Command cl -ErrorAction SilentlyContinue) -and $(throw "cl.exe was found!") + + - name: Set up Visual Studio shell + uses: ./ + with: + arch: '${{ matrix.arch }}' + + - name: cl.exe should be found now + run: | + $(Get-Command cl -ErrorAction SilentlyContinue) -or $(throw "cl.exe wasn't found!") + + - name: Build foo.exe + run: | + cl.exe /EHsc foo.cpp + ./foo.exe diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..ab8c3ff --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Egor Tensin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/action.yml b/action.yml new file mode 100644 index 0000000..a418c44 --- /dev/null +++ b/action.yml @@ -0,0 +1,119 @@ +name: Set up 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" + } + } + } + + $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 diff --git a/foo.cpp b/foo.cpp new file mode 100644 index 0000000..b9d3132 --- /dev/null +++ b/foo.cpp @@ -0,0 +1,6 @@ +#include + +int main() { + std::cout << "foo\n"; + return 0; +} -- cgit v1.2.3