Skip to content

fix(release): migrate Open VSX publishing to OIDC trusted publishing - W-24666922 - #199

Open
madhur310 wants to merge 4 commits into
mainfrom
ms/W-24666922-ovsx-trusted-publishing
Open

madhur310 wants to merge 4 commits into
mainfrom
ms/W-24666922-ovsx-trusted-publishing

Conversation

@madhur310

@madhur310 madhur310 commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • openvsx-publish-release-vsix.yml: migrates ovsx publish from a PAT (-p $IDEE_OVSX_PAT) to ovsx publish --trusted-publishing (requires id-token: write, now granted). Adds optional vsix-name-pattern/exclude-web-vsix inputs (behavior-preserving defaults).
  • vscode-promote-prerelease.yml / vscode-promote-stable.yml: removes the ovsx matrix leg entirely (no toggle) — IDEE_OVSX_PAT no longer required by either. Adds a release-tag output to vscode-promote-stable.yml (the stable tag it just created).
  • vscode-manual-publish.yml: its publish job's ovsx leg becomes a deliberate no-op step (matrix entry and job status unchanged, so every downstream needs.publish.result == 'success' check in this file is unaffected). Adds a hard error in prepare for source-run-id + registries: ovsx/all, since that path has no GitHub Release for a tag-based trusted-publishing dispatch to target.

