Compare commits

...

10 Commits

Author SHA1 Message Date
Asher
be537ce77a Optimize builtin copilot extension (#7757) 2026-04-16 00:07:15 -08:00
Asher
cc8f0b7348 Strip sourcemaps (#7756)
This will significantly reduce the size, and for errors we should be
able to map them as necessary.
2026-04-15 22:56:00 -08:00
Olivier Benz
7cc2270228 Update Code to 1.116.0 (#7754)
* Update Code to 1.116.0

* Add copilot extension build

Seems the vscode build requires this separately now.

* Disable welcome popup

A giant modal window asking you to sign in for AI features is blocking
the tests.  Rather than have to click through it, disable it.  It looks like
this has to be a user setting, so switch to that instead of machine (we
used machine because user settings were in the browser, but they have
been since moved back to disk).

---------

Co-authored-by: Asher <ash@coder.com>
2026-04-15 15:05:17 -08:00
dependabot[bot]
34ac5f47de chore: bump basic-ftp from 5.2.0 to 5.2.1 (#7749) 2026-04-10 11:51:18 -08:00
dependabot[bot]
523c0cbaa7 chore: bump docker/setup-buildx-action from 3.12.0 to 4.0.0 (#7732) 2026-04-10 11:50:15 -08:00
dependabot[bot]
05f481d2f0 chore: bump codecov/codecov-action from 5.5.3 to 6.0.0 (#7731) 2026-04-08 15:29:57 -08:00
dependabot[bot]
c66372452f chore: bump docker/setup-qemu-action from 3.7.0 to 4.0.0 (#7729) 2026-04-08 13:47:30 -08:00
dependabot[bot]
aee8825558 chore: bump azure/setup-helm from 4.3.1 to 5.0.0 (#7728) 2026-04-08 13:46:54 -08:00
dependabot[bot]
f612511974 chore: bump awalsh128/cache-apt-pkgs-action from 1.5.3 to 1.6.0 (#7727) 2026-04-08 13:46:25 -08:00
dependabot[bot]
287f8ecd56 chore: bump path-to-regexp from 8.3.0 to 8.4.0 (#7722) 2026-04-08 13:46:01 -08:00
13 changed files with 202 additions and 50 deletions

View File

@@ -90,7 +90,7 @@ jobs:
if: needs.changes.outputs.helm == 'true'
steps:
- uses: actions/checkout@v6
- uses: azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4 # v4
- uses: azure/setup-helm@dda3372f752e03dde6b3237bc9431cdc2f7a02a2 # v5.0.0
with:
token: ${{ secrets.GITHUB_TOKEN }}
- run: helm plugin install https://github.com/instrumenta/helm-kubeval
@@ -143,7 +143,7 @@ jobs:
test/package-lock.json
- run: SKIP_SUBMODULE_DEPS=1 npm ci
- run: npm run test:unit
- uses: codecov/codecov-action@1af58845a975a7985b0beb0cbe6fbbb71a41dbad # v5
- uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v5
if: success()
with:
token: ${{ secrets.CODECOV_TOKEN }}
@@ -162,7 +162,7 @@ jobs:
steps:
- run: sudo apt update && sudo apt install -y libkrb5-dev
- uses: awalsh128/cache-apt-pkgs-action@2c09a5e66da6c8016428a2172bd76e5e4f14bb17 # latest
- uses: awalsh128/cache-apt-pkgs-action@acb598e5ddbc6f68a970c5da0688d2f3a9f04d05 # latest
with:
packages: quilt
version: 1.0

View File

@@ -108,8 +108,8 @@ jobs:
echo "VERSION=${TAG#v}" >> $GITHUB_ENV
- uses: actions/checkout@v6
- uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3
- uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
- uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0
- uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
- uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
with:

View File

@@ -54,7 +54,7 @@ jobs:
steps:
- run: sudo apt update && sudo apt install -y libkrb5-dev
- uses: awalsh128/cache-apt-pkgs-action@2c09a5e66da6c8016428a2172bd76e5e4f14bb17 # latest
- uses: awalsh128/cache-apt-pkgs-action@acb598e5ddbc6f68a970c5da0688d2f3a9f04d05 # latest
with:
packages: quilt
version: 1.0

View File

@@ -107,6 +107,9 @@ main() {
EOF
) > product.json
VSCODE_QUALITY=stable npm run gulp compile-copilot-extension-full-build
npm run gulp core-ci
npm run gulp "vscode-reh-web-$VSCODE_TARGET${MINIFY:+-min}-ci"

12
package-lock.json generated
View File

@@ -1639,9 +1639,9 @@
"license": "MIT"
},
"node_modules/basic-ftp": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.2.0.tgz",
"integrity": "sha512-VoMINM2rqJwJgfdHq6RiUudKt2BV+FY5ZFezP/ypmwayk68+NzzAQy4XXLlqsGD4MCzq3DrmNFD/uUmBJuGoXw==",
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.2.1.tgz",
"integrity": "sha512-0yaL8JdxTknKDILitVpfYfV2Ob6yb3udX/hK97M7I3jOeznBNxQPtVvTUtnhUkyHlxFWyr5Lvknmgzoc7jf+1Q==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
@@ -5042,9 +5042,9 @@
"license": "MIT"
},
"node_modules/path-to-regexp": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz",
"integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==",
"version": "8.4.2",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz",
"integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==",
"license": "MIT",
"funding": {
"type": "opencollective",

163
patches/copilot.diff Normal file
View File

@@ -0,0 +1,163 @@
Index: code-server/lib/vscode/build/gulpfile.extensions.ts
===================================================================
--- code-server.orig/lib/vscode/build/gulpfile.extensions.ts
+++ code-server/lib/vscode/build/gulpfile.extensions.ts
@@ -287,6 +287,29 @@ export const compileCopilotExtensionBuil
gulp.task(compileCopilotExtensionBuildTask);
/**
+ * Compiles the built-in copilot extension with proper `.vscodeignore` filtering
+ * and materializes native dependency shims (`node-pty`, `ripgrep`).
+ * Produces output equivalent to what CI ships from the pre-built VSIX.
+ *
+ * The result is placed in `.build/extensions/copilot/` and can be copied
+ * directly into a VS Code Insiders installation at:
+ * `<insiders>/resources/app/extensions/copilot/`
+ */
+export const compileCopilotExtensionFullBuildTask = task.define('compile-copilot-extension-full-build', task.series(
+ // Step 1: Clean previous copilot build output
+ task.define('clean-copilot-build', util.rimraf('.build/extensions/copilot')),
+ // Step 2: Build and package with proper `.vscodeignore` filtering
+ task.define('package-copilot-extension-full', () => ext.packageCopilotExtensionFullStream().pipe(gulp.dest('.build'))),
+ // Step 3: Materialize native dependency shims (`node-pty`, `ripgrep`)
+ task.define('copilot-extension-native-shims', () => {
+ const copilotExtDir = path.join(root, '.build', 'extensions', 'copilot');
+ ext.prepareCopilotExtensionNativeShims(copilotExtDir);
+ return Promise.resolve();
+ })
+));
+gulp.task(compileCopilotExtensionFullBuildTask);
+
+/**
* Compiles the extensions for the build.
* This is essentially a helper task that combines {@link cleanExtensionsBuildTask}, {@link compileNonNativeExtensionsBuildTask} and {@link compileNativeExtensionsBuildTask}
*/
Index: code-server/lib/vscode/build/lib/extensions.ts
===================================================================
--- code-server.orig/lib/vscode/build/lib/extensions.ts
+++ code-server/lib/vscode/build/lib/extensions.ts
@@ -24,6 +24,7 @@ import { getProductionDependencies } fro
import { type IExtensionDefinition, getExtensionStream } from './builtInExtensions.ts';
import { fetchUrls, fetchGithub } from './fetch.ts';
import { createTsgoStream, spawnTsgo } from './tsgo.ts';
+import { prepareBuiltInCopilotExtensionShims } from './copilot.ts';
import vzip from 'gulp-vinyl-zip';
import { createRequire } from 'module';
@@ -482,6 +483,116 @@ export function packageCopilotExtensionS
).pipe(util2.setExecutableBit(['**/*.sh']));
}
+/**
+ * Package the built-in copilot extension as a properly filtered VSIX-equivalent.
+ * Unlike {@link packageCopilotExtensionStream}, this uses vsce.listFiles with
+ * PackageManager.Npm so that .vscodeignore is respected for dependency filtering,
+ * producing output equivalent to what CI ships from the pre-built VSIX.
+ */
+export function packageCopilotExtensionFullStream(): Stream {
+ const vsce = require('@vscode/vsce') as typeof import('@vscode/vsce');
+ const extensionPath = path.join(root, 'extensions', 'copilot');
+ if (!fs.existsSync(extensionPath)) {
+ return es.readArray([]);
+ }
+
+ const esbuildConfigFileName = '.esbuild.ts';
+ const esbuildScript = path.join(extensionPath, esbuildConfigFileName);
+ if (!fs.existsSync(esbuildScript)) {
+ throw new Error(`Copilot esbuild script not found at ${esbuildScript}`);
+ }
+
+ const result = es.through();
+
+ // Step 1: Run esbuild to compile the extension
+ new Promise<void>((resolve, reject) => {
+ const proc = cp.execFile(process.argv[0], [esbuildScript], { cwd: extensionPath }, (error, _stdout, stderr) => {
+ if (error) {
+ return reject(error);
+ }
+ const matches = (stderr || '').match(/\> (.+): error: (.+)?/g);
+ fancyLog(`Bundled extension: ${ansiColors.yellow(path.join('copilot', esbuildConfigFileName))} with ${matches ? matches.length : 0} errors.`);
+ for (const match of matches || []) {
+ fancyLog.error(match);
+ }
+ return resolve();
+ });
+ proc.stdout!.on('data', (data) => {
+ fancyLog(`${ansiColors.green('esbuilding copilot')}: ${data.toString('utf8')}`);
+ });
+ }).then(() => {
+ // Step 2: Use `vsce.listFiles` with Npm package manager so `.vscodeignore`
+ // is applied to both source files AND `node_modules` dependencies.
+ // This is the key difference from `packageCopilotExtensionStream` which
+ // uses `PackageManager.None` and then blindly merges all production deps.
+ return vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.Npm });
+ }).then(fileNames => {
+ const files = fileNames
+ .map(fileName => path.join(extensionPath, fileName))
+ .map(filePath => new File({
+ path: filePath,
+ stat: fs.statSync(filePath),
+ base: extensionPath,
+ contents: fs.createReadStream(filePath)
+ }));
+
+ es.readArray(files).pipe(result);
+ }).catch(err => {
+ console.error('Failed to package copilot extension:', err);
+ result.emit('error', err);
+ });
+
+ // Apply the same package.json cleanup as bundled extensions get
+ const cleaned = updateExtensionPackageJSON(
+ result.pipe(rename(p => p.dirname = `extensions/copilot/${p.dirname}`)),
+ (data: any) => {
+ delete data.scripts;
+ delete data.dependencies;
+ delete data.devDependencies;
+ if (data.main) {
+ data.main = data.main.replace('/out/', '/dist/');
+ }
+ return data;
+ }
+ );
+
+ return minifyExtensionResources(cleaned)
+ .pipe(util2.setExecutableBit(['**/*.sh']));
+}
+
+/**
+ * Materializes native dependency shims (`node-pty`, `ripgrep`) into the copilot
+ * extension output at {@link outputDir}. Uses the root `node_modules` as the
+ * source for native binaries, targeting the current platform/arch.
+ *
+ * This is the equivalent of what {@link copyCopilotNativeDepsTask} in
+ * `gulpfile.vscode.ts` does during a full product build, but scoped to
+ * just the standalone copilot extension output.
+ *
+ * Failures are logged as warnings rather than throwing, since the copilot
+ * extension can still create shims at runtime if they are missing.
+ */
+export function prepareCopilotExtensionNativeShims(outputDir: string): void {
+ const platform = process.platform;
+ const arch = process.arch;
+ const appNodeModulesDir = path.join(root, 'node_modules');
+
+ if (!fs.existsSync(outputDir)) {
+ fancyLog.warn('[prepareCopilotExtensionNativeShims] Copilot extension not found at', outputDir, '- skipping shims');
+ return;
+ }
+
+ try {
+ prepareBuiltInCopilotExtensionShims(platform, arch, outputDir, appNodeModulesDir);
+ fancyLog(`[prepareCopilotExtensionNativeShims] Materialized native shims for ${platform}-${arch}`);
+ } catch (err) {
+ // Downgrade to a warning for local builds since the extension
+ // can still function without shims (it creates them at runtime).
+ fancyLog.warn(`[prepareCopilotExtensionNativeShims] Failed to materialize shims: ${err}`);
+ fancyLog.warn('[prepareCopilotExtensionNativeShims] The extension will still work but will create shims at runtime.');
+ }
+}
+
export function packageMarketplaceExtensionsStream(forWeb: boolean): Stream {
const marketplaceExtensionsDescriptions = [
...builtInExtensions.filter(({ name }) => (forWeb ? !marketplaceWebExtensionsExclude.has(name) : true)),

View File

@@ -8,7 +8,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts
+++ code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts
@@ -342,6 +342,10 @@ export class Extension implements IExten
if (this.type === ExtensionType.System && this.productService.quality === 'stable') {
if (this.type === ExtensionType.System && this.productService.quality === 'stable' && !this.productService.builtInExtensionsEnabledWithAutoUpdates?.some(id => id.toLowerCase() === this.identifier.id.toLowerCase())) {
return false;
}
+ // Do not update builtin extensions.

View File

@@ -291,7 +291,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens
}
// Prefers to run on UI
@@ -2072,17 +2069,6 @@ export class SetLanguageAction extends E
@@ -2242,17 +2239,6 @@ export class SetLanguageAction extends E
update(): void {
this.enabled = false;
this.class = SetLanguageAction.DisabledClass;
@@ -309,7 +309,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens
}
override async run(): Promise<any> {
@@ -2099,7 +2085,6 @@ export class ClearLanguageAction extends
@@ -2269,7 +2255,6 @@ export class ClearLanguageAction extends
private static readonly DisabledClass = `${this.EnabledClass} disabled`;
constructor(
@@ -317,7 +317,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens
@ILocaleService private readonly localeService: ILocaleService,
) {
super(ClearLanguageAction.ID, ClearLanguageAction.TITLE.value, ClearLanguageAction.DisabledClass, false);
@@ -2109,17 +2094,6 @@ export class ClearLanguageAction extends
@@ -2279,17 +2264,6 @@ export class ClearLanguageAction extends
update(): void {
this.enabled = false;
this.class = ClearLanguageAction.DisabledClass;

View File

@@ -22,3 +22,4 @@ clipboard.diff
display-language.diff
trusted-domains.diff
signature-verification.diff
copilot.diff

View File

@@ -1,43 +1,25 @@
Make sourcemaps self-hosted
Remove sourcemaps URL
Normally source maps get removed as part of the build process so prevent that
from happening. Also avoid using the windows.net host since obviously we can
not host our source maps there and want them to be self-hosted even if we could.
To test try debugging/browsing the source of a build in a browser.
These will not work since we patch VS Code.
Index: code-server/lib/vscode/build/gulpfile.reh.ts
===================================================================
--- code-server.orig/lib/vscode/build/gulpfile.reh.ts
+++ code-server/lib/vscode/build/gulpfile.reh.ts
@@ -263,8 +263,7 @@ function packageTask(type: string, platf
@@ -261,10 +261,15 @@ function packageTask(type: string, platf
const destination = path.join(BUILD_ROOT, destinationFolderName);
return () => {
+ const jsFilterMain = util.filter(data => !data.isDirectory() && /\.js$/.test(data.path));
+
const src = gulp.src(sourceFolderName + '/**', { base: '.' })
.pipe(rename(function (path) { path.dirname = path.dirname!.replace(new RegExp('^' + sourceFolderName), 'out'); }))
- .pipe(util.setExecutableBit(['**/*.sh']))
.pipe(util.setExecutableBit(['**/*.sh']))
- .pipe(filter(['**', '!**/*.{js,css}.map']));
+ .pipe(util.setExecutableBit(['**/*.sh']));
+ .pipe(filter(['**', '!**/*.{js,css}.map']))
+ .pipe(jsFilterMain)
+ .pipe(util.stripSourceMappingURL())
+ .pipe(jsFilterMain.restore);
const workspaceExtensionPoints = ['debuggers', 'jsonValidation'];
const isUIExtension = (manifest: { extensionKind?: string; main?: string; contributes?: Record<string, unknown> }) => {
@@ -304,9 +303,9 @@ function packageTask(type: string, platf
.map(name => `.build/extensions/${name}/**`);
const extensions = gulp.src(extensionPaths, { base: '.build', dot: true });
- const extensionsCommonDependencies = gulp.src('.build/extensions/node_modules/**', { base: '.build', dot: true });
- const sources = es.merge(src, extensions, extensionsCommonDependencies)
+ const extensionsCommonDependencies = gulp.src('.build/extensions/node_modules/**', { base: '.build', dot: true })
.pipe(filter(['**', '!**/*.{js,css}.map'], { dot: true }));
+ const sources = es.merge(src, extensions, extensionsCommonDependencies);
let version = packageJson.version;
const quality = (product as typeof product & { quality?: string }).quality;
@@ -501,7 +500,7 @@ function tweakProductForServerWeb(produc
const minifyTask = task.define(`minify-vscode-${type}`, task.series(
bundleTask,
util.rimraf(`out-vscode-${type}-min`),
- optimize.minifyTask(`out-vscode-${type}`, `https://main.vscode-cdn.net/sourcemaps/${commit}/core`)
+ optimize.minifyTask(`out-vscode-${type}`, ``)
));
gulp.task(minifyTask);

View File

@@ -101,7 +101,7 @@ Index: code-server/lib/vscode/src/vs/base/common/product.ts
readonly version: string;
readonly date?: string;
@@ -117,6 +118,7 @@ export interface IProductConfiguration {
@@ -118,6 +119,7 @@ export interface IProductConfiguration {
readonly resourceUrlTemplate: string;
readonly nlsBaseUrl: string;
readonly accessSKUs?: string[];

View File

@@ -77,11 +77,14 @@ export class CodeServer {
*/
private async createWorkspace(): Promise<string> {
const dir = await this.workspaceDir
await fs.mkdir(path.join(dir, "Machine"), { recursive: true })
await fs.mkdir(path.join(dir, "User"), { recursive: true })
await fs.writeFile(
path.join(dir, "Machine/settings.json"),
path.join(dir, "User/settings.json"),
JSON.stringify({
"workbench.startupEditor": "none",
// Disable the welcome popup so we can avoid having to click through it
// on every test.
"workbench.welcomePage.experimentalOnboarding": false,
}),
"utf8",
)