GitLab CI and MsBuild (with tests)
As an addendum to Jürgen Steinblock answer, I would like to suggest a simplier alternative for the test stage script:
variables:
SOLUTION_DIR: "MySolution"
BUILD_DIR: "Release"
TESTER: "vstest.console.exe" # or "mstest.exe /testcontainer:"
before_script:
- call "%VS120COMNTOOLS%\vsvars32" # import in path tools like msbuild, mstest, etc using VS script
test:
stage: test
script:
- for /f %%F in ('dir /s /b %SOLUTION_DIR%\%BUILD_DIR%\*Tests.dll') do set dllPath=%%F
- "%TESTER% %dllPath%"
This will launch testing on all test project binaries found which ends by convention with *Tests.dll
in the build directory. This has the advantage of not using an intermediate file.
Since things have changed a bit since this question has been opened (and now MS supports core/linux docker deployments right in VS), I thought I'd share my solution.
# Default image is docker:stable
image: docker:stable
# Define deployment stages
stages:
- Test
- Build
# We use docker-in-docker (dind) for building docker images (build stage)
services:
- docker:dind
# Run unit test on dotnet core sdk image
test:
stage: Test
image: mcr.microsoft.com/dotnet/core/sdk:3.1
script:
- dotnet restore "${CI_PROJECT_DIR}/Project.Tests/Project.Tests.csproj"
- dotnet test "${CI_PROJECT_DIR}/Project.Tests/Project.Tests.csproj"
tags:
- docker
only:
- master
# Only build when testing passes, build using Dockerfile/dind
build:
stage: Build
# Print docker instance details for logging/diagnosing
before_script:
- docker info
- docker login registry.gitlab.com -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD}
script:
- docker build -t ${CI_REGISTRY}/${CI_PROJECT_PATH}:latest .
- docker push ${CI_REGISTRY}/${CI_PROJECT_PATH}:latest
after_script:
- docker logout ${CI_REGISTRY}
tags:
- docker
only:
- master
when: on_success
This should run the MS Unit tests on your solution, and if the tests pass, create an image from them (provided you have a Dockerfile next to the gitlab-ci.yml file). Ignore the build stage if you're only looking to perform unit testing automatically on commits.
This is what I used eventually. It runs all the *Tests.Dll in a single run.
dir /s /b *.Tests.dll | findstr /r bin\\Debug > testcontainers.txt
for /f %%x in (testcontainers.txt) do set list=!list! %%x
set list=%list:~1%
vstest.console.exe %list%
Apparently there is no simple msbuild example but this should get you started:
variables:
Solution: MySolution.sln
before_script:
- "echo off"
- 'call "%VS120COMNTOOLS%\vsvars32.bat"'
# output environment variables (usefull for debugging, propably not what you want to do if your ci server is public)
- echo.
- set
- echo.
stages:
- build
- test
- deploy
build:
stage: build
script:
- echo building...
- 'msbuild.exe "%Solution%"'
except:
- tags
test:
stage: test
script:
- echo testing...
- 'msbuild.exe "%Solution%"'
- dir /s /b *.Tests.dll | findstr /r Tests\\*\\bin\\ > testcontainers.txt
- 'for /f %%f in (testcontainers.txt) do mstest.exe /testcontainer:"%%f"'
except:
- tags
deploy:
stage: deploy
script:
- echo deploying...
- 'msbuild.exe "%Solution%" /t:publish'
only:
- production
Figuring out which tests to run is a bit tricky. My convention is that every project has a folder tests in which the test projects are named after the schema MyProject.Core.Tests (for a project called MyProject.Core)
Just as a first feedback towards gitlab-ci
I like the simplicity and the source control integration. But I would like to be able to modify the script before execution (especially while changing the script) but I could imaging to rerun a specific commit and inject variables or change the script (I can do that with teamcity). Or even ignore a failed test and rerun the script again (I do that a lot with teamcity). I know gitlab-ci does not know anything about my tests I just have a command line that returns an error code.