Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 11 additions & 9 deletions .github/actions/apply-version/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,13 @@ runs:

echo "Applied version $INPUT_VERSION (MSIX: $MSIX_VERSION, productName: '$PRODUCT_NAME', appstore: $APPSTORE_IDENTIFIER, windows: $WINDOWS_IDENTIFIER)"

# macOS and Windows bundlers both read icons straight out of
# src-tauri/icons at build time (tauri.conf.json's bundle.icon list,
# and tauri-windows-bundle's hardcoded src-tauri/icons lookup), so
# swapping the staging icon set in here — before those bundlers run —
# is enough to make staging builds visually distinct from release on
# a device that has both installed. Only touches the checkout for
# this CI run, never committed.
# Both bundlers resolve icons out of src-tauri/icons at build time:
# tauri.conf.json's bundle.icon list (macOS .app + Windows exe favicon),
# and our windows:assets script, which regenerates the whole Microsoft
# Store asset set from src-tauri/icons/icon.png. Swapping the staging
# icon set in here — before those run — is enough to make staging builds
# visually distinct from release on a device that has both installed.
# Only touches the checkout for this CI run, never committed.
- name: Select app icon set
shell: bash
env:
Expand All @@ -117,11 +117,13 @@ runs:
# Icon Composer source, which xcodebuild's actool compiles itself
# (the iOS step below places it into gen/apple). Both derive from
# the same Icon Composer project.
cp src-tauri/icons-staging/32x32.png src-tauri/icons-staging/64x64.png \
# Only the icons actually consumed at build: the bundle.icon
# PNGs, icon.png (Store asset source), icon.icns + Assets.car
# (macOS), and icon.ico (Windows exe favicon).
cp src-tauri/icons-staging/32x32.png \
src-tauri/icons-staging/128x128.png "src-tauri/icons-staging/128x128@2x.png" \
src-tauri/icons-staging/icon.png src-tauri/icons-staging/icon.icns src-tauri/icons-staging/icon.ico \
src-tauri/icons-staging/Assets.car \
src-tauri/icons-staging/Square*.png src-tauri/icons-staging/StoreLogo.png \
src-tauri/icons/
# icon.icon is a directory — replace wholesale rather than cp into it.
rm -rf src-tauri/icons/icon.icon
Expand Down
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@
"cloud:deploy:staging": "wrangler deploy -c src/lib/cloud/wrangler.toml --env staging",
"cloud:deploy:prod": "wrangler deploy -c src/lib/cloud/wrangler.toml --env production",
"build:standalone": "next build && tauri dev --no-watch",
"windows:assets": "npx tsx scripts/generate-windows-store-assets.ts",
"prebuild:windows": "npm run windows:assets",
"predebug:windows": "npm run windows:assets",
"predebug:windows:x64": "npm run windows:assets",
"prebuild:windows:x64": "npm run windows:assets",
"prebuild:windows:arm64": "npm run windows:assets",
"build:windows": "tauri-windows-bundle build --arch x64,arm64 --runner npm",
"debug:windows": "tauri-windows-bundle build --arch x64,arm64 --debug --runner npm",
"debug:windows:x64": "tauri-windows-bundle build --arch x64 --debug --runner npm",
Expand Down Expand Up @@ -126,6 +132,7 @@
"patch-package": "^8.0.1",
"playwright": "^1.58.2",
"prisma": "^7.7.0",
"sharp": "^0.34.5",
"tsx": "^4.21.0",
"typescript": "^5.7.3",
"typescript-plugin-css-modules": "^5.2.0",
Expand Down
58 changes: 58 additions & 0 deletions scripts/generate-windows-store-assets.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Regenerates the entire MSIX/Store asset set in src-tauri/gen/windows/Assets
// from a SINGLE source icon: src-tauri/icons/icon.png. Nothing in this set is
// committed (see gen/windows/.gitignore) — it is rebuilt before every Windows
// build by the pre* npm hooks, so to change the visuals you only ever update the
// master icon (app-icon.png -> `tauri icon` -> icon.png); every tile and every
// taskbar variant re-derives from it.
//
// Staging is handled for free: apply-version swaps src-tauri/icons-staging/icon.png
// into src-tauri/icons/ before the build, so this script picks up the blue master
// and emits blue tiles + blue unplated taskbar icons. (The exe favicon separately
// follows the swapped src-tauri/icons/icon.ico.)
import sharp from "sharp";
import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";

const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
const source = path.join(root, "src-tauri", "icons", "icon.png"); // 512px master
const outDir = path.join(root, "src-tauri", "gen", "windows", "Assets");
const transparent = { r: 0, g: 0, b: 0, alpha: 0 };

fs.mkdirSync(outDir, { recursive: true });

/** Resize the master to an NxN transparent PNG. */
const square = (size: number) =>
sharp(source).resize(size, size, { fit: "contain", background: transparent }).png();

