Ship the vsce toolchain as a Fallout plugin, and align the release pipeline with the framework - #3
Merged
Conversation
Fallout 10.4.0 shipped to nuget.org, so the dogfood build no longer needs the private GitHub Packages feed or its token: - Pin Fallout.Common and the CLI tool to 10.4.0. The tool's package id changed on GA (fallout.globaltools -> fallout.globaltool). - Drop the github package source, its credentials, and the source mapping from nuget.config; nuget.org is now the only feed. Verified that Fallout.Common 10.4.0 resolves from api.nuget.org. - Drop FALLOUT_PACKAGES_TOKEN from the publish workflow. Nerdbank.GitVersioning stamps stable builds with a four-component version (10.4.0.15+f16e0f1441), so FrameworkVersion() now picks the height out of the fourth component rather than assuming a prerelease counter. Returning the release verbatim would emit 10.4.0.15, which is not valid semver and fails marketplace validation. The extension version therefore moves from calendar versioning to tracking the framework release line: 10.4.15 against Fallout 10.4. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The VS Marketplace rejects semver prerelease versions outright, so an RC cannot be expressed as 10.4.15-rc.1. Instead an RC is an ordinary three-integer version whose VSIX manifest carries a pre-release bit (Microsoft.VisualStudio.Code.PreRelease), set at package time. The rc suffix lives only on the git tag and the GitHub release. - Add a PreRelease build parameter, independent of the framework's own version state so the extension can cut an RC while Fallout is GA. It ORs with the framework-derived prerelease flag. - Split the workflow into package / prerelease / publish. An rc tag now routes to a GitHub pre-release with the .vsix attached and never reaches a marketplace, which the previous 'v*' trigger would have done. - Narrow the tag patterns so a stable tag and an rc tag cannot match each other's pattern, and anything else triggers nothing at all. - Gate the stable publish on the 'marketplace' environment, so a tag push alone cannot publish without an approval. Verified locally: PreRelease=true packages 10.4.15 with Microsoft.VisualStudio.Code.PreRelease="true" in extension.vsixmanifest; the default still packages it as a stable release. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Emitted by the Fallout build itself when the parameter was added. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Two changes that belong together, because the plugin is what makes the version mapping expressible. plugins/Fallout.Vsce — the vsce/ovsx toolchain as a Fallout plugin rather than an in-tree framework component. This is the pilot for the plugin shape ADR-0001 sketches for Octopus: tool wrappers in the same form the Tooling.Generator emits (ToolTasks + [Command] ToolOptions + [Argument] properties + fluent [Builder] setters), plus IPackVsix / IPublishVsix components mirroring Fallout.Components' IPack / IPublish. Registries are declared as data (VsixPublishTarget, the VSIX analogue of PublishTarget) and narrowed per-run with --publish-vsix-to, so adding Open VSX was a list entry rather than a new target. Versioning now matches the framework: Nerdbank.GitVersioning over version.json, replacing the hand-rolled parse of the pinned assembly's informational version. version.json pins the 10.4 line and the build asserts it still matches the referenced Fallout.Common, so the two cannot drift apart silently — the extension's major.minor is a documented promise about which framework line it targets. MarketplaceVersion holds the one rule neither NB.GV nor the marketplaces will enforce for us: three integers, no prerelease. It is where the four-component stable-build case and the rc case both get normalised. Also fixes two things this surfaced: - .vscodeignore did not exclude plugins/, so a package built after adding it shipped 30 files of C# source and build output to the marketplace. - package.json's version is now 0.0.0. The build stamps the real one at package time, and a hardcoded number next to it was a second source of truth guaranteed to drift. The npm package/publish scripts are gone for the same reason — the plugin owns that path now. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Brings the pipeline in line with the framework repo so both are read with one mental model. Changelog by PR label: .github/release.yml mirrors Fallout's taxonomy (breaking-change / enhancement / bug / security / dependencies / documentation, plus skip-changelog), and releases are cut with --generate-notes so the label on a PR is what lands in the notes. The four missing labels now exist on the repo with the same colours. CHANGELOG.md stays hand-written and separate: it ships inside the .vsix and is what the marketplace renders on the extension page. Channels as environments, mirroring publish-packages-release.yml: validate-ref -> pack -> three channel jobs, each in its own environment. GitHub Releases is the ungated pre-stage; vs-marketplace and open-vsx are promotion targets behind an opt-in workflow_dispatch flag AND an approval gate, the same two layers Fallout puts in front of nuget.org. A tag push can no longer reach a marketplace at all, which the previous single-gate shape allowed. The old 'marketplace' environment is replaced by the three. The promotion jobs publish the exact artifact the pack job produced (--skip PackVsix) rather than rebuilding, so what gets approved is what ships. The workflow_dispatch boolean is compared against both true and 'true' — the REST API can only send strings, and a bare == true would silently skip every CLI-triggered promotion while reporting success. RELEASING.md documents the runbook, including why a release candidate is not -rc.N and why RCs deliberately stop at GitHub: publishing a version as a marketplace pre-release burns that number for the GA. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ding Fallout.Components was referenced by both projects but appeared only in doc comments — the plugin's components mirror its shape without depending on it, so a consumer can take Fallout.Vsce without pulling that package in. CHANGELOG.md's top section is now "## Unreleased". The patch component is a git height, so any commit touching a filtered path moves it; hardcoding a number in a file that is itself a filtered path meant the heading was stale the moment it was written. It gets renamed when the release is cut, which RELEASING.md now spells out. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Generated CI gate: .github/workflows/build.yml is now emitted from a [GitHubActions] attribute in build/Build.CI.GitHubActions.cs. The repo had no PR gate at all before this — nothing ran on a pull request. publish.yml stays hand-written, for the same category of reason the framework repo hand-writes publish-packages-release.yml. Two specifics: the generator emits checkout/cache/setup-dotnet and has no hook for extra steps, so it cannot set up Node with npm caching; and it emits one job per image, with no notion of the per-channel fan-out into GitHub Environments with approval gates that the release path needs. The gate can live with the runner's preinstalled Node; a release cannot. Both files only provision toolchains and route channels — every step that does anything is a Fallout target, so the build itself is defined in C# either way. Dropped CHANGELOG.md. The label taxonomy already records what changed, and a hand-maintained file could not state its own version correctly: the patch is a git height, so the number is not settled until the release is cut, and the changelog commit itself moves it. If the marketplace page ever wants a rendered changelog it should be generated into the .vsix at pack time. Renamed the repo to Fallout.Extensions.VSCode. Verified nothing upstream depends on the old name: vsce reads the repository URL from package.json (for the marketplace link and for resolving relative README assets), never from the GitHub repo name, and extension identity is publisher.name — fallout.fallout. Unlike a Homebrew tap, neither registry constrains it. package.json, the environment URLs and PackageProjectUrl are updated. Action versions aligned with the rest of the org (checkout@v7, cache@v6, setup-node@v6, setup-dotnet@v6, upload-artifact@v7, download-artifact@v8). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Targets Fallout 10.4.0 GA, moves the vsce/ovsx toolchain into a Fallout plugin, and brings changelog, versioning and release channels in line with the framework repo.
Fallout.Vsce — the toolchain as a plugin
plugins/Fallout.Vsceis the pilot for shipping provider integrations as plugins rather than in-tree components, the shape ADR-0001 proposes for Octopus. It's the smaller sibling that proves it first.VsceTasks,OvsxTasks) in the exact formTooling.Generatoremits —ToolTasks+[Command]ToolOptions+[Argument]properties + fluent[Builder]setters.IPackVsix/IPublishVsixmirroringFallout.Components'IPack/IPublish; registries are declared as data (VsixPublishTarget, the VSIX analogue ofPublishTarget) and narrowed with--publish-vsix-to. Adding Open VSX was a list entry, not a new target.The plugin shape holds up. Nothing needed an escape hatch into framework internals. Two things made it work, both worth knowing for the Octopus plugin:
Fallout.SourceGeneratorsships as an analyzer insideFallout.Common, so a downstream project gets the codegen for free; andToolOptions.ProcessToolPathis the right seam for tools that live innode_modules/.binrather than onPATH. It depends onFallout.Commonalone and is packable, so extracting it to its own feed is a build-file change.Versioning
Nerdbank.GitVersioning over
version.json, as in the framework repo, replacing a hand-rolled parse of the pinned assembly's informational version. The build now asserts the declared line still matches the referencedFallout.Common, somajor.minorremains an enforced promise about which framework line the extension targets rather than a hopeful comment.MarketplaceVersionholds the rule neither NB.GV nor the registries enforce: three integers, no prerelease.Release channels
validate-ref → pack →three channel jobs, each bound to its own GitHub Environment, mirroringpublish-packages-release.yml.github-releasesvs-marketplaceopen-vsxA tag push can no longer reach a marketplace; promotion needs the flag and an approval, the two layers Fallout puts in front of nuget.org. Promotion publishes the exact packed artifact (
--skip PackVsix), so what's approved is what ships.Why release candidates aren't
-rc.NBoth registries take exactly three integers —
vscethrowsThe VS Marketplace doesn't support prerelease versions. An RC is an ordinary triple carrying a pre-release bit in the VSIX manifest, with-rc.Nliving only on the tag. Since a version is pre-release or stable and never both, publishing an RC to a marketplace would burn that number for the GA — so RCs stop at GitHub.Changelog
.github/release.ymlmirrors the framework's label taxonomy;--generate-notesturns PR labels into release notes.CHANGELOG.mdis removed: it duplicated the labels, and couldn't state its own version correctly since the patch is a git height not settled until the release is cut.Also
.github/workflows/build.ymlis emitted from[GitHubActions]. The repo previously ran nothing on a PR.publish.ymlstays hand-written — the generator can't set up Node or express per-channel environment gating — matching how the framework splits generated CI from hand-written publish workflows.Fallout.Extensions.VSCode. Verified nothing upstream depends on the old name: vsce reads the repository URL frompackage.json, and extension identity ispublisher.name.FALLOUT_PACKAGES_TOKENand the private feed — Fallout 10.4.0 restores from nuget.org.Bugs this surfaced
.vscodeignoredidn't excludeplugins/— a package built after adding it shipped 30 files of C# source to the marketplace..gitignoreonly coveredbuild/bin|obj, so plugin binaries were staged.package.jsonhardcoded a version next to a computed one. Now0.0.0; the build stamps the real one.Verification
Packaged locally, stable and RC:
10.4.18, 12 files,Microsoft.VisualStudio.Code.PreRelease="true"present only on the RC.--publish-vsix-toand--skip PackVsixboth parse. Nothing has been published to either marketplace.🤖 Generated with Claude Code