週末にGitHub Actionsを使ってMSBuildするやり方を色々調べつつ、色々触ってみたのでまとめました。
リポジトリ: https://github.com/yuta0428/msbuild-actions-sample/blob/master/.github/workflows/msbuild.yml
GitHub Actions自体のセットアップや詳細な解説は省いてます。(というか自分もまだあまり理解してない)
👇らへん見つつ試しました。
前提
- Visual Studio 2019 Community(16.3.9)で作成したWindowsデスクトップアプリケーション(C++)
- GitHub Actions v2(2019/11/17時点)
コード
- 最小コードとしてはこれで動きます。
- リポジトリにある
msbuild.yml
は後述する色々を試した結果です。
name: MSBuild
on: push
jobs:
build:
name: MSBuild
runs-on: windows-latest
steps:
- uses: actions/checkout@v1
- name: Setup MSBuild.exe
uses: warrenbuckley/Setup-MSBuild@v1
- name: MSBuild
run: msbuild msbuild_actions_sample.sln
shell: cmd
解説
- Windows runnersにVS2019 Enterprise版が入っているため、実行環境は
runs-on: windows-latest
を指定で問題なかったです。 - VS2017を使用したい、開発環境とバージョンを合わせたい場合などは_self-hosted runner_を使用すればいいです。
- privateリポジトリでやること。
- 参考:GitHub Actions をローカル環境で実行したい(Self-hosted runners)
# runs-on: windows-latest
runs-on: self-hosted
- デフォルトでは
msbuild
コマンドへのPATHが通ってないので通す必要があります。 - それをやってくれるのが
uses: warrenbuckley/Setup-MSBuild@v1
です。- 内部的には_vswhere.exe_をダウンロードしてきて_MSBuild.exe_を探してPATHに追加してるだけです。
- https://github.com/warrenbuckley/Setup-MSBuild/blob/master/src/main.ts
- なので、自前で建ててるなら直接PATH通しておいた方が速いです。
以下+αでやったこと。できなかったこと。
生成結果をアップロードする / upload-artifact
-
uses: actions/upload-artifact@v1@
でできました- デフォルトだと_x64/Debug_みたいなパスになるので
-p:OutDir="out/
を指定しました。
- デフォルトだと_x64/Debug_みたいなパスになるので
- name: MSBuild
run: msbuild msbuild_actions_sample.sln -p:OutDir="out/"
shell: cmd
- name: Upload artifact
uses: actions/upload-artifact@v1
with:
name: build-result
path: ./msbuild_actions_sample/out/
Self-hosted runnersを追加する
- _Self-hosted runners_を追加すると、ワークスペースに
actions-runner
というフォルダが追加されます。 - このフォルダの中に追加時に設定した作業ディレクトリ(この場合だと
work
)が作成され、actions packageやビルド実行結果などが追加されます。
.
└── actions-runner
├── _diag
├── actions-runner-win-x64-2.160.2.zip
├── bin
├── config.cmd
├── externals
├── run.cmd
└── work
- 差分として余計なので.gitignoreに追加していいと思います。(言及されてるの見つけれなかったので参考程度に)
+ actions-runner/
dotnet msbuildでもできるのか
- 必要な依存関係をちゃんと解決すればできるのか検証してみた。
- 結論:エラーを解決できなかった
- コード:https://github.com/yuta0428/msbuild-actions-sample/blob/master/.github/workflows/dotnetmsbuild.yml
- Windows runnersに.NET Core 3.0が既に入ってるので
dotnet msbuild
にしただけ。
- Windows runnersに.NET Core 3.0が既に入ってるので
- 変数設定が必要で、検証時は
runs-on: self-hosted
にしてlocal環境でごちゃごちゃやってました
環境
> dotnet --version
3.0.100
VCTargetsPathなくて死ぬ
...\msbuild-actions-sample\msbuild_actions_sample\msbuild_actions_sample.vcxproj(28,3): error MSB4019: The imported project "d:\Microsoft.Cpp.Default.props" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.
=> VCTargetsPathにC:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160
を設定
MSB4018: System.TypeLoadException: Could not load type 'Microsoft.Build.Utilities.CanonicalTrackedOutputFiles' from assembly 'Microsoft.Build.Utilities.Core...で死ぬ
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(185,5): error MSB4018: "GetOutOfDateItems" タスクが予期せずに失敗しました。
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(185,5): error MSB4018: System.TypeLoadException: Could not load type 'Microsoft.Build.Utilities.CanonicalTrackedOutputFiles' from assembly 'Microsoft.Build.Utilities.Core, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(185,5): error MSB4018: at Microsoft.Build.CPPTasks.GetOutOfDateItems.Execute()
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(185,5): error MSB4018: at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute()
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(185,5): error MSB4018: at Microsoft.Build.BackEnd.TaskBuilder.ExecuteInstantiatedTask(ITaskExecutionHost taskExecutionHost, TaskLoggingContext taskLoggingContext, TaskHost taskHost, ItemBucket bucket, TaskExecutionMode howToExecuteTask)
=> VCToolsInstallDir
とWindowsSDKDir
が無いよWarning出てたけどそれ消しても解決できなかった。よく分かってないので諦めました。
所感
コマンドとか一式入った実行環境が一通り揃っているので簡単にセットアップできる
- ありがたい。細かいことやろうとするなら自前で建てればいいので最悪なんとかなる。
- 料金もprivateリポでも一定時間(月2000分~)までは無料なのでとりあえず試せる。
local executeができないのが辛い
- (自分が発見できなかっただけでもしかしたらあるのかもですが)
- 基本的にpushして確認するので、動いてほしくないの別のworkflowも発火して無駄にビルド時間取られます。
- そのため、基本稼働させるworkflowにはbranch filterを設定してあげておいたよさそうに感じました。
-
master
、develop
、feaure/*
とかで制限しておく。 - テスト用に試したいときは該当しないブランチで作業する。
- 参考:GitHub Actionsのワークフロー構文#onpushpull_requestbranchestags
-
workflowをvalidateできないの辛い
- (自分が発見できなかっただけでry)
- 構文チェックないのでsyntax errorのままpushして失敗することあります
- 自分はGitHub上で_Actions_タブから_Set up a workflow yourself_を押して、新規ファイル追加画面にコピペして確認してました。(そこならsyntax checkしてくれるので)
個人的にはCircleCIより使い勝手よくて楽だったのでもっと使っていきたいですね。
うまくいかない場合はコメント等で指摘して頂けると助かります🙇