Visual Studio code editor: Eight tips for using GitLab VS Code
Learn how to use the Visual Studio code editor more efficiently and meet some of the GitLab contributors that made these new features happen.
Tomas Vik
As a software engineer, I spend a significant portion of my day in the Visual Studio code editor. Since I started maintaining the officially supported GitLab VS Code extension, I’ve developed a few tricks that make me a productive GitLab user. Below, I share eight tips that make my work more efficient and productive, while also introducing you to some of the GitLab contributors who made this tooling happen.
What is Visual Studio Code?
Visual Studio Code, developed by Microsoft, lets a user debug source code in various languages from the editor. It is also used for syntax highlighting, intelligent code completion, code refactoring, embedded Git and autocomplete. VS Code, as it is commonly known, can be launched or attached to running apps.
It is designed for Windows, Linux, and MacOS. VS Code can be used with several programming languages such as Java, JavaScript, Node.js, Python, C++ and Fortran. Support for additional languages is provided by freely available extensions on the VS Code Marketplace.
Below are eight tips for using GitLab VS Code.
How to clone any GitLab project
GitLab contributor Felix Haase recently implemented a feature that lets you clone any GitLab project where you are a member. To clone the project, use the official Git: Clone command and select your GitLab instance. Use the Git: Clone command by selecting the command from the Command Palette.
This feature can save you time if you already know the name of the project you want to clone.

VS Code lets you filter which project to clone.
How to view MRs and issues
It is easy to look through issues and MRs that you created, are assigned to, or are reviewing using GitLab. The lesser-known feature of the GitLab Workflow extension is custom queries. Custom search queries allow you to refine the search expressions for issues and MRs that appear in the VS Code side panel. You can apply all the advanced search terms you are used to from the GitLab web search: Labels, full-text search expression, milestones, authors, assignees, and more.

See your issues and MRs in the VS Code sidebar.
Another option is reviewing the MRs in VS Code. The final functionality that is missing in MR review is creating new comments on the MR diff, which we plan to ship by July 2021.
How to create an MR with two clicks
If you use the git command in a terminal, you might have noticed that pushing your branch to GitLab produces the following output:
remote: To create a merge request for my-new-branch, visit: remote: https://gitlab-instance.com/my-group/my-project/merge_requests/new?merge_request%5Bsource_branch%5D=my-new-branch
After clicking the link, the terminal will open your browser on a new MR page where you can create an MR from the branch you just pushed.
When I started pushing my branches through VS Code, I missed this feature. To the point that I searched through the VS Code Git Extension logs to find the create MR link (command Git: Show Git Output ).
Luckily, GitLab contributor Jonas Tobias Hopusch implemented a status bar button that lets you create MRs just as easily.
To create an MR from your changes, push them to your remote repository (the cloud icon next to the branch name) and then click on the GitLab: Create MR. button.

VS Code status bar with buttons from GitLab extension.
How to configure your GitLab CI
The GitLab extension helps you edit your .gitlab-ci.yml configuration file in two ways: Autocompleting environment variables and validating the configuration.
Thanks to Kev’s fantastic contribution, you can use CI variable autocompletion anywhere in your .gitlab-ci.yml . The hints even include variable descriptions and explain supported GitLab versions.

CI variables autocomplete dialogue.
When you finish writing your .gitlab-ci.yml CI configuration, you can use the GitLab: Validate GitLab CI config command to surface any problems before committing the CI config to your repository.
How to create and paste project snippets
Is there a piece of text that you and your teammates often use? Maybe it is a license header for a file or a test scenario template. You can use GitLab snippets in combination with Visual studio code editor to save you a few keystrokes.
For example, you can create a test file snippet with the GitLab: Create snippet command and then paste it into every new test file you create with the GitLab: Insert snippet command.

