@mnci/cli 4.12.4 → 4.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -4
- package/dist/cli.js +35 -8
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1479,10 +1479,18 @@ extension:
|
|
|
1479
1479
|
Linux binaries. Unix file modes survive into the package, so the binary stays
|
|
1480
1480
|
executable. Resolve it at runtime from `context.extensionPath` + `bin/`.
|
|
1481
1481
|
- **`nx-release-publish`** runs `vsce publish --packagePath <every vsix>
|
|
1482
|
-
--skip-duplicate`
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1482
|
+
--skip-duplicate` with a Marketplace credential, and skips with a message without
|
|
1483
|
+
one. It depends on `package`, so it ships the version `nx release` just wrote. Two
|
|
1484
|
+
credentials work, and Entra ID wins when both are configured:
|
|
1485
|
+
- **Microsoft Entra ID, no secret (GitHub Actions).** When the `AZURE_CLIENT_ID`
|
|
1486
|
+
and `AZURE_TENANT_ID` repository variables exist, the release job signs in with
|
|
1487
|
+
`azure/login` through OIDC (`id-token: write`) and publishes with
|
|
1488
|
+
`vsce publish --azure-credential`. Nothing is stored and nothing expires. Setup
|
|
1489
|
+
is below.
|
|
1490
|
+
- **`VSCE_PAT`**, a Marketplace personal access token as a CI secret, in both
|
|
1491
|
+
providers. Creating one needs an Azure DevOps organization, which now needs an
|
|
1492
|
+
Azure subscription, and global PATs are reported to retire on 2026-12-01. Azure
|
|
1493
|
+
Pipelines has only this route for now.
|
|
1486
1494
|
- **Debugging**: an `<name>: debug` launch entry (`extensionHost`) opens a second
|
|
1487
1495
|
VS Code window with the extension loaded, after the `<name>: build (development)`
|
|
1488
1496
|
task, which keeps source maps.
|
|
@@ -1493,6 +1501,35 @@ Both targets run `tools/vscode-extension.cjs`, a workspace file mnci owns (like
|
|
|
1493
1501
|
`package.json` `bin` and runs them with `node`, with no shell, so a workspace path
|
|
1494
1502
|
containing spaces works on Windows.
|
|
1495
1503
|
|
|
1504
|
+
### Publishing with Microsoft Entra ID (one-time setup)
|
|
1505
|
+
|
|
1506
|
+
Think of it as a guest list rather than a key. GitHub vouches for "a job in
|
|
1507
|
+
`<owner>/<repo>` on `main`", Entra ID checks that against the federated credential
|
|
1508
|
+
and issues a short-lived token, and the Marketplace accepts the token because the
|
|
1509
|
+
identity is a member of the publisher.
|
|
1510
|
+
|
|
1511
|
+
1. **A tenant.** A free Azure account creates one. No billable resource is needed.
|
|
1512
|
+
2. **An app registration** (Entra admin center → App registrations → New
|
|
1513
|
+
registration, single tenant, no redirect URI). Prefer it to a managed identity:
|
|
1514
|
+
it lives in the tenant, not a subscription, so a lapsed trial does not stop
|
|
1515
|
+
publishing. Note its Application (client) ID and Directory (tenant) ID.
|
|
1516
|
+
3. **A federated credential** on it (Certificates & secrets → Federated
|
|
1517
|
+
credentials → GitHub Actions deploying Azure resources): your owner and
|
|
1518
|
+
repository, entity type *Branch*, branch `main`. Repositories created after
|
|
1519
|
+
2026-07-15 (or opted in) send GitHub's immutable subject, which carries the
|
|
1520
|
+
numeric IDs: `repo:<owner>@<owner_id>/<repo>@<repo_id>:ref:refs/heads/main`.
|
|
1521
|
+
The form asks for both IDs; `GET /repos/<owner>/<repo>` returns them as
|
|
1522
|
+
`owner.id` and `id`.
|
|
1523
|
+
4. **Repository variables** (Settings → Secrets and variables → Actions →
|
|
1524
|
+
Variables, not Secrets): `AZURE_CLIENT_ID` and `AZURE_TENANT_ID`.
|
|
1525
|
+
5. **The identity as a publisher member.** The Marketplace's Members page wants
|
|
1526
|
+
the identity's Azure DevOps profile ID, which only the identity can read, so read
|
|
1527
|
+
it from a workflow run on `main` after `azure/login`:
|
|
1528
|
+
`az rest -u https://app.vssps.visualstudio.com/_apis/profile/profiles/me
|
|
1529
|
+
--resource 499b84ac-1321-427f-aa17-267ca6975798 --query id -o tsv`. Add that ID
|
|
1530
|
+
under Members with the **Contributor** role, then confirm with
|
|
1531
|
+
`npx @vscode/vsce verify-pat --azure-credential <publisher>` in the same job.
|
|
1532
|
+
|
|
1496
1533
|
Not built yet: integration tests through `@vscode/test-cli` (they download VS Code
|
|
1497
1534
|
and need a display, so they would be gated like the Go and Flutter sections).
|
|
1498
1535
|
|
package/dist/cli.js
CHANGED
|
@@ -1020,7 +1020,8 @@ var ACTION_VERSIONS = {
|
|
|
1020
1020
|
"actions/checkout": "v7",
|
|
1021
1021
|
"actions/setup-node": "v7",
|
|
1022
1022
|
"actions/setup-dotnet": "v6",
|
|
1023
|
-
"actions/upload-artifact": "v7"
|
|
1023
|
+
"actions/upload-artifact": "v7",
|
|
1024
|
+
"azure/login": "v3"
|
|
1024
1025
|
};
|
|
1025
1026
|
var NPM_VERSION = "11";
|
|
1026
1027
|
var DOTNET_SDK_VERSION = "10.0.x";
|
|
@@ -1433,6 +1434,11 @@ permissions:
|
|
|
1433
1434
|
# Lets the release step push the version tag nx release creates back to main,
|
|
1434
1435
|
# and (github-only provider) create the GitHub Release itself.
|
|
1435
1436
|
contents: write
|
|
1437
|
+
# Lets azure/login exchange this job's OIDC token for a Microsoft Entra ID one,
|
|
1438
|
+
# which is how a VS Code extension reaches the Marketplace with no stored secret.
|
|
1439
|
+
# A token minted on a pull request cannot use it: the federated credential is
|
|
1440
|
+
# pinned to refs/heads/main.
|
|
1441
|
+
id-token: write
|
|
1436
1442
|
|
|
1437
1443
|
jobs:
|
|
1438
1444
|
ci:
|
|
@@ -1634,14 +1640,31 @@ ${npmAuthPreflight(registryKind) ? `
|
|
|
1634
1640
|
# which is why 'nx release' pushes the tag itself here \u2014 see
|
|
1635
1641
|
# releaseConfig's remarks for why that is safe on this Nx version and
|
|
1636
1642
|
# why every other provider combination keeps the explicit push step below.` : ""}
|
|
1643
|
+
# Signs in to Microsoft Entra ID as the Marketplace publishing identity (an
|
|
1644
|
+
# app registration with a federated credential for this repository's main
|
|
1645
|
+
# branch), so the release step publishes VS Code extensions with
|
|
1646
|
+
# 'vsce publish --azure-credential' and no token. Runs only when the
|
|
1647
|
+
# AZURE_CLIENT_ID and AZURE_TENANT_ID repository variables exist and the
|
|
1648
|
+
# workspace has an extension (every one ships a .vscodeignore). No Azure
|
|
1649
|
+
# subscription is needed. Setup: README, 'VS Code extensions'.
|
|
1650
|
+
- uses: azure/login@${ACTION_VERSIONS["azure/login"]}
|
|
1651
|
+
name: Sign in to Microsoft Entra ID (VS Code Marketplace)
|
|
1652
|
+
if: \${{ ${onMain} && vars.AZURE_CLIENT_ID != '' && hashFiles('apps/*/.vscodeignore') != '' }}
|
|
1653
|
+
with:
|
|
1654
|
+
client-id: \${{ vars.AZURE_CLIENT_ID }}
|
|
1655
|
+
tenant-id: \${{ vars.AZURE_TENANT_ID }}
|
|
1656
|
+
allow-no-subscriptions: true
|
|
1657
|
+
|
|
1637
1658
|
- run: ${releaseGuard(pythonPublishEnvFragment(pythonPublishUrl2, registryKind), nugetPublishEnvFragment(nugetFeedUrl2))}
|
|
1638
1659
|
name: Release \u2014 version, tag${githubReleases ? ", publish and GitHub Release" : " and publish"} (npm + Python + C# + VS Code)
|
|
1639
1660
|
if: \${{ ${onMain} }}
|
|
1640
1661
|
env:
|
|
1641
1662
|
${npmAuthName}: ${npmAuthValue}${pypiTokenEnvLine(registryKind, (name) => `\${{ secrets.${name} }}`, " ".repeat(10))}
|
|
1642
1663
|
RELEASE_SPECIFIER: \${{ vars.RELEASE_SPECIFIER }}
|
|
1643
|
-
# A VS Code extension publishes with
|
|
1644
|
-
#
|
|
1664
|
+
# A VS Code extension publishes with Entra ID when the sign-in step
|
|
1665
|
+
# above ran (VSCE_AUTH=entra), else with the VSCE_PAT token;
|
|
1666
|
+
# tools/vscode-extension.cjs skips the Marketplace with neither.
|
|
1667
|
+
VSCE_AUTH: \${{ vars.AZURE_CLIENT_ID != '' && 'entra' || '' }}
|
|
1645
1668
|
VSCE_PAT: \${{ secrets.VSCE_PAT }}${githubReleases ? `
|
|
1646
1669
|
GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }}` : ""}
|
|
1647
1670
|
${githubReleases ? "" : `
|
|
@@ -2139,17 +2162,20 @@ function renameScaffoldPlaceholder(projectRoot, name) {
|
|
|
2139
2162
|
(0, import_node_fs3.renameSync)(spec, renamed);
|
|
2140
2163
|
writeFileEnsured(
|
|
2141
2164
|
renamed,
|
|
2142
|
-
(0, import_node_fs3.readFileSync)(renamed, "utf8")
|
|
2165
|
+
repointSpecifier((0, import_node_fs3.readFileSync)(renamed, "utf8"), `./${name}`, `./${name}.use-case`)
|
|
2143
2166
|
);
|
|
2144
2167
|
}
|
|
2145
2168
|
const barrel = (0, import_node_path3.join)(projectRoot, "src", "index.ts");
|
|
2146
2169
|
if ((0, import_node_fs3.existsSync)(barrel)) {
|
|
2147
2170
|
writeFileEnsured(
|
|
2148
2171
|
barrel,
|
|
2149
|
-
(0, import_node_fs3.readFileSync)(barrel, "utf8")
|
|
2172
|
+
repointSpecifier((0, import_node_fs3.readFileSync)(barrel, "utf8"), `./lib/${name}`, `./lib/${name}.use-case`)
|
|
2150
2173
|
);
|
|
2151
2174
|
}
|
|
2152
2175
|
}
|
|
2176
|
+
function repointSpecifier(source, from, to) {
|
|
2177
|
+
return source.replaceAll(`${from}'`, () => `${to}'`).replaceAll(`${from}.js'`, () => `${to}.js'`);
|
|
2178
|
+
}
|
|
2153
2179
|
function ensureNxPeerOverrides(workspaceRoot) {
|
|
2154
2180
|
const manifestPath = (0, import_node_path3.join)(workspaceRoot, "package.json");
|
|
2155
2181
|
if (!(0, import_node_fs3.existsSync)(manifestPath)) {
|
|
@@ -3890,16 +3916,17 @@ function publishExtension (manifest, sidecar, dryRun) {
|
|
|
3890
3916
|
|
|
3891
3917
|
return
|
|
3892
3918
|
}
|
|
3919
|
+
const entra = process.env.VSCE_AUTH === 'entra'
|
|
3893
3920
|
const token = process.env.VSCE_PAT ?? ''
|
|
3894
|
-
if (token === '' || /^\$\(.*\)$/.test(token)) {
|
|
3895
|
-
console.log('
|
|
3921
|
+
if (!entra && (token === '' || /^\$\(.*\)$/.test(token))) {
|
|
3922
|
+
console.log('No Marketplace credential - skipping the Marketplace publish of ' + manifest.name + '. Set the AZURE_CLIENT_ID and AZURE_TENANT_ID variables (Microsoft Entra ID) or the VSCE_PAT secret to publish.')
|
|
3896
3923
|
|
|
3897
3924
|
return
|
|
3898
3925
|
}
|
|
3899
3926
|
const files = vsixFiles(project, sidecar)
|
|
3900
3927
|
const missing = files.filter(file => !existsSync(file))
|
|
3901
3928
|
if (missing.length > 0) fail('Nothing to publish: ' + missing.join(', ') + ' not found - run the package target first.')
|
|
3902
|
-
run('@vscode/vsce', 'vsce', ['publish', '--packagePath', ...files, '--skip-duplicate'])
|
|
3929
|
+
run('@vscode/vsce', 'vsce', ['publish', ...(entra ? ['--azure-credential'] : []), '--packagePath', ...files, '--skip-duplicate'])
|
|
3903
3930
|
}
|
|
3904
3931
|
|
|
3905
3932
|
const [command, projectRoot, ...rest] = process.argv.slice(2)
|