(Previously split across this PR and #200 — folded into one here since all of these are the same migration and it's simpler to coordinate one github-workflows branch against each calling repo's own migration PR.)

Context

Open VSX's trusted-publisher match keys off the OIDC token's workflow_ref claim — the run's initiating workflow — not job_workflow_ref (the reusable workflow actually executing a job, which can be nested arbitrarily deep via uses:, even cross-repo, without changing workflow_ref). Open VSX also allows exactly one trusted-publisher registration per extension, enforced server-side (TrustedPublishingService.registerTrustedPublisher in eclipse-openvsx/openvsx) — not just a UI limitation.

Each caller of these reusable workflows was publishing Open VSX from these files' inline PAT-based leg, while also having one or more other top-level workflows for its other release channels — different workflow_ref values for the same extension, which can't all be registered. forcedotcom/salesforcedx-vscode has two such channels (stable, prerelease); forcedotcom/apex-language-support has three (prerelease, stable, and a manual/break-glass publish path). Each caller is migrating Open VSX publishing onto one dedicated top-level workflow that every one of its channels dispatches/triggers directly (not nested via uses:), delegating the actual publish step to this PR's openvsx-publish-release-vsix.yml. That makes removing/redirecting the old PAT-based legs here required, not just cleanup — otherwise every publish double-publishes to Open VSX and IDEE_OVSX_PAT can never be retired.

Validation

  • actionlint on all four changed files: zero new findings vs. main (confirmed via git stash/diff — same pre-existing shellcheck notices as before, exact counts matched).
  • Traced every real caller of all four files via GitHub code search (vscode-promote-prerelease.yml: 2 callers; vscode-promote-stable.yml and vscode-manual-publish.yml: 1 caller each; openvsx-publish-release-vsix.yml: 1 caller) to confirm none are left unaccounted for.
  • End-to-end confirmed against both calling repos, dispatching each one's publishOpenVSXTrusted.yml (pinned to this branch) for real against an already-published, --skip-duplicate-safe tag — no new content reached the registry:
    • forcedotcom/apex-language-support (1 extension): run 41496313940 / publish job — 🔐 Trusted publishing token issued for salesforce.apex-lsp-vscode-extension logged, publish step completed via --skip-duplicate.
    • forcedotcom/salesforcedx-vscode (all 17 Open VSX-published extensions): run 41499926285 / publish job — trusted publishing token issued for every extension, zero ❌ No trusted publisher matches errors.

Test plan

  • forcedotcom/salesforcedx-vscode's and forcedotcom/apex-language-support's migration PRs validate end-to-end against this branch before merge
  • Coordinate merge order: this PR merges alongside/after each caller's compensating PR
  • Register the Open VSX trusted publisher for each affected extension against its new top-level workflow file
  • Confirm a real (or --skip-duplicate-safe) publish logs 🔐 Trusted publishing token issued for salesforce.<extension> / ...apex-lsp-vscode-extension
  • Confirm vscode-manual-publish.yml's new validation fires for source-run-id + registries: all

@W-24666922@

…- W-24666922

openvsx-publish-release-vsix.yml and vscode-promote-prerelease.yml both ran
`ovsx publish` against a PAT (-p $OVSX_PAT / $IDEE_OVSX_PAT). Switches both
to `ovsx publish --trusted-publishing`, which exchanges this job's GitHub
Actions OIDC ID token for a short-lived publish token instead -- requires
`id-token: write`, which both workflows now grant.

Open VSX's trusted-publisher config binds one identity per extension to the
exact workflow file that requests the OIDC token (its job_workflow_ref).
vscode-promote-prerelease.yml's `ovsx` leg previously ran its own `ovsx
publish` inline, inside the same matrix job as `vsce` -- a different file
from openvsx-publish-release-vsix.yml, which the stable release path uses.
That would mean two different job_workflow_ref values for the same
extension's Open VSX publishes, which a single trusted-publisher entry
can't match.

Split the `ovsx` leg out of that matrix job (GitHub Actions won't let a
`uses:`-based job share a matrix with per-leg different targets) into its
own `publish-ovsx` job that delegates to openvsx-publish-release-vsix.yml
via `uses:`, instead of duplicating the ovsx-publish logic. Every Open VSX
publish for a given extension -- stable, stable hotfix, prerelease,
prerelease/emergency hotfix -- now requests its OIDC token from that one
file. openvsx-publish-release-vsix.yml gained `vsix-name-pattern` and
`exclude-web-vsix` inputs (both optional, default-compatible) so the
delegated call can reproduce vscode-promote-prerelease.yml's existing
filtering for monorepo/multi-extension callers.

vsce/Marketplace publishing (VSCE_PERSONAL_ACCESS_TOKEN) is untouched.
Open VSX's trusted-publisher check matches the OIDC token's workflow_ref
claim (the top-level/triggering workflow), not job_workflow_ref (the
reusable workflow actually executing a job) -- confirmed against
eclipse-openvsx/openvsx's TrustedPublishingService/
GitHubTrustedPublishingProviderSupport source. Consolidating this
reusable workflow's ovsx leg onto openvsx-publish-release-vsix.yml never
closed that gap: salesforcedx-vscode's stable and prerelease flows are
started by two different top-level workflow files regardless of what
runs underneath them, and Open VSX only allows one trusted-publisher
registration per extension (a hard server-side check).

The real fix has to live in salesforcedx-vscode's own top-level
workflows instead, so this reusable workflow goes back to vsce-only.
Keeps the openvsx-publish-release-vsix.yml PAT -> --trusted-publishing
migration, which the new salesforcedx-vscode-side design still delegates
to.
…s - W-24666922

Folds the removal work from the now-closed #200 into this PR, since both
are the same migration and coordinating one github-workflows branch against
each calling repo's own migration PR is simpler than two.

Removes the `ovsx` matrix leg from vscode-promote-prerelease.yml and
vscode-promote-stable.yml entirely (no toggle). Each of these reusable
workflows' real callers (forcedotcom/salesforcedx-vscode,
forcedotcom/apex-language-support) are migrating their Open VSX publishing
onto a dedicated top-level workflow (publishOpenVSXTrusted.yml) that
delegates to this PR's openvsx-publish-release-vsix.yml instead -- required,
not optional, since Open VSX's trusted-publisher match keys off workflow_ref
(the run's initiating workflow) and allows only one registration per
extension.

Also adds a `release-tag` output to vscode-promote-stable.yml (the stable
tag it just created), so a caller can dispatch its own Open VSX publish for
that exact tag afterward.
…o the caller - W-24666922

Same migration, applied to the third apex-language-support entry point that
can publish Open VSX (promote-prerelease.yml and promote-stable.yml already
covered). vscode-manual-publish.yml is this repo's only real caller
(confirmed via GitHub code search), so no toggle needed.

The `publish` job's ovsx leg becomes a deliberate no-op step (not a removed
step, and not a removed matrix entry) specifically so the job's own
success/skip status -- and every downstream needs.publish.result ==
'success' check in this file -- stays exactly as it was. The caller is
expected to dispatch its own single top-level Open VSX workflow afterward,
for the version-tag path only: adds a hard error in `prepare` for
source-run-id + ovsx/all, since a branch-CI-run artifact has no GitHub
Release for a tag-based trusted-publishing dispatch to target, and silently
never publishing to Open VSX for that combination would be worse than
failing loudly.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant