Выпуск версии
Для разработчиков NetForms: что публикуется, как это запускается и что владелец репозитория настраивает
один раз. Всё остальное делают workflow .github/workflows/ci.yml и release.yml.
Как выходит версия
Выпуск — это смена версии в main. Поднимите <Version> в Directory.Build.props, влейте в main, и
после зелёных тестов CI сам:
- видит, что тега
v<Version>ещё нет (задачаrelease-check); - вызывает
release.yml: собирает все пакеты, публикует NuGet-пакеты в nuget.org, расширение — в VS Code Marketplace и Open VSX; - создаёт GitHub Release с файлами пакетов и текстом
CHANGELOG.md— вместе с ним появляется тегv<Version>.
Следующие пуши в main с той же версией ничего не публикуют: тег уже есть.
Если учётных данных NuGet нет, release-check пишет предупреждение и ничего не выпускает (и тег не
создаётся). Добавьте их — и следующий пуш в main (или ручной запуск CI) выпустит эту версию.
Другие способы запустить release.yml:
- вручную: Actions → Release → Run workflow. Без галочки publish — сухой прогон: собирает все пакеты как артефакты и ничего не публикует. С галочкой — настоящий выпуск текущей версии;
- тегом:
git tag v0.1.0-preview.1 && git push origin v0.1.0-preview.1(тег обязан совпадать с версией).
Повторная публикация безопасна: dotnet nuget push --skip-duplicate, vsce publish --skip-duplicate,
ovsx publish --skip-duplicate, существующий GitHub Release пропускается.
Что выходит
| Куда | Что | Собирается |
|---|---|---|
| nuget.org | NetForms, NetForms.Drawing, NetForms.Drawing.Common, NetForms.Platform, NetForms.Platform.Avalonia (+ .snupkg с символами и Source Link) |
dotnet pack NetForms.slnx -c Release -o artifacts/pkg |
| nuget.org | NetForms.Templates — dotnet new netforms, netforms-form, netforms-usercontrol |
dotnet pack templates/NetForms.Templates.csproj -c Release -o artifacts/pkg |
| nuget.org | NetForms.Convert — .NET tool netforms-convert (~42 МБ: натив Skia только для настольных платформ) |
входит в dotnet pack NetForms.slnx |
| VS Code Marketplace, Open VSX | netforms.netforms-designer, по пакету на платформу (win32-x64, win32-arm64, linux-x64, linux-arm64, darwin-x64, darwin-arm64, ~13 МБ каждый); версия NetForms с дефисом → pre-release |
cd designer && npm run package:targets |
| GitHub Releases | всё перечисленное + универсальный .vsix (41 МБ) |
задача github-release |
| GitHub Pages | сайт: site/ + документация из docs/ |
.github/workflows/pages.yml при изменении site/ или docs/ в main |
Не публикуются (IsPackable=false по умолчанию в Directory.Build.props): NetForms.Design,
NetForms.Design.Serialization (едут внутри расширения), тесты, сэмплы, ApiDiff, Markup, хост дизайнера.
Один раз, руками (владелец репозитория)
nuget.org — один из двух способов
A. Trusted Publishing, без хранимого ключа (рекомендуется).
- Войдите на nuget.org под учётной записью, которая будет владельцем пакетов.
- Username → Trusted Publishing → Create: Repository Owner
Go-Forms, Repository.NetForms, Workflow Filerelease.yml(если публикация из CI упадёт с ошибкой политики, добавьте вторую политику сci.yml— CI вызываетrelease.ymlкак reusable workflow). Scopes: «Push new packages and package versions» (не только новых версий: первые публикации — это новые пакеты), Glob Pattern:NetForms*(или*). Environment оставьте пустым. - В GitHub: Settings → Secrets and variables → Actions → Variables → переменная
NUGET_USER= имя пользователя nuget.org (не e-mail).
Workflow получает от GitHub OIDC-токен, обменивает его на ключ, живущий час (NuGet/login@v1), и публикует.
Самой первой публикацией нового id на nuget.org владельцем становится эта учётная запись.
Если в логе «Successfully exchanged OIDC token for NuGet API key», а затем 403 … does not have permission to access the specified package, — политика найдена, но не разрешает эту публикацию: проверьте Scopes и Glob
Pattern (выше) и что e-mail учётной записи nuget.org подтверждён. Если в репозитории есть и секрет
NUGET_API_KEY, workflow после такого отказа повторяет публикацию с ним.
B. API-ключ.
- nuget.org → API Keys → Create: scope Push new packages and package versions, Glob Pattern
NetForms*, срок — до года. - В GitHub: Settings → Secrets and variables → Actions → Secrets →
NUGET_API_KEY. - Поставьте напоминание продлить ключ до истечения срока.
После первой публикации зарезервируйте префикс NetForms. (ID prefix reservation, заявка на
account@nuget.org): чужие пакеты с этим префиксом не смогут выглядеть нашими.
VS Code Marketplace
Публикует задача vscode-publish в release.yml: шесть платформенных .vsix под одним id
netforms.netforms-designer, в окружении GitHub marketplace (оно создаётся само при первом запуске).
- Publisher. https://marketplace.visualstudio.com/manage → войти учётной записью Microsoft → Create
publisher, ID
netforms(должен совпадать с"publisher"вdesigner/package.json; если занят — поменяйте там и в документации:netforms.netforms-designer). - Вход для публикации — один из двух способов (заданы оба — сначала B, при отказе A).
A. Токен VSCE_PAT — пять минут, но только до 30 ноября 2026. 1 декабря 2026 Microsoft отключает
глобальные токены Azure DevOps, а Marketplace принимает только их.
- https://dev.azure.com той же учётной записью Microsoft (попросит создать организацию — любое имя) → User settings → Personal access tokens → New Token: Organization: All accessible organizations (с одной организацией будет 403), Scopes: Custom defined → Show all scopes → Marketplace: Manage, срок — до 30.11.2026.
- GitHub: Settings → Secrets and variables → Actions → Secrets →
VSCE_PAT.
B. Managed identity в Microsoft Entra ID — без хранимого ключа, и после 1 декабря 2026. Нужна подписка
Azure (сама identity бесплатна). Вход через GitHub OIDC, как Trusted Publishing у nuget.org; vsce publish --oidc Marketplace пока не поддерживает.
- Azure Portal → Managed Identities → Create: любая resource group, регион и имя (например
netforms-marketplace). В Properties — Client ID и Tenant ID. - На identity: Settings → Federated credentials → Add credential, сценарий GitHub Actions deploying Azure
resources: Organization
Go-Forms, Repository.NetForms(регистр важен), Entity type Environment, Environment namemarketplace. - GitHub: секреты
AZURE_CLIENT_IDиAZURE_TENANT_ID. - Actions → Marketplace identity → Run workflow: он входит как identity и печатает её id Marketplace
(профиль Azure DevOps, не Object ID из Entra). Marketplace → publisher
netforms→ Members → Add → этот id, роль Contributor.
Именно managed identity: с app registration вход проходит, а публикация, по опыту других проектов, падает с
InvalidAccessException.
Шаги 1–2 без поиска пунктов меню (портал на любом языке): значок >_ (Cloud Shell) вверху портала → Bash →
az provider register --namespace Microsoft.ManagedIdentity --wait
az group create -n netforms-marketplace -l westeurope
az identity create -g netforms-marketplace -n netforms-marketplace
az identity federated-credential create -g netforms-marketplace --identity-name netforms-marketplace \
-n github-marketplace --issuer https://token.actions.githubusercontent.com \
--subject repo:Go-Forms/.NetForms:environment:marketplace --audiences api://AzureADTokenExchange
az identity show -g netforms-marketplace -n netforms-marketplace \
--query "{AZURE_CLIENT_ID:clientId, AZURE_TENANT_ID:tenantId}" -o table
Последняя команда печатает значения для секретов шага 3. В русском портале эти два поля легко перепутать: «клиентом» там переводят и client, и tenant; вывод команды подписан именами секретов.
Без обоих способов шаг публикации в Marketplace пропускается с предупреждением, остальной выпуск идёт.
Расширение для уже вышедшей версии (секреты добавлены после выпуска): Actions → Release → Run workflow с галочкой publish. NuGet-пакеты и GitHub Release уже есть — они пропускаются, уйдёт только расширение.
Open VSX (VSCodium, Cursor и др.) — по желанию
Аккаунт на https://open-vsx.org через GitHub, подписать Publisher Agreement,
npx ovsx create-namespace netforms -p <token>, секрет OVSX_PAT. Без секрета шаг пропускается.
GitHub Pages — сделано
Settings → Pages → Source: GitHub Actions включено 2026-09-24, сайт — https://go-forms.github.io/.NetForms/.
Свой домен задаётся там же (Custom domain) плюс запись CNAME у регистратора на go-forms.github.io; файл
CNAME в репозитории при публикации через Actions не нужен.
Лицензия
LICENSE — MIT, правообладатель «NetForms contributors» (как Authors в Directory.Build.props). Если
правообладатель другой — поменяйте в LICENSE и Copyright там же.
Каждый выпуск
- Версия.
<Version>вDirectory.Build.props,Versionпакета NetForms вtemplates/netforms-app/NetFormsApp1.csprojиnetformsVersionвdesigner/package.json— одинаковые (их равенство держатTemplateTestsиdesigner/test/version.test.js; конвертер берёт версию из своей сборки). Версия самого расширения —versionвdesigner/package.json(Marketplace понимает толькоx.y.z), поднимайте её, когда меняется расширение. - Что вошло:
CHANGELOG.md(его текст идёт в GitHub Release) иdesigner/CHANGELOG.md. - Покрытие API:
dotnet run --project tools/NetForms.ApiDiff -- --markdown docs/api; цифры вdocs/compatibility.md,docs/ru/compatibility.md,README.md,README.ru.mdи на главных страницах сайта — по нему. - Прогон:
dotnet test NetForms.slnx,cd designer && npm test; на Windows — с оракулами (см. PLAN.md). - Сухой прогон (по желанию): Actions → Release → Run workflow без publish.
- PR в
mainсо сменой версии → после зелёного CI выпуск идёт сам.
Проверить пакеты локально
dotnet pack NetForms.slnx -c Release -o artifacts/pkg
dotnet pack templates/NetForms.Templates.csproj -c Release -o artifacts/pkg
# шаблон → проект → сборка из локального фида (nuget.config с <add key="local" value=".../artifacts/pkg" />)
dotnet new install artifacts/pkg/NetForms.Templates.0.1.0-preview.1.nupkg
dotnet new netforms -n Hello && cd Hello && dotnet build
# конвертер как tool
dotnet tool install -g NetForms.Convert --prerelease --add-source artifacts/pkg
netforms-convert path/to/WinFormsApp.csproj --apply
# расширение: пакет под платформу и его хост против protocol-теста
cd designer && node scripts/package-targets.js linux-x64
unzip -q netforms-designer-linux-x64.vsix -d /tmp/vsix
NETFORMS_TEST_HOST=/tmp/vsix/extension/host/NetFormsDesigner.Host.dll node --test test/protocol.test.js
# сайт с документацией
cd site && npm ci && npm run build && npm run serve
Тот же путь «пакеты → шаблоны из .nupkg → новый проект собирается из пакетов» каждый раз проходит тест
TemplateTests.ANewProjectFromTheTemplatePackageBuildsFromTheNetFormsPackages.