mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-17 15:24:40 +01:00
* Add merge script for extension configuration policies from distro Adds build/lib/policies/mergeExtensionPolicies.ts which fetches the distro's product.json (at the commit pinned in package.json) and merges extensionConfigurationPolicy entries into policyData.jsonc. The --export-policy-data step only captures policies from the OSS configuration registry. Extension policies (e.g., Copilot settings) are defined in vscode-distro's product.json and are not available in the OSS dev build. This merge script bridges that gap. Workflow: ./scripts/code.sh --export-policy-data && node build/lib/policies/mergeExtensionPolicies.ts Also updates: - policyExport integration test to run the merge step - add-policy skill documentation with extension policy lifecycle * Simplify extension policy format: drop localization block from distro - mergeExtensionPolicies.ts now reads only description/category from the distro and synthesizes localization key/value pairs internally - Integration test gracefully skips merge step when distro is unavailable - Updated SKILL.md to document the simplified distro format * docs: use gh auth token in policy export command * Handle old distro format missing description/category fields * docs: add troubleshooting section for merge step in policy skill * Require description and category fields in extension policy entries * Add extension configuration policies to policyData.jsonc * Address PR feedback: fix disclaimer, log targetPath, strip GITHUB_TOKEN from test * fix: revert extension policies from policyData.jsonc, remove console.log from test Extension policies should only be added after the distro PR merges. Test runner disallows console output in tests. * Add mock distro test for mergeExtensionPolicies, remove merge from export test - mergeExtensionPolicies.ts: add DISTRO_PRODUCT_JSON env var to override the distro path (for testing without private repo access) - New test: creates a mock product.json, runs the merge script, verifies policies are added correctly and idempotently - Export test: no longer runs the merge step (avoids needing distro access or GITHUB_TOKEN in CI) * Update distro and regenerate policyData.jsonc with extension policies * Fix CI: add extension policy fixture for export test The export test now runs mergeExtensionPolicies using a checked-in fixture file instead of requiring distro access or GITHUB_TOKEN. When extension policies change in the distro, regenerate both policyData.jsonc and the fixture file. * Integrate extension policy merge into --export-policy-data - Removed mergeExtensionPolicies.ts — no separate CLI tool needed - --export-policy-data now reads build/lib/policies/extensionPolicies.json and merges extension policies into the output automatically - Single command workflow: ./scripts/code.sh --export-policy-data - Simplified test — no merge step, no GITHUB_TOKEN, no distro access - Updated SKILL.md to document the simplified workflow * Dynamic distro reading: --export-policy-data fetches from distro directly - policyExport.contribution.ts reads distro product.json dynamically: 1. DISTRO_PRODUCT_JSON env var (for testing) 2. .build/distro/mixin/stable/product.json (local checkout) 3. GitHub API with GITHUB_TOKEN (remote fetch) - New scripts/export-policy-data.sh wrapper: sets up GITHUB_TOKEN via gh CLI and runs the export - Deleted build/lib/policies/extensionPolicies.json (no static copy) - Test uses DISTRO_PRODUCT_JSON with a fixture file - Uses sandbox process.env and VSBuffer (renderer-safe) * Replace bash wrapper with cross-platform TS script - New build/lib/policies/exportPolicyData.ts: handles transpilation, GITHUB_TOKEN setup via gh CLI, and runs --export-policy-data - Added 'npm run export-policy-data' script to package.json - Removed scripts/export-policy-data.sh - Updated SKILL.md and test error message * Use OAuth device flow for GitHub token acquisition exportPolicyData.ts now acquires tokens via: 1. GITHUB_TOKEN env var (if set) 2. gh CLI (fast, non-interactive) 3. GitHub OAuth device flow (interactive, no dependencies) Based on vscode-copilot-chat's getToken.mts pattern. * Fix error messages to reference npm run export-policy-data * Fix disclaimer to reference npm run export-policy-data, clean up stale refs * Clarify test fixture is static and not expected to track distro changes * Add inline comment in test clarifying fixture is static * SKILL.md: add step to update distro commit hash in package.json * Remove inline comment per PR feedback * Remove local .build/distro/ fallback path per PR feedback
86 lines
3.2 KiB
TypeScript
86 lines
3.2 KiB
TypeScript
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
import { execSync, execFileSync } from 'child_process';
|
|
import { resolve } from 'path';
|
|
|
|
const rootPath = resolve(import.meta.dirname, '..', '..', '..');
|
|
|
|
// VS Code OAuth app client ID (same as the GitHub Authentication extension)
|
|
const CLIENT_ID = '01ab8ac9400c4e429b23';
|
|
|
|
/**
|
|
* Acquires a GitHub token via the OAuth device flow.
|
|
* Opens the browser for the user to authorize, then polls for the token.
|
|
*/
|
|
async function acquireTokenViaDeviceFlow(): Promise<string> {
|
|
const response1 = await (await fetch('https://github.com/login/device/code', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ client_id: CLIENT_ID, scope: 'repo' }),
|
|
headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' },
|
|
})).json() as { user_code: string; device_code: string; verification_uri: string; expires_in: number; interval: number };
|
|
|
|
console.log(`\n Copy this code: ${response1.user_code}`);
|
|
console.log(` Then open: ${response1.verification_uri}`);
|
|
console.log(` Waiting for authorization (up to ${response1.expires_in}s)...\n`);
|
|
|
|
let expiresIn = response1.expires_in;
|
|
while (expiresIn > 0) {
|
|
await new Promise(resolve => setTimeout(resolve, 1000 * response1.interval));
|
|
expiresIn -= response1.interval;
|
|
|
|
const response2 = await (await fetch('https://github.com/login/oauth/access_token', {
|
|
method: 'POST',
|
|
body: JSON.stringify({
|
|
client_id: CLIENT_ID,
|
|
device_code: response1.device_code,
|
|
grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
|
|
}),
|
|
headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' },
|
|
})).json() as { access_token?: string };
|
|
|
|
if (response2.access_token) {
|
|
return response2.access_token;
|
|
}
|
|
}
|
|
|
|
throw new Error('Timed out waiting for GitHub authorization');
|
|
}
|
|
|
|
// Ensure sources are transpiled
|
|
console.log('Transpiling client sources...');
|
|
execSync('npm run transpile-client', { cwd: rootPath, stdio: 'inherit' });
|
|
|
|
// Set up GITHUB_TOKEN if not already set
|
|
if (!process.env['GITHUB_TOKEN'] && !process.env['DISTRO_PRODUCT_JSON']) {
|
|
// Try gh CLI first (fast, non-interactive)
|
|
let token: string | undefined;
|
|
try {
|
|
token = execFileSync('gh', ['auth', 'token'], { encoding: 'utf8' }).trim();
|
|
console.log('Set GITHUB_TOKEN from gh CLI.');
|
|
} catch {
|
|
// Fall back to OAuth device flow (interactive)
|
|
console.log('gh CLI not available, starting GitHub OAuth device flow...');
|
|
token = await acquireTokenViaDeviceFlow();
|
|
console.log('GitHub authorization successful.');
|
|
}
|
|
|
|
process.env['GITHUB_TOKEN'] = token;
|
|
}
|
|
|
|
// Run the export
|
|
console.log('Exporting policy data...');
|
|
const codeScript = process.platform === 'win32'
|
|
? resolve(rootPath, 'scripts', 'code.bat')
|
|
: resolve(rootPath, 'scripts', 'code.sh');
|
|
|
|
execSync(`"${codeScript}" --export-policy-data`, {
|
|
cwd: rootPath,
|
|
stdio: 'inherit',
|
|
env: process.env,
|
|
});
|
|
|
|
console.log('\nPolicy data exported to build/lib/policies/policyData.jsonc');
|