Paste Snippet dialogue.
I mostly use snippets when I want to share a big blob of text. I select the text and then create the snippet with the GitLab: Create snippet command.
How to copy web URL for a project file
Most of the communication at GitLab happens asynchronously. So instead of being able to show your colleague an open file in your editor, you’ll need to be able to create a textual pointer to the file.
A straightforward way to do that is to use the GitLab: Copy link to active file on GitLab command, which will copy the web URL of the open file into your clipboard. It even includes the line number or a range of lines based on your cursor or selection in the Visual studio code editor.
You might also consider using the GitLens: Copy Remote File URL , which even includes the commit SHA in the URL, making it a permalink. The permalink will always point to the same version of the file regardless of further commits to your branch. We’ll look at the GitLens extension in tip number 7 a bit later on.
For the GitLab Enterprise/Community Edition you can use:
«gitweblinks.gitLabEnterprise»: [
«http»: «https://local-gitlab»,
«ssh»: «git@local-gitlab»
>
]
What to do if VS Code source control is not working
A SourceControl is the entity responsible for populating the Source Control model with resource states, instances of SourceControlResourceState . Resource states are organized in groups, instances of SourceControlResourceGroup .
Linking to issues in source code is a normal part of the VS Code workflow, especially when there’s some logic that’s difficult to understand or when there’s a //TODO comment that needs action. Users report experiencing issues with changes in the file not appearing to the source code, unless inputted manually.
One user offered a 7-step solution that worked for them. Another said that all they had to do was disable and then reenable the build in Git extension, which fixed it. Yet another said they went to their “code” folder where they keep all their repos, right-clicked on the folder containing the repo they wanted and opening that folder with VS code.
An often-used approach to look at issues is to pick one to work on, create a branch to work in, make some commits, then merge your changes back into the main or default branch with a pull request. You can do that from the new Issues view.
GitLab Workflow extensions for VS Code
The GitLab Workflow extension integrates GitLab with VS Code. You can decrease context switching and do more day-to-day tasks in VS Code, such as:
- View issues.
- Run common commands from the Visual Studio Code command palette.
- Create and review merge requests directly from Visual Studio Code.
- Validate your GitLab CI configuration.
- View the status of your current pipeline.
- Create and paste snippets to, and from, your editor.
- Browse repositories without cloning them
Download the extension from the Visual Studio Code Marketplace. Then you can configure:
- Features to display or hide.
- Self-signed certificate information
Report any issues, bugs, or feature requests in the gitlab-vscode-extension issue queue.
This extension supports GitLab Version 13.0 and later. To find your GitLab version, visit help.
You can also see pipeline status, open MR and closing issue links in the status bar. The pipeline status is updated automatically so you don’t need to open GitLab to see your pipeline status.
Within the marketplace you can also use the command palette to run the commands and create a GitLab personal access token (required) and assign it to the extension.
You can also set set the token in an environment variable and learn how to change the VS Code settings. There are instructions for several other in-depth features as well.
How GitLens simplifies working with VS Code editor
Up until now, the tips were centered around the GitLab Workflow extension, but there is a fantastic extension that’s improving VS Code git integration regardless of where you host your repository: GitLens.
Walking file history
GitLens makes it easy to browse the history of changes to the current file. Each versioned file will have three new editor icons, which provides quick access to all previous revisions of the file. The middle button seen in the image below provides series of actions on the current version (e.g., opening the commit in GitLab web).

GitLens history browsing buttons
How to compare current HEAD against branch or tag
One of my habits was inspecting git diff between my feature branch and the main branch before creating an MR. More often than not, I forgot to write a test or remove some pesky console.log() .
GitLens adds multiple sections to your «Source Control» tab. For each branch, tag, and commit, click a «Compare» icon which will show you changes between your current HEAD and the reference. Seeing the local diff is great for previewing changes before pushing the new branch to the remote.

How to compare with a branch using GitLens.
Everyone can contribute
New features and fixes to the GitLab Visual Studio Code editor extension are added every month. If you find any issues or have a feature request, please go to our GitLab VSCode issues tracker and if your request isn’t already present in the tracker, create one. Everyone can contribute to GitLab, and we welcome your ideas on how to improve our Visual Studio Code editor.
Read more on Visual Studio and GitLab:
- Four new tools for your Visual Studio Code and GitLab tool belt
- VS Code extension development with GitLab
- How to do GitLab merge request reviews in VS Code
- How we created a GitLab Workflow Extension for VS Code
GitLab and Visual Studio Code
I’m trying to integrate Visual Studio Code as GitLab to perform version control of source code. I did not find anything that would help me during the Google searches, so I’m asking here. How can I integrate it? I’m using GitLab’s free account and I want to commit, push, and clone through Visual Studio Code. Is it possible?
30.7k 22 22 gold badges 106 106 silver badges 131 131 bronze badges
asked Nov 28, 2018 at 18:05
William Gustavo Marquetti William Gustavo Marquetti
129 1 1 gold badge 3 3 silver badges 12 12 bronze badges
This is now fully supported with GitLab 14.0 (June 2021): see my edited answer below.
Jun 22, 2021 at 16:15
4 Answers 4
In the Marketplace you find a lot of Visual Studio Code Extensions. They are labeled with tags, e.g.
Which to use depends on your preferences and scenarios. I recommend and I am personally using GitLens — Git supercharged.
The installation in Visual Studio Code is easy, for GitLens e.g.:
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
ext install eamodio.gitlens
The documentation you find on the extension page, see link above.
1 1 1 silver badge
answered Nov 28, 2018 at 20:57
1,367 1 1 gold badge 14 14 silver badges 19 19 bronze badges
Hi BiNZGi! I’ve installed GitLens like you suggested and used the git clone to import my project, but when in try to commit my changes, shows this error: > git commit —quiet —allow-empty-message —file — *** Please tell me who you are. Run git config —global user.email «[email protected]» git config —global user.name «Your Name» to set your account’s default identity. Omit —global to set the identity only in this repository. fatal: unable to auto-detect email address (got ‘punk@punk-PC.(none)’) > git config —get-all user.name
Dec 1, 2018 at 16:57
You have to setup git once with username and email. You can open a console and enter the commands like written in the error message and adjust to your username git config —global user.name «Your Name» and email git config —global user.email «[email protected]» . The two values are used for all commits you are going to do on this computer.
Dec 1, 2018 at 23:57
I would appreciate if you mark my answer as correct.
Dec 21, 2018 at 9:58
In Windows, once SSH keys are settled in your machine and you have Git installed (e.g., Git-2.20.1-64-bit.exe), you then need to setup the Git inside Visual Studio Code.
In the terminal of Visual Studio Code, set up the global configuration:
In the same terminal, navigate to your local directory where you want to set up the remote repository from GitLab.
Then since you are creating a new remote repository in GitLab (e.g inside NewFolder with repo.git as the Git name) type:
git clone ssh://[email protected]/NewFolder/repo.git
In the same terminal, navigate to your newly created local folder called «repo»:
cd repo
You can then add files into that local folder «repo». Then in the Visual Studio Code source control button, stage the changes and click the check icon to commit it.
Once committed, you can then publish it via the Visual Studio Code interface.
Or manually by typing:
git add . git commit -m "Initial commit" git push -u origin master
30.7k 22 22 gold badges 106 106 silver badges 131 131 bronze badges
answered Sep 17, 2019 at 23:57
DonAriston DonAriston
101 1 1 silver badge 5 5 bronze badges
Note that, with GitLab 13.3 (August 2020), this is officially supported:
GitLab Workflow extension for Visual Studio Code now official

Over two years ago, Fatih Acet created an extension to integrate GitLab with development in Visual Studio Code.
Fatih and more than 25 contributors continued to improve the extension with new features, and it has now been installed over 160,000 times. Fatih transferred maintainership to GitLab, and we’ll continue to improve and support this extension.
The GitLab Workflow is now officially maintained and supported by the Editor Group. We’ll be continuing to contribute features, and support the community who was actively involved in our early releases. If you have ideas or feedback, please open an issue.
See Documentation and Issue.
Three months later, that GitLab-Visual Studio Code integration is even more complete: See GitLab 13.6 (November 2020)
Issues and Merge Requests in VS Code

Issues are the source of truth for collaboration and what needs to be implemented. Referring back to user stories, designs, and discussions on the issue involves switching between your editor and browser. Merge Requests are the place where feedback on contributions is provided. Referencing this feedback and continuing to make changes requires this same context-switch between browser and editor.
Reducing the friction of context-switching between tools makes it more efficient to contribute changes to a project. With the 3.6.0 Release of GitLab Workflow, issues and merge requests are available directly in VS Code for easy access and collaboration. You can find issues and merge requests assigned to you or created by you and open those directly inside VS Code. This gives quick access to the information needed and the ability to respond directly to issues and merge requests via comments.
This is the first step in enabling more complete Merge Request reviews in VS Code.
See Documentation and Issue.
And, still with GitLab 13.6 (Nov. 2020):
Insert GitLab Snippets directly in VS Code
Project snippets are a place to share code fragments among your team. These snippets often contain fragments of code that are re-used in multiple places or help to bootstrap similar pages and components.
When contributing to a project, it can be important to find these snippets and insert their contents in to your working file. Finding these requires context switching out of your editor and then copy/pasting the correct information.
Using the VS Code extension GitLab Workflow v3.5.0, you can now insert snippets in to your working file, both single and multi-file snippets are supported.
See Documentation and Issue.
With GitLab 13.7 (December 2020), you now have:
View Merge Request changes in VS Code

When working in VS Code to review a merge request, easily referencing changes often requires checking out a branch and then trying to determine the diff between that branch and the merge target.
With the 3.7.0 Release of GitLab Workflow, merge request changes are available directly in VS Code. This provides quick access to seeing changes for merge requests in your projects.
As we continue working on bringing a complete Code Review experience to VS Code, we’ll be bringing comments on diffs to the extension next.
See Documentation and Issue.
GitLab 13.9 (February 2021) brings two new integrations with Visual Studio Code:
Autocomplete GitLab CI Variables in VS Code

GitLab CI is fast and highly configurable, but it can be hard to remember all the predefined environment variables, and the wrong typo can make your .gitlab-ci.yml file invalid. To make it easier to configure your GitLab CI pipeline, the 3.11.0 Release of GitLab Workflow provides auto completion for predefined environment variables when editing your .gitlab-ci.yml file.
Tooltips in the auto complete dialog provide information on what the variable can be used for as well as information on supported GitLab and Runner versions. These additional pieces of information really help to ensure your CI configuration will be valid.
Thanks to @KevSlashNull for the contribution!
See Documentation and Issue.
And (still with GitLab 13.9, February 2021):
View code review comments in VS Code