// 1. Store/tile logos referenced by AppxManifest.xml (VisualElements + Logo).
const tiles: Record<string, number> = {
"StoreLogo.png": 50,
"Square44x44Logo.png": 44,
"Square150x150Logo.png": 150,
"LargeTile.png": 310,
};
for (const [name, size] of Object.entries(tiles)) {
await square(size).toFile(path.join(outDir, name));
}

// Wide tile: the square logo centered on a 310x150 transparent canvas.
const wideLogo = await square(150).toBuffer();
await sharp({ create: { width: 310, height: 150, channels: 4, background: transparent } })
.composite([{ input: wideLogo, left: Math.floor((310 - 150) / 2), top: 0 }])
.png()
.toFile(path.join(outDir, "Wide310x150Logo.png"));

// 2. Taskbar & app-list variants. altform-unplated tells Windows to draw the
// icon with no background plate (otherwise it fills the plate with the system
// accent color); the plain targetsize variants cover contexts that do plate.
const sizes = [16, 24, 32, 48, 256];
const forms = ["", "_altform-unplated", "_altform-lightunplated"];
for (const n of sizes) {
const variant = square(n);
for (const form of forms) {
await variant.clone().toFile(path.join(outDir, `Square44x44Logo.targetsize-${n}${form}.png`));
}
}

console.log(`Generated Windows Store assets in ${path.relative(root, outDir)} from ${path.relative(root, source)}`);
4 changes: 4 additions & 0 deletions src-tauri/gen/windows/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
# Generated files
# Keep bundle.config.json and templates in git

# Store assets are regenerated from src-tauri/icons by the windows:assets
# script (a pre* hook on every windows build), so they are not committed.
Assets/
Binary file removed src-tauri/gen/windows/Assets/LargeTile.png
Binary file not shown.
Binary file removed src-tauri/gen/windows/Assets/Square150x150Logo.png
Binary file not shown.
Binary file removed src-tauri/gen/windows/Assets/Square44x44Logo.png
Binary file not shown.
Binary file removed src-tauri/gen/windows/Assets/StoreLogo.png
Binary file not shown.
Binary file removed src-tauri/gen/windows/Assets/Wide310x150Logo.png
Binary file not shown.
Binary file removed src-tauri/icons-staging/64x64.png
Binary file not shown.
Binary file removed src-tauri/icons-staging/Square107x107Logo.png
Binary file not shown.
Binary file removed src-tauri/icons-staging/Square142x142Logo.png
Binary file not shown.
Binary file removed src-tauri/icons-staging/Square150x150Logo.png
Binary file not shown.
Binary file removed src-tauri/icons-staging/Square284x284Logo.png
Binary file not shown.
Binary file removed src-tauri/icons-staging/Square30x30Logo.png
Binary file not shown.
Binary file removed src-tauri/icons-staging/Square310x310Logo.png
Binary file not shown.
Binary file removed src-tauri/icons-staging/Square44x44Logo.png
Binary file not shown.
Binary file removed src-tauri/icons-staging/Square71x71Logo.png
Binary file not shown.
Binary file removed src-tauri/icons-staging/Square89x89Logo.png
Binary file not shown.
Binary file removed src-tauri/icons-staging/StoreLogo.png
Binary file not shown.
Binary file removed src-tauri/icons/64x64.png
Binary file not shown.
Binary file removed src-tauri/icons/Square107x107Logo.png
Binary file not shown.
Binary file removed src-tauri/icons/Square142x142Logo.png
Binary file not shown.
Binary file removed src-tauri/icons/Square150x150Logo.png
Binary file not shown.
Binary file removed src-tauri/icons/Square284x284Logo.png
Binary file not shown.
Binary file removed src-tauri/icons/Square30x30Logo.png
Binary file not shown.
Binary file removed src-tauri/icons/Square310x310Logo.png
Binary file not shown.
Binary file removed src-tauri/icons/Square44x44Logo.png
Binary file not shown.
Binary file removed src-tauri/icons/Square71x71Logo.png
Binary file not shown.
Binary file removed src-tauri/icons/Square89x89Logo.png
Diff not rendered.
Binary file removed src-tauri/icons/StoreLogo.png
Diff not rendered.
5 changes: 0 additions & 5 deletions src-tauri/icons/android/mipmap-anydpi-v26/ic_launcher.xml

This file was deleted.

Binary file removed src-tauri/icons/android/mipmap-hdpi/ic_launcher.png
Diff not rendered.
Diff not rendered.
Diff not rendered.
Binary file removed src-tauri/icons/android/mipmap-mdpi/ic_launcher.png
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
4 changes: 0 additions & 4 deletions src-tauri/icons/android/values/ic_launcher_background.xml

This file was deleted.

Loading