mirror of
https://github.com/microsoft/vscode.git
synced 2026-02-15 07:28:05 +00:00
fix: update disk badge icons for dmg (#290879)
* fix: update disk badge icons for dmg * chore: try with code icons as badge * fix: patch badge icon outside of dmgbuild Refs https://github.com/dmgbuild/dmgbuild/issues/278 which doesn't work well on macOS 26. We avoid forking the project in this manner.
This commit is contained in:
@@ -119,9 +119,12 @@ jobs:
|
|||||||
|
|
||||||
- script: |
|
- script: |
|
||||||
set -e
|
set -e
|
||||||
|
# Needed for https://github.com/dmgbuild/dmgbuild/blob/main/src/dmgbuild/badge.py
|
||||||
|
python3 -m pip install pyobjc-framework-Quartz
|
||||||
DMG_OUT="$(Pipeline.Workspace)/vscode_client_darwin_$(VSCODE_ARCH)_dmg"
|
DMG_OUT="$(Pipeline.Workspace)/vscode_client_darwin_$(VSCODE_ARCH)_dmg"
|
||||||
mkdir -p $DMG_OUT
|
mkdir -p $DMG_OUT
|
||||||
node build/darwin/create-dmg.ts $(agent.builddirectory) $DMG_OUT
|
node build/darwin/create-dmg.ts $(agent.builddirectory) $DMG_OUT
|
||||||
|
python3 build/darwin/patch-dmg.py $DMG_OUT/VSCode-darwin-$(VSCODE_ARCH).dmg resources/darwin/disk.icns
|
||||||
echo "##vso[task.setvariable variable=DMG_PATH]$DMG_OUT/VSCode-darwin-$(VSCODE_ARCH).dmg"
|
echo "##vso[task.setvariable variable=DMG_PATH]$DMG_OUT/VSCode-darwin-$(VSCODE_ARCH).dmg"
|
||||||
displayName: Create DMG installer
|
displayName: Create DMG installer
|
||||||
|
|
||||||
|
|||||||
@@ -226,9 +226,12 @@ steps:
|
|||||||
|
|
||||||
- script: |
|
- script: |
|
||||||
set -e
|
set -e
|
||||||
|
# Needed for https://github.com/dmgbuild/dmgbuild/blob/main/src/dmgbuild/badge.py
|
||||||
|
python3 -m pip install pyobjc-framework-Quartz
|
||||||
DMG_OUT="$(Pipeline.Workspace)/vscode_client_darwin_$(VSCODE_ARCH)_dmg"
|
DMG_OUT="$(Pipeline.Workspace)/vscode_client_darwin_$(VSCODE_ARCH)_dmg"
|
||||||
mkdir -p $DMG_OUT
|
mkdir -p $DMG_OUT
|
||||||
node build/darwin/create-dmg.ts $(agent.builddirectory) $DMG_OUT
|
node build/darwin/create-dmg.ts $(agent.builddirectory) $DMG_OUT
|
||||||
|
python3 build/darwin/patch-dmg.py $DMG_OUT/VSCode-darwin-$(VSCODE_ARCH).dmg resources/darwin/disk.icns
|
||||||
echo "##vso[task.setvariable variable=DMG_PATH]$DMG_OUT/VSCode-darwin-$(VSCODE_ARCH).dmg"
|
echo "##vso[task.setvariable variable=DMG_PATH]$DMG_OUT/VSCode-darwin-$(VSCODE_ARCH).dmg"
|
||||||
condition: eq(variables['BUILT_CLIENT'], 'true')
|
condition: eq(variables['BUILT_CLIENT'], 'true')
|
||||||
displayName: Create DMG installer
|
displayName: Create DMG installer
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ const product = JSON.parse(fs.readFileSync(path.join(root, 'product.json'), 'utf
|
|||||||
interface DmgBuildSettings {
|
interface DmgBuildSettings {
|
||||||
title: string;
|
title: string;
|
||||||
icon?: string | null;
|
icon?: string | null;
|
||||||
|
'badge-icon'?: string | null;
|
||||||
background?: string;
|
background?: string;
|
||||||
'background-color'?: string;
|
'background-color'?: string;
|
||||||
'icon-size'?: number;
|
'icon-size'?: number;
|
||||||
@@ -70,7 +71,7 @@ async function main(buildDir?: string, outDir?: string): Promise<void> {
|
|||||||
const dmgName = `VSCode-darwin-${arch}`;
|
const dmgName = `VSCode-darwin-${arch}`;
|
||||||
const artifactPath = path.join(outDir, `${dmgName}.dmg`);
|
const artifactPath = path.join(outDir, `${dmgName}.dmg`);
|
||||||
const backgroundPath = path.join(import.meta.dirname, `dmg-background-${quality}.tiff`);
|
const backgroundPath = path.join(import.meta.dirname, `dmg-background-${quality}.tiff`);
|
||||||
const appIconPath = path.join(appPath, 'Contents', 'Resources', `${product.nameShort}.icns`);
|
const diskIconPath = path.join(root, 'resources', 'darwin', 'code.icns');
|
||||||
let title = 'Code OSS';
|
let title = 'Code OSS';
|
||||||
switch (quality) {
|
switch (quality) {
|
||||||
case 'stable':
|
case 'stable':
|
||||||
@@ -99,7 +100,7 @@ async function main(buildDir?: string, outDir?: string): Promise<void> {
|
|||||||
|
|
||||||
const settings: DmgBuildSettings = {
|
const settings: DmgBuildSettings = {
|
||||||
title,
|
title,
|
||||||
icon: appIconPath,
|
'badge-icon': diskIconPath,
|
||||||
background: backgroundPath,
|
background: backgroundPath,
|
||||||
format: 'ULMO',
|
format: 'ULMO',
|
||||||
'text-size': 12,
|
'text-size': 12,
|
||||||
|
|||||||
71
build/darwin/patch-dmg.py
Normal file
71
build/darwin/patch-dmg.py
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import subprocess
|
||||||
|
import shutil
|
||||||
|
import tempfile
|
||||||
|
import plistlib
|
||||||
|
import os
|
||||||
|
|
||||||
|
def patch_dmg_icon(dmg_path, new_icon_path):
|
||||||
|
"""Replace the volume icon in an existing DMG."""
|
||||||
|
|
||||||
|
# 1. Convert to read-write format
|
||||||
|
temp_rw = tempfile.NamedTemporaryFile(suffix=".dmg", delete=False)
|
||||||
|
temp_rw.close()
|
||||||
|
|
||||||
|
subprocess.run([
|
||||||
|
"hdiutil", "convert", dmg_path,
|
||||||
|
"-format", "UDRW", # Read-write
|
||||||
|
"-o", temp_rw.name,
|
||||||
|
"-ov" # Overwrite
|
||||||
|
], check=True)
|
||||||
|
|
||||||
|
# 2. Attach the writable DMG
|
||||||
|
result = subprocess.run(
|
||||||
|
["hdiutil", "attach", "-nobrowse", "-plist", temp_rw.name],
|
||||||
|
capture_output=True, check=True
|
||||||
|
)
|
||||||
|
plist = plistlib.loads(result.stdout)
|
||||||
|
|
||||||
|
mount_point = None
|
||||||
|
device = None
|
||||||
|
for entity in plist["system-entities"]:
|
||||||
|
if "mount-point" in entity:
|
||||||
|
mount_point = entity["mount-point"]
|
||||||
|
device = entity["dev-entry"]
|
||||||
|
break
|
||||||
|
|
||||||
|
try:
|
||||||
|
# 3. Copy custom icon
|
||||||
|
icon_target = os.path.join(mount_point, ".VolumeIcon.icns")
|
||||||
|
shutil.copyfile(new_icon_path, icon_target)
|
||||||
|
|
||||||
|
# 4. Set the custom icon attribute on the volume
|
||||||
|
subprocess.run(["/usr/bin/SetFile", "-a", "C", mount_point], check=True)
|
||||||
|
|
||||||
|
# Sync before detach
|
||||||
|
subprocess.run(["sync", "--file-system", mount_point], check=True)
|
||||||
|
|
||||||
|
finally:
|
||||||
|
# 5. Detach
|
||||||
|
subprocess.run(["hdiutil", "detach", device], check=True)
|
||||||
|
|
||||||
|
# 6. Convert back to compressed format (ULMO = lzma)
|
||||||
|
subprocess.run([
|
||||||
|
"hdiutil", "convert", temp_rw.name,
|
||||||
|
"-format", "ULMO",
|
||||||
|
"-o", dmg_path,
|
||||||
|
"-ov"
|
||||||
|
], check=True)
|
||||||
|
|
||||||
|
# Cleanup temp file
|
||||||
|
os.unlink(temp_rw.name)
|
||||||
|
print(f"Successfully patched {dmg_path} with new icon")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import sys
|
||||||
|
if len(sys.argv) != 3:
|
||||||
|
print(f"Usage: {sys.argv[0]} <dmg_path> <icon.icns>")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
patch_dmg_icon(sys.argv[1], sys.argv[2])
|
||||||
@@ -88,6 +88,7 @@ export const indentationFilter = Object.freeze<string[]>([
|
|||||||
'!test/unit/assert.js',
|
'!test/unit/assert.js',
|
||||||
'!resources/linux/snap/electron-launch',
|
'!resources/linux/snap/electron-launch',
|
||||||
'!build/ext.js',
|
'!build/ext.js',
|
||||||
|
'!build/darwin/patch-dmg.py',
|
||||||
'!build/npm/gyp/patches/gyp_spectre_mitigation_support.patch',
|
'!build/npm/gyp/patches/gyp_spectre_mitigation_support.patch',
|
||||||
'!product.overrides.json',
|
'!product.overrides.json',
|
||||||
|
|
||||||
@@ -177,6 +178,7 @@ export const copyrightFilter = Object.freeze<string[]>([
|
|||||||
'!**/*.wasm',
|
'!**/*.wasm',
|
||||||
'!**/*.tiff',
|
'!**/*.tiff',
|
||||||
'!build/**/*.init',
|
'!build/**/*.init',
|
||||||
|
'!build/darwin/patch-dmg.py',
|
||||||
'!build/linux/libcxx-fetcher.*',
|
'!build/linux/libcxx-fetcher.*',
|
||||||
'!build/npm/gyp/custom-headers/*.patch',
|
'!build/npm/gyp/custom-headers/*.patch',
|
||||||
'!resources/linux/snap/snapcraft.yaml',
|
'!resources/linux/snap/snapcraft.yaml',
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "code-oss-dev",
|
"name": "code-oss-dev",
|
||||||
"version": "1.109.0",
|
"version": "1.109.0",
|
||||||
"distro": "ce54912c8b9b4ad03645ec984f7fb9e0a6247c32",
|
"distro": "1468752e41ea530021336a556d31c13ff82e02b9",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Microsoft Corporation"
|
"name": "Microsoft Corporation"
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user