In a previous release of GitLab Workflow for VS Code it became possible for you to view merge request changes in VS Code. However, seeing the changes proposed by a merge request is only part of reviewing that change and being able to respond to feedback.
With GitLab Workflow 3.10.0, comments provided on changes are now available as part of the diff view. This greatly improves your ability to action feedback provided on your merge request directly in the editor without the additional context switch between VS Code and GitLab.
We’re continuing to expand on Code Review experiences in VS Code. Responding to comments is up next.
See Documentation and Issue.
Clone project inside Visual Studio Code
- find the project in GitLab,
- copy its clone link,
- clone it into your local machine, and
- finally open it in VS Code.
This is now fully supported with GitLab 14.0 (June 2021):
Merge request reviews in VS Code
Merge request reviews in VS Code
As a developer, you often spend a majority of your time working in your local development environment. When you’re assigned a merge request for review, this requires you to leave your editor and perform that review inside of GitLab. While performing your review inside GitLab, you might also need to use your local editor to gain more context on the proposed changes.
GitLab Workflow version 3.21.0 for Visual Studio Code (VS Code) now supports the complete merge request review process, including threads. Select the GitLab icon in VS Code to open the sidebar to display Merge requests I’m reviewing. Select a merge request overview to view the complete details and discussions of the merge request.
The sidebar also contains a list of all the changed files in the merge request. Selecting files opens a diff comparison for you to review the changes in VS Code. While viewing the diff, you can read feedback left on the files, and create new comments by selecting a line number and creating your comment. All comments and feedback you provide in VS Code are available in the GitLab web interface, making it easy for you to perform your reviews in VS Code, and other users to participate in GitLab.
We’re really excited about bringing the complete merge request review process to you inside of VS Code. Let us know what you think by opening an issue for GitLab Workflow.
See Documentation and Epic.
See GitLab 15.4 (September 2022)
Improved CI/CD integration in VS Code

When you’re constructing complicated GitLab CI configurations that may contain include: or extends: keywords, it’s challenging to ensure the configuration is valid and the resulting file has your expected configuration. Use GitLab Workflow for Visual Studio Code to preview your merged GitLab CI/CD configuration file directly in VS Code. You can view your changes locally, and ensure your configuration is as you expect, before you commit and push.
GitLab Workflow v3.50.0 also provides more CI/CD pipeline interactions to help you avoid context-switching:
- Download artifacts: commit f4d027c , merge request !635
- Retry or cancel an existing pipeline: commit c2caee4 , merge request !637
Thank you Lennard Sprong for all these amazing contributions!
See Documentation and Issue.
GitLab Workflow extension for VS Code
Download the extension from the Visual Studio Code Marketplace.
Configure the extension
- Features to display or hide.
- Self-signed certificate information.
- Code Suggestions.
- GitLab Duo Chat.
Report issues with the extension
Report any issues, bugs, or feature requests in the gitlab-vscode-extension issue queue.
Related topics
- Download the extension
- Extension documentation
- View source code
Help & feedback
Docs
Edit this page to fix an error or add an improvement in a merge request.
Create an issue to suggest an improvement to this page.
Product
Create an issue if there’s something you don’t like about this feature.
Propose functionality by submitting a feature request.
Join First Look to help shape new features.
Feature availability and product trials
View pricing to see all GitLab tiers and features, or to upgrade.
Try GitLab for free with access to all features for 30 days.
Get Help
If you didn’t find what you were looking for, search the docs.
If you want help with something specific and could use community support, post on the GitLab forum.
For problems setting up or using this feature (depending on your GitLab subscription).
Пошаговая инструкция по настройке и использованию Gitlab CI + Visual Studio для сборки приложения .NET Framework
По натуре своей многие разработчики слишком ленивые не любят делать одно и то же действие много раз. Нам проще научить компьютер, чтобы он делал монотонные действия за нас.
Как только кто-либо из нашей команды вносит изменения в код (читай «мерджит feature-ветку в develop»), наш билд-сервер:
- Собирает исходный код и установщик приложения
- проставляет номер сборки, каждый раз увеличивая последнюю цифру. Например, текущая версия нашего ПО 3.3.0.202 – часть 3.3.0 когда-то ввёл разработчик (привет, SemVer), а «202» проставляется в процессе сборки.
- В процессе анализирует качество кода (с использованием SonarQube) – и отправляет отчёт во внутренний SonarQube,
Также, в зависимости от ветки, в которую были внесены изменения, могут быть выполнены:
- отправка сборки (вместе с changelog-ом) в один или несколько телеграм-каналов (иногда удобнее брать сборки оттуда).
- публикация файлов в систему автообновления ПО.
Под катом о том, как мы научили Gitlab CI делать за нас бОльшую часть этой муторной работы.
Оглавление
- Устанавливаем и регистрируем Gitlab Runner.
- Что нужно знать про .gitlab-ci.yml и переменные сборки.
- Активируем режим Developer PowerShell for VS.
- Используем CI для проставления версии во все сборки решения.
- Добавляем отправку данных в SonarQube.
- «Причёсываем» автотесты xUnit + добавляем вычисление покрытия тестами через OpenCover.
- Послесловие.
Перед началом
Чтобы быть уверенными, что написанное ниже работает, мы взяли на github небольшой проект, написанный на WPF и имеющий unit-тесты, и воспроизвели на нём описанные в статье шаги. Самые нетерпеливые могут сразу зайти в созданный на сайте gitlab.com репозиторий и посмотреть, как это выглядит.
Устанавливаем и регистрируем Gitlab Runner
Для того чтобы Gitlab CI мог что-либо собрать, сначала установите и настройте Gitlab Runner на машине, на которой будет осуществляться сборка. В случае проекта на .Net Framework это будет машина с ОС Windows.
Чтобы настроить Gitlab Runner, выполните следующие шаги:
- Установите Git для Windows с сайта git.
- Установите Visual Studio с сайта Microsoft. Мы поставили себе Build Tools для Visual Studio 2019. Чтобы скачать именно его, разверните список Инструменты для Visual Studio 2019.
- Создайте папку C:\GitLab-Runner и сохраните в неё программу gitlab runner. Скачать её можно со страницы [документации Gitlab] (https://docs.gitlab.com/runner/install/windows.html) — ссылки скрыты прямо в тексте: «Download the binary for x86 or amd64».
- Запустите cmd или powershell в режиме администратора, перейдите в папку C:\GitLab-Runner и запустите скачанный файл с параметром install (Gitlab runner установится как системная служба).
.\gitlab-runner.exe install- только в одном проекте — смотрите токен в меню проекта Settings >CI/CD в разделе Runners,
- в группе проектов — смотрите токен в меню группы Settings >CI/CD в разделе Runners,
- для всех проектов Gitlab-а — смотрите токен в секции администрирования, меню Overview >Runners.
.\gitlab-runner.exe registerДалее надо ввести ответы на вопросы мастера регистрации Runner-а:
- coordinator URL — http или https адрес вашего сервера gitlab;
- gitlab-ci token — введите токен, полученный на предыдущем шаге;
- gitlab-ci description — описание Runner-а, которое будет показываться в интерфейсе Gitlab-а;
- gitlab-ci tags — через запятую введите тэги для Runner-а. Если вы не знакомы с этим механизмом, оставьте поле пустым — отредактировать его можно позднее через интерфейс самого gitlab-а. Тэги можно использовать для того, чтобы определённые задачи выполнялись на определённых Runner-ах (например, чтобы настроить сборку ПО на Runner-е, развёрнутом на копьютере ОС Windows, а подготовку документации на Runner-е с ОС Linux);
- enter the executor — ответьте shell . На этом шаге указывается оболочка, в которой будут выполняться команды; при указании значения shell под windows выбирается оболочка powershell, а последующие скрипты написаны именно для неё.
Что нужно знать про .gitlab-ci.yml и переменные сборки
В процессе своей работы Gitlab CI берёт инструкции о том, что делать в процессе сборки того или иного репозитория из файла .gitlab-ci.yml , который следует создать в корне репозитория.
Вбив в поиске содержимое .gitlab-ci.yml для сборки приложения .NET Framework можно найти несколько шаблонов: 1, 2. Выглядят они примерно так:
variables: # Максимальное количество параллельно собираемых проектов при сборке решения; зависит от количества ядер ПК, выбранного для сборки MSBUILD_CONCURRENCY: 4 # Тут куча путей до утилит, которые просто обязаны лежать там, где ожидается NUGET_PATH: 'C:\Tools\Nuget\nuget.exe' MSBUILD_PATH: 'C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin\msbuild.exe' XUNIT_PATH: 'C:\Tools\xunit.runner.console.2.3.1\xunit.console.exe' TESTS_OUTPUT_FOLDER_PATH: '.\tests\CiCdExample.Tests\bin\Release\' # Тут указываются стадии сборки. Указывайте любые названия которые вам нравятся, но по умолчанию используют три стадии: build, test и deploy. # Стадии выполняются именно в такой последовательности. stages: - build - test # Далее описываются задачи (job-ы) build_job: stage: build # указание, что задача принадлежит этапу build # tags: windows # если тут указать тэг, задача будет выполняться только на Runner-е с указанным тэгом only: # для каких сущностей требуется выполнять задачу - branches script: # код шага - '& "$env:NUGET_PATH" restore' - '& "$env:MSBUILD_PATH" /p:Configuration=Release /m:$env:MSBUILD_CONCURRENCY /nr:false /clp:ErrorsOnly' # сборка; ключ clp:ErrorsOnlyоставляет только вывод ошибок; ключ nr:false завершает инстансы msbuild artifacts: # где по завершении задачи будут результаты, которые надо сохранить в gitlab (т.н. артефакты) и которые можно будет передать другим задачам по цепочке expire_in: 2 days # сколько хранить артефакты paths: # список путей, по которым находятся файлы для сохранения - '$env:TESTS_OUTPUT_FOLDER_PATH' test_job: stage: test only: - branches script: - '& "$env:XUNIT_PATH" "$env:TESTS_OUTPUT_FOLDER_PATH\CiCdExample.Tests.dll"' dependencies: # указание, что для запуска этой задачи требуется успешно завершенная задача build_job - build_jobИ последнее: если нам требуется передавать в скрипт значение параметра, который мы не хотим хранить в самом скрипте (например, пароль для подключения куда-либо), мы можем использовать для этого объявление параметров в gitlab. Для этого зайдите в проекте (или в группе проекта) в Settings > CI/CD и найдите раздел Variables. Прописав в нём параметр с именем (key) SAMPLE_PARAMETER, вы сможете получить его значение в в скрипте .gitlab-ci.yml через обращение $env:SAMPLE_PARAMETER.
Также в этом разделе можно настроить передачу введенных параметров только при сборке защищённых веток (галочка Protected) и/или скрытие значения параметра из логов (галочка Masked).
Подробнее о параметрах окружения сборки смотрите в документации к Gitlab CI.
Активируем режим Developer PowerShell for VS
Скрипт, приведённый выше, уже можно использовать для сборки и вызова тестов. Правда, присутствует НО: крайне неудобно прописывать абсолютные пути к разным установкам Visual Studio. К примеру, если на одной билд-машине стоит Visual Studio 2017 BuildTools, а на другой Visual Studio Professional 2019, то такой скрипт будет работать только для одной из двух машин.
К счастью, с версии Visual Studio 2017 появился способ поиска всех инсталляций Visual Studio на компьютере. Для этого существует утилита vswhere, путь к которой не привязан ни к версии Visual Studio, ни к её редакции. А в Visual Studio 2019 (в версии 16.1 или более новой) есть библиотека, которая умеет «трансформировать» консоль Powershell в режим Developer Powershell, в котором уже прописаны пути к утилитам из поставки VS.
Дописываем переменную к секции Variables:
variables: VSWHERE_PATH: '%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe'Затем создаём новую секцию before_msbuild якорем enter_vsdevshell и следующим текстом:
.before_msbuild: &enter_vsdevshell before_script: - '$vsWherePath = [System.Environment]::ExpandEnvironmentVariables($env:VSWHERE_PATH)' - '& $vsWherePath -latest -format value -property installationPath -products Microsoft.VisualStudio.Product.BuildTools | Tee-Object -Variable visualStudioPath' - 'Join-Path "$visualStudioPath" "\Common7\Tools\Microsoft.VisualStudio.DevShell.dll" | Import-Module' - 'Enter-VsDevShell -VsInstallPath:"$visualStudioPath" -SkipAutomaticLocation'И всюду, где нам надо использовать утилиты Visual Studio, добавляем этот якорь. После этого задача сборки начинает выглядеть намного более опрятно:
build_job:Подробно о том, что написано в .before_msbuild
- Утилита vswhere.exe умеет находить и выдавать список найденных инсталляций Visual Studio. Расположен она всегда по одному и тому же пути (этот путь записан в переменной VSWHERE_PATH). Поскольку в переменной фигурирует подстановка %programfiles% , её требуется раскрыть до пути к этой папке. Такое раскрытие проще всего сделать через статический метод .NET System.Environment.ExpandEnvironmentVariables.
Результат: мы имеем путь к vswhere.
- Вызовом vswhere получим путь к папке с установленной Visual Studio.
Все параметры утилиты можно посмотреть, если запустить vswhere.exe с параметром -help , в статье же только перечислю использованные:- -latest (искать самые свежие установки),
- -property installationPath (вывести параметр пути установки),
- -format value (при печати параметра вывести только значение параметра, без его имени),
- -products (указание искомых редакций Visual Studio). Например, при запуске с параметром -products Microsoft.VisualStudio.Product.Community Microsoft.VisualStudio.Product.BuildTools утилита попробует найти Visual Studio редакций Community или BuildTools. Подробнее об идентификаторах продуктов смотрите по ссылке https://aka.ms/vs/workloads.
Результат: в переменную $visualStudioPath записан путь к Visual Studio или пустая строка, если инсталляций Visual Studio не найдено (обработку этой ситуации мы ещё не добавили).
- Команда Import-Module загружает библиотеку Microsoft.VisualStudio.DevShell.dll, в которой прописаны командлеты трансформации консоли Powershell в Developer-консоль. А командлет Join-Path формирует путь к этой библиотеке относительно пути установки Visual Studio.
На этом шаге нам прилетит ошибка, если библиотека Microsoft.VisualStudio.DevShell.dll отсутствует или путь к установке Visual Studio нужной редакции не был найден — Import-Module сообщит, что не может загрузить библиотеку.
Результат: загружен модуль Powershell с командлетом трансформации.
- Запускаем «переделку» консоли в Developer Powershell. Чтобы корректно прописать пути к утилитам, командлету требуется путь к установленной Visual Studio (параметр -VsInstallPath ). А указание SkipAutomaticLocation требует от командлета не менять текущее расположение (без этого параметра путь меняется на \source\repos ).
Результат: мы получили полноценную консоль Developer Powershell с прописанными путями к msbuild и многим другим утилитам, которые можно использовать при сборке.
Используем CI для проставления версии во все сборки решения
Раньше мы использовали t4 шаблоны для проставления версий: номер версии собиралась из содержимого файла в формате .. , далее к ней добавлялся номер сборки из Gitlab CI и он передавался в tt-шаблон, добавляющий в решение везде, где требуется, номер версии. Однако некоторое время назад был найден более оптимальный способ — использование команд git tag и git describe .
Команда git tag устанавливает коммиту метку (тэг). Отметить таким образом можно любой коммит в любой момент времени. В отличие от веток, метка не меняется. То есть если после помеченного коммита вы добавите ещё один, метка останется на помеченном коммите. Если попробуете переписать отмеченный коммит командами git rebase или git commit --amend, метка также продолжит указывать на исходный коммит, а не на изменённый. Подробнее о метках смотрите в git book.
Команда git describe , к сожалению, в русскоязычном gitbook не описана. Но работает она примерно так: ищет ближайшего помеченного родителя текущего коммита. Если такого коммита нет — команда возвращает ошибку fatal: No tags can describe '' . А вот если помеченный коммит нашёлся — тогда команда возвращает строку, в которой участвует найденная метка, а также количество коммитов между помеченным и текущим.
На заметку: чтобы данная команда работала корректно во всех случаях, автор gitflow даже чуть-чуть поменял скрипты finish hotfix и finish release. Если кому интересно посмотреть обсуждение с автором gitflow, а также увидеть что изменилось (картинка с актуальной схемой в последнем сообщении в треде).
Кстати, по этой же причине если вы используете gitflow, после вливания feature-ветки в develop требуется удалить влитую локальную ветку, после чего пересоздать её от свежего develop:

(обратите внимание на историю git в левой части картинки: из-за отсутствия пути из текущего коммита до коммита с меткой 1.0.5, команда git describe выдаст неверный ответ)
Но вернёмся к автопроставлению версии. В нашем репозитории царит gitflow (точнее его rebase-версия), метки расставляются в ветке master и мы не забываем пересоздавать feature-ветки от develop, а также merge-ить master в develop после каждого релиза или хотфикса.
Тогда получить версию для любого коммита и сразу передать её в msbuild можно добавив всего пару строк к задаче сборки:
build_job: [0-9]+)\.(?[0-9]*)\.(?[0-9]*)\-(?[0-9]+)\-g[0-9a-f]+" | Select-Object -First 1' - '[int]$major, [int]$minor, [int]$patch, [int]$commit = $versionGroup.Matches[0].Groups["major", "minor", "patch", "commit"].Value' - '[string]$version = "$major.$minor.$patch.$commit"' - 'msbuild /p:Configuration=Release /p:AssemblyVersionNumber=$version /m:$env:MSBUILD_CONCURRENCY /nr:false /clp:ErrorsOnly' artifacts: expire_in: 2 days paths: - '$env:TESTS_OUTPUT_FOLDER_PATH'Как это работает:
- Мы проставляем метки в формате .. .
- Тогда git describe --long возвращает нам строку, описывающую версию в формате ..--g .
- Парсим полученную строку через регулярные выражения, выделяя нужные нам части — и записывем части в $versionGroup .
- Преобразовываем четыре найденные подстроки в 4 числа и пишем их в переменные $major , $minor , $patch , $commit , после чего собираем из них строку уже в нужном нам формате.
- Передаём указанную строку в msbuild чтобы он сам проставил версию файлов при сборке.
Обратите внимание: если вы, согласно gitflow, будете отмечать (тэгировать) ветку master после вливания в неё release или hofix, будьте внимательны: до простановки метки автосборка будет вестись относительно последней существующей ветки. Например, сейчас опубликована версия 3.4, а вы создаёте release-ветку для выпуска версии 3.5. Так вот: всё время существования этой ветки, а также после её вливания в master, но до простановки тэга, автосборка будет проставлять версию 3.4.
Добавляем отправку данных в SonarQube
SonarQube — это мощный инструмент контроля качества кода.
SonarQube имеет бесплатную Community-версию, которая способна проводить полный анализ. Правда, только одной ветки. Чтобы настроить её на контроль качества ветки разработки (develop), требуется выполнить следующие шаги (разумеется, помимо установки и развёртывания сервера SonarQube):
- Создайте в SonarQube новый проект, после чего запомните его ключ.
- Скачайте SonarScanner for MSBuild (с сайта sonarqube.org)[https://docs.sonarqube.org/latest/analysis/scan/sonarscanner-for-msbuild/] — мы используем версию .NET Framework 4.6+.
- Распакуйте содержимое архива в папку. Например, в C:\Tools\SonarScanner .
На заметку: эту утилиту также можно скачать на сборочную машину через NuGet, но тогда надо будет чуть по-иному указывать её путь. - Зайдите в параметры CI/CD в свойствах проекта Gitlab и добавьте следующие параметры:
- SONARQUBE_PROJECT_KEY — ключ проекта,
- SONARQUBE_AUTH_TOKEN — токен авторизации.
variables: SONARSCANNER_MSBUILD_PATH: 'C:\Tools\SonarScanner\SonarScanner.MSBuild.exe' SONARQUBE_HOST_URL: 'url вашего сервера SonarQube'test_job: stage: test only: - /^develop$/ [0-9]+)\.(?[0-9]*)\.(?[0-9]*)\-(?[0-9]+)\-g[0-9a-f]+" | Select-Object -First 1' - '[int]$major, [int]$minor, [int]$patch, [int]$commit = $versionGroup.Matches[0].Groups["major", "minor", "patch", "commit"].Value' - '[string]$version = "$major.$minor.$patch.$commit"' - '& "$env:SONARSCANNER_MSBUILD_PATH" begin /key:$env:SONARQUBE_PROJECT_KEY /d:sonar.host.url=$env:SONARQUBE_HOST_URL /d:sonar.login=$env:SONARQUBE_AUTH_TOKEN /d:sonar.gitlab.project_id=$CI_PROJECT_PATH /d:sonar.gitlab.ref_name=develop /v:$version /d:sonar.dotnet.excludeGeneratedCode=true' - 'msbuild /t:rebuild /m:$env:MSBUILD_CONCURRENCY /nr:false /clp:ErrorsOnly' - '& "$env:SONARSCANNER_MSBUILD_PATH" end /d:sonar.login=$env:SONARQUBE_AUTH_TOKEN' - '& "$env:XUNIT_PATH" "$env:TESTS_OUTPUT_FOLDER_PATH\CiCdExample.Tests.dll"'Теперь при каждой сборке ветки develop в SonarQube будет отправляться подробный анализ нашего кода.
На заметку: вообще команда msbuild /t:rebuild полностью пересобирает решение. Вероятно, в большинстве проектов анализ можно было бы встроить прямо в стадию сборки. Но сейчас у нас анализ в отдельной задаче.
Пара слов об использованных параметрах:
- key — ключ проекта на сервере SonarQube,
- v — собираемая версия. Отлично комбинируется с предыдущим шагом автопроставления версии,
- sonar.gitlab.project_id — ID проекта на сервере Gitlab,
- sonar.gitlab.ref_name — название ветки, которое получает сервер SonarQube при передаче результатов анализа,
- sonar.dotnet.excludeGeneratedCode — не включать в анализ объекты, отмеченные атрибутом System.CodeDom.Compiler.GeneratedCode (чтобы не оценивать качество автосгенерированного кода).
«Причёсываем» автотесты xUnit + добавляем вычисление покрытия тестами через OpenCover
Со сборкой более-менее разобрались — теперь приступаем к тестам. Доработаем код прогона тестов, чтобы он:
- сам находил библиотеки с тестами,
- прогонял их пачкой через xUnit,
- вычислял тестовое покрытие через OpenConver,
- отправлял результаты покрытия тестами в SonarQube.
На заметку: обычно в паре с OpenCover используют ReportGenerator, но при наличии SonarQube мы с тем же успехом можем смотреть результаты через его интерфейс.
Для настройки выполним следующие шаги:
- Скачайте OpenCover в виде zip-файла с сайта github.
- Распакуйте содержимое архива в папку. Например, в C:\Tools\OpenCover .
На заметку: эту утилиту также можно скачать на сборочную машину через NuGet, но тогда надо будет чуть по-иному указывать её путь. - Допишите переменные к секции Variables:
variables: OBJECTS_TO_TEST_REGEX: '^Rt[^\n]*\.(dll|exe)$' OPENCOVER_PATH: 'C:\Tools\opencover-4.7.922\xunit.console.exe' OPENCOVER_FILTER: '+[Rt.*]* -[*UnitTests]* -[*AssemblyInfo]*' OPENCOVER_REPORT_FILE_PATH: '.\cover.xml'test_job: stage: test only: - /^develop$/ [0-9]+)\.(?[0-9]*)\.(?[0-9]*)\-(?[0-9]+)\-g[0-9a-f]+" | Select-Object -First 1' - '[int]$major, [int]$minor, [int]$patch, [int]$commit = $versionGroup.Matches[0].Groups["major", "minor", "patch", "commit"].Value' - '[string]$version = "$major.$minor.$patch.$commit"' - '& "$env:SONARSCANNER_MSBUILD_PATH" begin /key:$env:SONARQUBE_PROJECT_KEY /d:sonar.host.url=$env:SONARQUBE_HOST_URL /d:sonar.login=$env:SONARQUBE_AUTH_TOKEN /d:sonar.gitlab.project_id=$CI_PROJECT_PATH /d:sonar.gitlab.ref_name=develop /v:$version /d:sonar.cs.opencover.reportsPaths="$env:OPENCOVER_REPORT_FILE_PATH" /d:sonar.dotnet.excludeGeneratedCode=true' - 'msbuild /t:rebuild /m:$env:MSBUILD_CONCURRENCY /nr:false /clp:ErrorsOnly' - '$dllsToRunUnitTesting = @(Get-ChildItem "$env:TESTS_OUTPUT_FOLDER_PATH" -Recurse) | Where-Object | ForEach-Object < """""$_""""" >| Join-String -Separator " "' - '& "$env:OPENCOVER_PATH" -register -target:"$env:XUNIT_PATH" -targetargs:"$dllsToRunUnitTesting -noshadow" -filter:"$env:OPENCOVER_FILTER" -output:"$env:OPENCOVER_REPORT_FILE_PATH" | Write-Host' - 'if ($?) !>"' - 'Write-Host "Total Branch Coverage [![$branchCoverage]!]"' - '> else ' - '& "$env:SONARSCANNER_MSBUILD_PATH" end /d:sonar.login=$env:SONARQUBE_AUTH_TOKEN'- если хочется видеть значение покрытия тестов по строкам кода (его ешё называют Sequence Coverage или Statement Coverage), указываем выражение ]+)>!> ,
- если хочется видеть значение покрытия тестов по веткам условных операторов (его называют Decision Coverage или Branch Coverage), указываем выражение \[!\[([^>]+)\]!\] .
