From 7875a60fe831aafbe3a28584a4fce293913c6681 Mon Sep 17 00:00:00 2001 From: hazre Date: Mon, 20 Jul 2026 19:20:32 +0200 Subject: [PATCH 01/11] feat: add mise support Signed-off-by: hazre --- mise.toml | 7 +++++++ rust-toolchain.toml | 3 +++ 2 files changed, 10 insertions(+) create mode 100644 mise.toml create mode 100644 rust-toolchain.toml diff --git a/mise.toml b/mise.toml new file mode 100644 index 000000000..04d18ed87 --- /dev/null +++ b/mise.toml @@ -0,0 +1,7 @@ +[settings] +idiomatic_version_file_enable_tools = ["pnpm", "node", "rust"] +experimental = true + +[tools] +cargo-binstall = "1.21.0" +"cargo:knope" = "0.23.0" diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 000000000..59277fee7 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,3 @@ +[toolchain] +channel = "1.97.1" +components = ["clippy", "rustfmt"] From 4cb52de8b723d54316e12b966167e4d98d689bbf Mon Sep 17 00:00:00 2001 From: hazre Date: Wed, 22 Jul 2026 01:43:28 +0200 Subject: [PATCH 02/11] chore(tauri): update cargo.toml metadata Signed-off-by: hazre --- knope.toml | 2 +- src-tauri/Cargo.lock | 2 +- src-tauri/Cargo.toml | 9 ++++----- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/knope.toml b/knope.toml index 04cc4e690..24ed9d44c 100644 --- a/knope.toml +++ b/knope.toml @@ -1,5 +1,5 @@ [package] -versioned_files = ["package.json", "src-tauri/tauri.conf.json"] +versioned_files = ["package.json", "src-tauri/tauri.conf.json", "src-tauri/Cargo.toml"] changelog = "CHANGELOG.md" extra_changelog_sections = [ { name = "Security", types = [ diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index fd5d34206..e849fd22f 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -5247,7 +5247,7 @@ checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" [[package]] name = "sable" -version = "0.1.0" +version = "1.20.0" dependencies = [ "async-stream", "base64 0.22.1", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index aedc31083..0ecbb65e9 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,12 +1,11 @@ [package] name = "sable" -version = "0.1.0" +version = "1.20.0" description = "Yet another matrix client but better" -authors = ["you"] -license = "" -repository = "" +authors = ["Sable Maintainers"] +license = "AGPL-3.0-or-later" +repository = "https://github.com/SableClient/Sable" edition = "2021" -rust-version = "1.88.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html From 9353926d5f9a989240581a34e64f89a6deb96ad5 Mon Sep 17 00:00:00 2001 From: hazre Date: Wed, 22 Jul 2026 01:43:43 +0200 Subject: [PATCH 03/11] chore(ci): add rust to dependabot Signed-off-by: hazre --- .github/dependabot.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 3c4f0f7ef..497e619ee 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -53,3 +53,19 @@ updates: update-types: - minor - patch + + - package-ecosystem: cargo + cooldown: + default-days: 7 + directory: /src-tauri + schedule: + interval: daily + open-pull-requests-limit: 5 + labels: + - internal + commit-message: + prefix: chore + groups: + docker: + patterns: + - '*' \ No newline at end of file From f97d16f309aedb060bd72e738cc3aef8a1264cda Mon Sep 17 00:00:00 2001 From: hazre Date: Wed, 22 Jul 2026 01:52:12 +0200 Subject: [PATCH 04/11] chore: move pnpm overrides to pnpm-workspace.yaml Signed-off-by: hazre --- package.json | 7 +------ pnpm-workspace.yaml | 1 + 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 9eff87f13..c0c479bfe 100644 --- a/package.json +++ b/package.json @@ -154,10 +154,5 @@ "node": "24.x", "pnpm": ">=10" }, - "packageManager": "pnpm@10.32.1+sha512.a706938f0e89ac1456b6563eab4edf1d1faf3368d1191fc5c59790e96dc918e4456ab2e67d613de1043d2e8c81f87303e6b40d4ffeca9df15ef1ad567348f2be", - "pnpm": { - "overrides": { - "jsdom>undici": "^7.28.0" - } - } + "packageManager": "pnpm@10.32.1+sha512.a706938f0e89ac1456b6563eab4edf1d1faf3368d1191fc5c59790e96dc918e4456ab2e67d613de1043d2e8c81f87303e6b40d4ffeca9df15ef1ad567348f2be" } diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index dd4699606..0b5e9b21e 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -18,6 +18,7 @@ overrides: brace-expansion: '>=1.1.12' esbuild: '>=0.25.0' flatted: '>=3.4.2' + jsdom>undici: '^7.28.0' lodash: '>=4.17.23' minimatch: '>=10.2.3' rollup: '>=4.59.0' From a7e4a1ed223371407ba66869dd22e64ec0ac6079 Mon Sep 17 00:00:00 2001 From: hazre Date: Wed, 22 Jul 2026 01:55:57 +0200 Subject: [PATCH 05/11] chore(scripts): convert shell scripts to cross-platform ESM Signed-off-by: hazre --- scripts/cef-copy-libs.sh | 1 + scripts/cef-package.sh | 1 + scripts/icons/replace.js | 163 +++++++++++++++++++++++++++++++++++++++ scripts/replace-logo.sh | 126 ------------------------------ scripts/tauri.js | 70 ++++++++--------- 5 files changed, 199 insertions(+), 162 deletions(-) create mode 100644 scripts/icons/replace.js delete mode 100755 scripts/replace-logo.sh diff --git a/scripts/cef-copy-libs.sh b/scripts/cef-copy-libs.sh index 99e026126..30603f817 100644 --- a/scripts/cef-copy-libs.sh +++ b/scripts/cef-copy-libs.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +#MISE description="Copy CEF runtime libs next to the built binary" # Copy the CEF runtime (libcef.so + resources) next to a built binary so the app # is self-contained: works standalone, when launched by the OS via a sable:// # deep link, or from a release package. Pair with the rpath=$ORIGIN that diff --git a/scripts/cef-package.sh b/scripts/cef-package.sh index aeff0fd11..440d48644 100755 --- a/scripts/cef-package.sh +++ b/scripts/cef-package.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +#MISE description="Package CEF build into deb/rpm/AppImage" # Package the Linux CEF build into deb/rpm/AppImage. Used by CI and locally. # Run after the binary is built (pnpm tauri:cef build). # Usage: scripts/cef-package.sh [version] diff --git a/scripts/icons/replace.js b/scripts/icons/replace.js new file mode 100644 index 000000000..3f02f5415 --- /dev/null +++ b/scripts/icons/replace.js @@ -0,0 +1,163 @@ +#!/usr/bin/env node +//MISE description="Replace logo/icon assets in public/ from SVG inputs via ffmpeg" + +import { execFileSync } from 'node:child_process'; +import { existsSync, mkdirSync, copyFileSync } from 'node:fs'; +import { dirname, resolve } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { createInterface } from 'node:readline'; +import { PrefixedLogger, createTextHelpers } from './utils/console-style.js'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const BASE_DIR = resolve(__dirname, '..'); + +const logger = new PrefixedLogger('[replace-logo]'); +const { red } = createTextHelpers({ useColor: logger.useColor }); + +/** + * Display a question on stdin and return the user's trimmed response. + * @param {string} question - The prompt text to display. + * @returns {Promise} The user's input with surrounding whitespace removed. + */ +function prompt(question) { + const rl = createInterface({ input: process.stdin, output: process.stdout }); + return new Promise((resolve_) => { + rl.question(question, (answer) => { + rl.close(); + resolve_(answer.trim()); + }); + }); +} + +/** Print CLI usage instructions to stdout. */ +function usage() { + logger.info(`Usage: run this script and provide four file paths when prompted. +It will replace icons in the repository public/ tree using ffmpeg. + +You will be prompted for: + - maskless (borderless) logo (used for maskable icons) + - circular logo (used for circular icons) + - highlight variant (icon for highlight indicator) + - unread variant (icon for unread indicator) + +Requires: ffmpeg, base64`); +} + +/** + * Render an SVG to a PNG at the given square dimension using ffmpeg. + * Creates the output directory if it doesn't already exist. + * @param {string} input - Absolute path to the source SVG file. + * @param {string} output - Absolute path for the generated PNG. + * @param {string | number} size - Width and height in pixels. + */ +function ffmpegCmd(input, output, size) { + mkdirSync(dirname(output), { recursive: true }); + logger.info(`Generating ${output} (${size} x ${size})`); + execFileSync( + 'ffmpeg', + ['-y', '-width', String(size), '-height', String(size), '-i', input, output], + { + stdio: 'pipe', + } + ); +} + +/** + * Check whether a file path has an SVG extension (case-insensitive). + * @param {string} filePath + * @returns {boolean} + */ +function isSvg(filePath) { + return filePath.toLowerCase().endsWith('.svg'); +} + +/** + * Entry point. Prompts for four SVG logo variants, validates them, + * then renders PNGs at every required size and copies SVGs into public/res/svg/. + * @param {string[]} args - CLI arguments (supports --help / -h). + */ +async function main(args) { + if (args.includes('--help') || args.includes('-h')) { + usage(); + process.exit(0); + } + + const maskless = await prompt('Path to maskless (borderless) logo: '); + const circular = await prompt('Path to circular logo: '); + const highlight = await prompt('Path to highlight variant: '); + const unread = await prompt('Path to unread variant: '); + + for (const f of [maskless, circular, highlight, unread]) { + if (!existsSync(f)) { + logger.error(`${red('File not found:')} ${f}`); + process.exit(2); + } + if (!isSvg(f)) { + logger.error(`${red('Input must be an SVG:')} ${f}`); + process.exit(3); + } + } + + /** @type {[number, string][]} */ + const CIRCULAR_TARGETS = [ + [512, 'public/favicon.png'], + [2560, 'public/full_res_sable.png'], + [144, 'public/res/logo/logo-144x144.png'], + [192, 'public/res/logo/logo-192x192.png'], + [256, 'public/res/logo/logo-256x256.png'], + [36, 'public/res/logo/logo-36x36.png'], + [384, 'public/res/logo/logo-384x384.png'], + [48, 'public/res/logo/logo-48x48.png'], + [512, 'public/res/logo/logo-512x512.png'], + [72, 'public/res/logo/logo-72x72.png'], + [96, 'public/res/logo/logo-96x96.png'], + ]; + + logger.info('Replacing circular icons...'); + for (const [size, out] of CIRCULAR_TARGETS) { + ffmpegCmd(circular, resolve(BASE_DIR, out), size); + } + + /** @type {[number, string][]} */ + const MASKABLE_TARGETS = [ + [114, 'public/res/logo-maskable/logo-maskable-114x114.png'], + [120, 'public/res/logo-maskable/logo-maskable-120x120.png'], + [144, 'public/res/logo-maskable/logo-maskable-144x144.png'], + [152, 'public/res/logo-maskable/logo-maskable-152x152.png'], + [167, 'public/res/logo-maskable/logo-maskable-167x167.png'], + [180, 'public/res/logo-maskable/logo-maskable-180x180.png'], + [192, 'public/res/logo-maskable/logo-maskable-192x192.png'], + [256, 'public/res/logo-maskable/logo-maskable-256x256.png'], + [36, 'public/res/logo-maskable/logo-maskable-36x36.png'], + [384, 'public/res/logo-maskable/logo-maskable-384x384.png'], + [48, 'public/res/logo-maskable/logo-maskable-48x48.png'], + [512, 'public/res/logo-maskable/logo-maskable-512x512.png'], + [57, 'public/res/logo-maskable/logo-maskable-57x57.png'], + [60, 'public/res/logo-maskable/logo-maskable-60x60.png'], + [72, 'public/res/logo-maskable/logo-maskable-72x72.png'], + [76, 'public/res/logo-maskable/logo-maskable-76x76.png'], + [96, 'public/res/logo-maskable/logo-maskable-96x96.png'], + ]; + + logger.info('Replacing maskable icons (using maskless input)...'); + for (const [size, out] of MASKABLE_TARGETS) { + ffmpegCmd(maskless, resolve(BASE_DIR, out), size); + } + + logger.info('Handling SVG assets in public/res/svg/...'); + const svgDir = resolve(BASE_DIR, 'public/res/svg'); + mkdirSync(svgDir, { recursive: true }); + + logger.info(`Copying circular SVG to ${svgDir}/logo.svg`); + copyFileSync(circular, resolve(svgDir, 'logo.svg')); + + logger.info(`Copying maskable SVG to ${svgDir}/logo-maskable.svg`); + copyFileSync(maskless, resolve(svgDir, 'logo-maskable.svg')); + + copyFileSync(highlight, resolve(svgDir, 'highlight.svg')); + copyFileSync(unread, resolve(svgDir, 'unread.svg')); + + logger.info('All done. Please review the generated files.'); +} + +main(process.argv.slice(2)); diff --git a/scripts/replace-logo.sh b/scripts/replace-logo.sh deleted file mode 100755 index 5d9231851..000000000 --- a/scripts/replace-logo.sh +++ /dev/null @@ -1,126 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -readonly BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" - -usage(){ - cat <&2 - exit 2 - fi - if [[ "${f,,}" != *.svg ]]; then - echo "Input must be an SVG: $f" >&2 - exit 3 - fi -done - -ffmpeg_cmd(){ - local in="$1" out="$2" size="$3" - mkdir -p "$(dirname "$out")" - echo "Generating $out ($size x $size)" - ffmpeg -y -width "$size" -height "$size" -i "$in" "$out" 2>/dev/null -} - -# All inputs are required to be SVG. Use ffmpeg to render SVGs to PNG targets -# and copy SVGs directly to the svg assets directory. - -is_svg(){ - local f="$1" - [[ "${f,,}" == *.svg ]] -} - -echo "Replacing circular icons..." - -declare -a CIRCULAR_TARGETS=( - "512:$BASE_DIR/public/favicon.png" - "2560:$BASE_DIR/public/full_res_sable.png" - "144:$BASE_DIR/public/res/logo/logo-144x144.png" - "192:$BASE_DIR/public/res/logo/logo-192x192.png" - "256:$BASE_DIR/public/res/logo/logo-256x256.png" - "36:$BASE_DIR/public/res/logo/logo-36x36.png" - "384:$BASE_DIR/public/res/logo/logo-384x384.png" - "48:$BASE_DIR/public/res/logo/logo-48x48.png" - "512:$BASE_DIR/public/res/logo/logo-512x512.png" - "72:$BASE_DIR/public/res/logo/logo-72x72.png" - "96:$BASE_DIR/public/res/logo/logo-96x96.png" -) - -for entry in "${CIRCULAR_TARGETS[@]}"; do - size=${entry%%:*} - out=${entry#*:} - ffmpeg_cmd "$CIRCULAR" "$out" "$size" -done - -echo "Replacing maskable icons (using maskless input)..." - -declare -a MASKABLE_TARGETS=( - "114:$BASE_DIR/public/res/logo-maskable/logo-maskable-114x114.png" - "120:$BASE_DIR/public/res/logo-maskable/logo-maskable-120x120.png" - "144:$BASE_DIR/public/res/logo-maskable/logo-maskable-144x144.png" - "152:$BASE_DIR/public/res/logo-maskable/logo-maskable-152x152.png" - "167:$BASE_DIR/public/res/logo-maskable/logo-maskable-167x167.png" - "180:$BASE_DIR/public/res/logo-maskable/logo-maskable-180x180.png" - "192:$BASE_DIR/public/res/logo-maskable/logo-maskable-192x192.png" - "256:$BASE_DIR/public/res/logo-maskable/logo-maskable-256x256.png" - "36:$BASE_DIR/public/res/logo-maskable/logo-maskable-36x36.png" - "384:$BASE_DIR/public/res/logo-maskable/logo-maskable-384x384.png" - "48:$BASE_DIR/public/res/logo-maskable/logo-maskable-48x48.png" - "512:$BASE_DIR/public/res/logo-maskable/logo-maskable-512x512.png" - "57:$BASE_DIR/public/res/logo-maskable/logo-maskable-57x57.png" - "60:$BASE_DIR/public/res/logo-maskable/logo-maskable-60x60.png" - "72:$BASE_DIR/public/res/logo-maskable/logo-maskable-72x72.png" - "76:$BASE_DIR/public/res/logo-maskable/logo-maskable-76x76.png" - "96:$BASE_DIR/public/res/logo-maskable/logo-maskable-96x96.png" -) - -for entry in "${MASKABLE_TARGETS[@]}"; do - size=${entry%%:*} - out=${entry#*:} - ffmpeg_cmd "$MASKLESS" "$out" "$size" -done - -echo "Handling SVG assets in public/res/svg/..." - -SVG_DIR="$BASE_DIR/public/res/svg" -mkdir -p "$SVG_DIR" - -# logo.svg from circular input (inputs are SVG so copy directly) -echo "Copying circular SVG to $SVG_DIR/logo.svg" -cp "$CIRCULAR" "$SVG_DIR/logo.svg" - -# logo-maskable.svg from maskless input -echo "Copying maskable SVG to $SVG_DIR/logo-maskable.svg" -cp "$MASKLESS" "$SVG_DIR/logo-maskable.svg" - -# highlight.svg -cp "$HIGHLIGHT" "$SVG_DIR/highlight.svg" - -# unread.svg -cp "$UNREAD" "$SVG_DIR/unread.svg" - -echo "All done. Please review the generated files." diff --git a/scripts/tauri.js b/scripts/tauri.js index e1c6c2ad7..59a028415 100644 --- a/scripts/tauri.js +++ b/scripts/tauri.js @@ -1,18 +1,9 @@ #!/usr/bin/env node - -/** - * Script to run tauri commands for a given runtime (wry or cef) with prepended CLI args. - * - * Usage: - * script/tauri [prepended-args...] - * - * Examples: - * script/tauri cef dev --verbose - * script/tauri cef dev -- --verbose - * Both will run: tauri dev --features cef -- --verbose --no-default-features - */ +//MISE description="Run Tauri CLI with platform-specific feature flags" +//USAGE arg "" help="Target" default="wry" choices "wry" "cef" "android" "ios" import { run } from '@tauri-apps/cli'; +import { spawn } from 'node:child_process'; import { fileURLToPath } from 'url'; import { dirname, join } from 'path'; import process from 'node:process'; @@ -27,19 +18,19 @@ const __dirname = dirname(__filename); const cmdlineArgs = process.argv.slice(2); if (cmdlineArgs.length < 2) { - logger.error('Usage: node scripts/tauri [prepended-args...]'); + logger.error('Usage: node scripts/tauri [prepended-args...]'); + logger.error(` ${dim('platform:')} wry, cef, android, or ios`); logger.error(` ${dim('command:')} dev or build`); - logger.error(` ${dim('runtime:')} wry or cef`); - logger.error( - ` ${dim('prepended-args:')} Arguments to prepend to the cargo args (-- separator is optional)` - ); process.exit(1); } -const [runtime, cmd, ...tauriArgs] = cmdlineArgs; +const [platform, cmd, ...tauriArgs] = cmdlineArgs; + +const MOBILE = ['android', 'ios']; +const DESKTOP = ['wry', 'cef']; -if (!['wry', 'cef'].includes(runtime)) { - logger.error(`Invalid runtime: ${runtime}. Must be 'wry' or 'cef'`); +if (![...DESKTOP, ...MOBILE].includes(platform)) { + logger.error(`Invalid platform: ${platform}. Must be wry, cef, android, or ios`); process.exit(1); } if (!['dev', 'build'].includes(cmd)) { @@ -47,23 +38,30 @@ if (!['dev', 'build'].includes(cmd)) { process.exit(1); } -tauriArgs.unshift('--features', runtime); -// tauri's Linux bundler can't package CEF; scripts/cef-package.sh does that. -if (runtime === 'cef' && cmd === 'build' && !tauriArgs.includes('--no-bundle')) { - tauriArgs.unshift('--no-bundle'); -} -if (!tauriArgs.includes('--')) { - tauriArgs.push('--'); -} -tauriArgs.push('--no-default-features'); +process.chdir(join(__dirname, '..')); -const args = [cmd, ...tauriArgs]; +if (MOBILE.includes(platform)) { + logger.info(`${dim('Running:')} tauri ${[platform, cmd, ...tauriArgs].join(' ')}`); + const child = spawn('tauri', [platform, cmd, ...tauriArgs], { + stdio: 'inherit', + shell: true, + }); + child.on('exit', (code) => process.exit(code ?? 1)); +} else { + const args = [cmd, '--features', platform, ...tauriArgs]; + if (!tauriArgs.includes('--')) { + args.push('--'); + } + args.push('--no-default-features'); -process.chdir(join(__dirname, '..')); + if (platform === 'cef' && cmd === 'build' && !tauriArgs.includes('--no-bundle')) { + args.unshift('--no-bundle'); + } -logger.info(`${dim('Running:')} tauri ${args.join(' ')}`); + logger.info(`${dim('Running:')} tauri ${args.join(' ')}`); -run(args, 'tauri').catch((error) => { - logger.error(`Failed to run tauri: ${error?.message ?? error}`); - process.exit(1); -}); + run(args, 'tauri').catch((error) => { + logger.error(`Failed to run tauri: ${error?.message ?? error}`); + process.exit(1); + }); +} From f24c71bf485a91e7647f6175c12dac6588fc16b9 Mon Sep 17 00:00:00 2001 From: hazre Date: Wed, 22 Jul 2026 01:55:57 +0200 Subject: [PATCH 06/11] chore(mise): add task definitions and reorganize scripts Signed-off-by: hazre --- .github/workflows/tauri-build.yml | 2 +- mise.toml | 64 ++++++++++++++++++- .../{cef-copy-libs.sh => cef/copy-libs.sh} | 0 scripts/{cef-package.sh => cef/package.sh} | 0 .../symlink.js} | 1 + scripts/install-knope.js | 2 + scripts/normalize-imports.js | 2 + 7 files changed, 67 insertions(+), 4 deletions(-) rename scripts/{cef-copy-libs.sh => cef/copy-libs.sh} (100%) rename scripts/{cef-package.sh => cef/package.sh} (100%) mode change 100755 => 100644 rename scripts/{symlink-tauri-icons.js => icons/symlink.js} (98%) diff --git a/.github/workflows/tauri-build.yml b/.github/workflows/tauri-build.yml index ac3dd679e..c0e0db11b 100644 --- a/.github/workflows/tauri-build.yml +++ b/.github/workflows/tauri-build.yml @@ -275,7 +275,7 @@ jobs: - name: Build native packages if: matrix.cef shell: bash - run: bash scripts/cef-package.sh "$VERSION" + run: bash scripts/cef/package.sh "$VERSION" - name: Sign the AppImage for the updater if: ${{ matrix.cef && env.TAURI_SIGNING_PRIVATE_KEY != '' }} diff --git a/mise.toml b/mise.toml index 04d18ed87..3cfa1a944 100644 --- a/mise.toml +++ b/mise.toml @@ -1,7 +1,65 @@ +[env] +_.path = ["{{config_root}}/node_modules/.bin"] + [settings] idiomatic_version_file_enable_tools = ["pnpm", "node", "rust"] experimental = true -[tools] -cargo-binstall = "1.21.0" -"cargo:knope" = "0.23.0" +[task_config] +includes = ["scripts"] + +[tasks.dev] +description = "Start Vite dev server" +alias = "d" +run = "vite dev" +raw = true + +[tasks.build] +description = "Build frontend with Vite" +alias = "b" +run = "vite build" + +[tasks.preview] +description = "Preview the production build" +alias = "p" +run = "vite preview" + +[tasks.lint] +description = "Run all linting, typechecking, formatting, and dead code checks" +alias = "l" +run = ["tsc", "oxlint .", "oxfmt --check .", "knip"] + +[tasks.lint-fix] +description = "Fix lint issues, format, and run typecheck and dead code checks" +alias = "lf" +run = ["oxlint . --fix", "oxfmt .", "knip --fix"] + +[tasks.test] +description = "Run tests" +alias = "t" +run = "vitest" +raw = true + +[tasks.document-change] +description = "Document a change with knope" +alias = "doc" +run = "knope document-change" + +[tasks."cargo:lint"] +description = "Check Rust formatting and lint with Clippy" +alias = ["cl", "cargo-lint"] +dir = "src-tauri" +run = ["cargo fmt --check", "cargo clippy --all-targets --all-features -- -D warnings"] + +[tasks."cargo:lint-fix"] +description = "Fix Rust formatting and lint issues" +alias = ["clf", "cargo-lint-fix"] +dir = "src-tauri" +run = ["cargo fmt", "cargo clippy --fix --allow-dirty --all-targets --all-features -- -D warnings"] + +[tasks."cargo:test"] +description = "Run Rust tests" +alias = ["ct", "cargo-test"] +dir = "src-tauri" +run = "cargo test" +raw = true diff --git a/scripts/cef-copy-libs.sh b/scripts/cef/copy-libs.sh similarity index 100% rename from scripts/cef-copy-libs.sh rename to scripts/cef/copy-libs.sh diff --git a/scripts/cef-package.sh b/scripts/cef/package.sh old mode 100755 new mode 100644 similarity index 100% rename from scripts/cef-package.sh rename to scripts/cef/package.sh diff --git a/scripts/symlink-tauri-icons.js b/scripts/icons/symlink.js similarity index 98% rename from scripts/symlink-tauri-icons.js rename to scripts/icons/symlink.js index 25674f335..938763932 100644 --- a/scripts/symlink-tauri-icons.js +++ b/scripts/icons/symlink.js @@ -1,4 +1,5 @@ #!/usr/bin/env node +//MISE description="Create symlinks for Tauri icons from the source set" /* eslint-disable no-console */ import fs from 'node:fs'; diff --git a/scripts/install-knope.js b/scripts/install-knope.js index 74fd9c264..ced1f260b 100644 --- a/scripts/install-knope.js +++ b/scripts/install-knope.js @@ -1,4 +1,6 @@ #!/usr/bin/env node +//MISE hide=true +//MISE description="Install or update knope to the pinned version" import { spawnSync } from 'node:child_process'; import process from 'node:process'; import { chmodSync, existsSync, mkdirSync, realpathSync, writeFileSync } from 'node:fs'; diff --git a/scripts/normalize-imports.js b/scripts/normalize-imports.js index 77af442c3..415e36696 100644 --- a/scripts/normalize-imports.js +++ b/scripts/normalize-imports.js @@ -1,4 +1,6 @@ #!/usr/bin/env node +//MISE hide=true +//MISE description="Normalize import paths across the codebase" /* oxlint-disable no-console */ import fs from 'node:fs/promises'; From 9878719242fa6758162d18ad778a1e65f968a6c2 Mon Sep 17 00:00:00 2001 From: hazre Date: Wed, 22 Jul 2026 04:01:52 +0200 Subject: [PATCH 07/11] chore(scripts): replace fpm with nfpm for deb/rpm packaging - Add nfpm.yaml declarative config with contents, deps, per-packager overrides - Replace fpm CLI invocations in package.sh with nfpm pkg - Manage appimagetool and nfpm via mise file task tools - Remove manual appimagetool download + sha256 verification - Fix stale paths from scripts/cef/ move (ROOT, copy-libs reference, usage) - Add version extraction guard and appimagetool availability check Signed-off-by: hazre --- nfpm.yaml | 48 +++++++++++++++++++++++++++++ scripts/cef/package.sh | 70 +++++++++++++++++------------------------- 2 files changed, 76 insertions(+), 42 deletions(-) create mode 100644 nfpm.yaml diff --git a/nfpm.yaml b/nfpm.yaml new file mode 100644 index 000000000..8f44eab70 --- /dev/null +++ b/nfpm.yaml @@ -0,0 +1,48 @@ +# yaml-language-server: $schema=https://nfpm.goreleaser.com/schema.json + +name: sable +arch: amd64 +platform: linux +version: ${PKG_VERSION} +release: ${PKG_RELEASE} +version_schema: semver +section: net +maintainer: SableClient +description: Sable, a Matrix client +homepage: https://sable.moe + +contents: + - src: ${PKGROOT}/opt/sable/ + dst: /opt/sable + type: tree + - src: ${PKGROOT}/usr/ + dst: /usr + type: tree + +overrides: + deb: + depends: + - libgtk-3-0 + - libnss3 + - libnspr4 + - libgbm1 + - libdrm2 + - libxkbcommon0 + - libasound2 + - libcups2 + - xdg-utils + - xwayland + - libayatana-appindicator3-1 + rpm: + depends: + - gtk3 + - nss + - nspr + - mesa-libgbm + - libdrm + - libxkbcommon + - alsa-lib + - cups-libs + - xdg-utils + - xorg-x11-server-Xwayland + - libayatana-appindicator3.so.1()(64bit) diff --git a/scripts/cef/package.sh b/scripts/cef/package.sh index 440d48644..0523d777f 100644 --- a/scripts/cef/package.sh +++ b/scripts/cef/package.sh @@ -1,13 +1,15 @@ #!/usr/bin/env bash #MISE description="Package CEF build into deb/rpm/AppImage" +#MISE tools={nfpm="2.47.0", "github:AppImage/appimagetool" = {version = "1.9.1", matching = ".AppImage"}} # Package the Linux CEF build into deb/rpm/AppImage. Used by CI and locally. # Run after the binary is built (pnpm tauri:cef build). -# Usage: scripts/cef-package.sh [version] +# Usage: scripts/cef/package.sh [version] set -euo pipefail -ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" cd "$ROOT" VERSION="${1:-$(grep -m1 '"version":' src-tauri/tauri.conf.json | sed 's/.*: *"\(.*\)".*/\1/')}" +: "${VERSION:?version not found in src-tauri/tauri.conf.json}" DEB_VERSION="$VERSION" RPM_VERSION="$VERSION" RPM_ITERATION=1 @@ -45,7 +47,7 @@ stage_runtime() { local dest="$1" mkdir -p "$dest" cp "$STAGE/$BIN_NAME" "$dest/sable" - bash scripts/cef-copy-libs.sh release "$dest" + bash scripts/cef/copy-libs.sh release "$dest" } # Bundle the system-tray libraries (Tauri's linuxdeploy path normally does this, @@ -87,8 +89,10 @@ MimeType=x-scheme-handler/sable;x-scheme-handler/moe.sable.app; EOF } -if command -v fpm >/dev/null 2>&1; then +CONFIG="$ROOT/nfpm.yaml" +if command -v nfpm >/dev/null 2>&1; then PKGROOT="$WORK/pkgroot" + export PKGROOT stage_runtime "$PKGROOT/opt/sable" mkdir -p "$PKGROOT/usr/bin" "$PKGROOT/usr/share/applications" cat > "$PKGROOT/usr/bin/sable" <<'EOF' @@ -102,57 +106,39 @@ EOF cp "src-tauri/icons/${size}.png" \ "$PKGROOT/usr/share/icons/hicolor/${size}/apps/sable.png" done - # 128x128@2x is 256x256 mkdir -p "$PKGROOT/usr/share/icons/hicolor/256x256/apps" cp "src-tauri/icons/128x128@2x.png" \ "$PKGROOT/usr/share/icons/hicolor/256x256/apps/sable.png" - COMMON=(-s dir -n sable - --description "Sable, a Matrix client" - --url "https://sable.moe" --maintainer "SableClient" - --category net) - # CEF deps: no WebKitGTK. ALSA/CUPS are NEEDED by libcef.so; - # xwayland because main.rs forces GDK_BACKEND=x11. - DEB_DEPS=(--depends libgtk-3-0 --depends libnss3 --depends libnspr4 - --depends libgbm1 --depends libdrm2 --depends libxkbcommon0 - --depends libasound2 --depends libcups2 --depends xdg-utils - --depends xwayland --depends libayatana-appindicator3-1) - (cd "$OUT/deb" && fpm "${COMMON[@]}" -v "$DEB_VERSION" --iteration 1 \ - -t deb -a amd64 -p "Sable-${VERSION}-linux-x86_64.deb" "${DEB_DEPS[@]}" -C "$PKGROOT" .) + PKG_VERSION="$DEB_VERSION" PKG_RELEASE=1 nfpm pkg -f "$CONFIG" -p deb \ + -t "$OUT/deb/Sable-${VERSION}-linux-x86_64.deb" - RPM_DEPS=(--depends gtk3 --depends nss --depends nspr - --depends mesa-libgbm --depends libdrm --depends libxkbcommon - --depends alsa-lib --depends cups-libs --depends xdg-utils - --depends xorg-x11-server-Xwayland - --depends 'libayatana-appindicator3.so.1()(64bit)') - (cd "$OUT/rpm" && fpm "${COMMON[@]}" -v "$RPM_VERSION" --iteration "$RPM_ITERATION" \ - -t rpm -a x86_64 -p "Sable-${VERSION}-linux-x86_64.rpm" "${RPM_DEPS[@]}" -C "$PKGROOT" .) + PKG_VERSION="$RPM_VERSION" PKG_RELEASE="$RPM_ITERATION" nfpm pkg -f "$CONFIG" -p rpm \ + -t "$OUT/rpm/Sable-${VERSION}-linux-x86_64.rpm" else - echo "fpm not found; skipping deb/rpm (building AppImage only)" + echo "nfpm not found; skipping deb/rpm" fi -APPDIR="$WORK/Sable.AppDir" -stage_runtime "$APPDIR/usr/bin" -stage_appindicator "$APPDIR/usr/bin" -# nosuid AppImage mount: drop setuid chrome-sandbox, use the namespace sandbox. -rm -f "$APPDIR/usr/bin/chrome-sandbox" -write_desktop "$APPDIR/sable.desktop" -cp src-tauri/icons/128x128.png "$APPDIR/sable.png" -cat > "$APPDIR/AppRun" <<'EOF' +if command -v appimagetool >/dev/null 2>&1; then + APPDIR="$WORK/Sable.AppDir" + stage_runtime "$APPDIR/usr/bin" + stage_appindicator "$APPDIR/usr/bin" + # nosuid AppImage mount: drop setuid chrome-sandbox, use the namespace sandbox. + rm -f "$APPDIR/usr/bin/chrome-sandbox" + write_desktop "$APPDIR/sable.desktop" + cp src-tauri/icons/128x128.png "$APPDIR/sable.png" + cat > "$APPDIR/AppRun" <<'EOF' #!/bin/sh HERE="$(dirname "$(readlink -f "$0")")" export LD_LIBRARY_PATH="$HERE/usr/bin${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" exec "$HERE/usr/bin/sable" "$@" EOF -chmod 755 "$APPDIR/AppRun" + chmod 755 "$APPDIR/AppRun" -APPIMAGETOOL_SHA256=ed4ce84f0d9caff66f50bcca6ff6f35aae54ce8135408b3fa33abfc3cb384eb0 -APPIMAGETOOL="$WORK/appimagetool" -curl -fsSL -o "$APPIMAGETOOL" \ - https://github.com/AppImage/appimagetool/releases/download/1.9.1/appimagetool-x86_64.AppImage -echo "${APPIMAGETOOL_SHA256} $APPIMAGETOOL" | sha256sum -c - -chmod +x "$APPIMAGETOOL" -APPIMAGE_EXTRACT_AND_RUN=1 ARCH=x86_64 "$APPIMAGETOOL" "$APPDIR" \ - "$OUT/appimage/Sable-${VERSION}-linux-x86_64.AppImage" + ARCH=x86_64 appimagetool "$APPDIR" \ + "$OUT/appimage/Sable-${VERSION}-linux-x86_64.AppImage" +else + echo "appimagetool not found; skipping AppImage" >&2 +fi echo "Packages in: $OUT" From 503e1315e6940a99e5088c20da276f5d1347901f Mon Sep 17 00:00:00 2001 From: hazre Date: Wed, 22 Jul 2026 05:31:25 +0200 Subject: [PATCH 08/11] chore(ci): update ci to use mise Signed-off-by: hazre --- .github/actions/prepare-tofu/action.yml | 16 +++---- .github/actions/setup/action.yml | 10 ++--- .github/workflows/cloudflare-web-deploy.yml | 24 +++++++++-- .github/workflows/cloudflare-web-dev.yml | 4 +- .github/workflows/codeql.yml | 2 + .github/workflows/docker-publish.yml | 6 ++- .github/workflows/flake-lock-fix.yml | 9 ++-- .github/workflows/prepare-release.yml | 8 ++-- .github/workflows/release.yml | 7 +-- .github/workflows/rust-quality.yml | 20 +++++---- .github/workflows/tauri-build.yml | 47 ++++++++++++--------- .github/zizmor.yml | 4 ++ mise.toml | 38 ++++++++++++++--- 13 files changed, 123 insertions(+), 72 deletions(-) create mode 100644 .github/zizmor.yml diff --git a/.github/actions/prepare-tofu/action.yml b/.github/actions/prepare-tofu/action.yml index c64332e3c..09e5f92c7 100644 --- a/.github/actions/prepare-tofu/action.yml +++ b/.github/actions/prepare-tofu/action.yml @@ -2,10 +2,6 @@ name: Prepare OpenTofu Deployment description: Prepares OpenTofu in infra/web. inputs: - opentofu-version: - description: The OpenTofu version to install. - required: false - default: '1.11.5' is_release_tag: description: Whether the build is for a release tag. Passed through to VITE_IS_RELEASE_TAG. required: false @@ -27,22 +23,20 @@ runs: SENTRY_ORG: ${{ env.SENTRY_ORG }} SENTRY_PROJECT: ${{ env.SENTRY_PROJECT }} - - name: Setup OpenTofu - uses: opentofu/setup-opentofu@9d84900f3238fab8cd84ce47d658d25dd008be2f # v1.0.8 - with: - tofu_version: ${{ inputs.opentofu-version }} + - name: Setup OpenTofu via mise + uses: jdx/mise-action@dad1bfd3df957f44999b559dd69dc1671cb4e9ea # v4.2.1 - name: Check formatting shell: bash working-directory: ${{ github.workspace }}/infra/web - run: tofu fmt -check + run: mise run opentofu -- fmt -check - name: Initialize OpenTofu shell: bash working-directory: ${{ github.workspace }}/infra/web - run: tofu init -input=false -reconfigure + run: mise run opentofu -- init -input=false -reconfigure - name: Validate configuration shell: bash working-directory: ${{ github.workspace }}/infra/web - run: tofu validate -no-color + run: mise run opentofu -- validate -no-color diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index 9b4c9acbb..961db8d82 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -18,14 +18,10 @@ inputs: runs: using: composite steps: - - name: Setup pnpm - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0 - - - name: Setup node - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + - name: Setup tools (mise) + uses: jdx/mise-action@dad1bfd3df957f44999b559dd69dc1671cb4e9ea # v4.2.1 with: - node-version-file: '.node-version' - cache: 'pnpm' + cache: true - name: Install dependencies shell: bash diff --git a/.github/workflows/cloudflare-web-deploy.yml b/.github/workflows/cloudflare-web-deploy.yml index 14d65c869..5bba6a672 100644 --- a/.github/workflows/cloudflare-web-deploy.yml +++ b/.github/workflows/cloudflare-web-deploy.yml @@ -55,8 +55,16 @@ jobs: - name: Resolve release version id: version shell: bash + env: + GIT_TAG: ${{ inputs.git_tag }} + REF_NAME: ${{ github.ref_name }} + EVENT_NAME: ${{ github.event_name }} run: | - TAG="${{ github.event_name == 'workflow_dispatch' && inputs.git_tag || github.ref_name }}" + if [[ "$EVENT_NAME" == "workflow_dispatch" && -n "$GIT_TAG" ]]; then + TAG="$GIT_TAG" + else + TAG="$REF_NAME" + fi echo "version=${TAG#v}" >> "$GITHUB_OUTPUT" - name: Prepare OpenTofu deployment @@ -95,8 +103,16 @@ jobs: - name: Resolve release version id: version shell: bash + env: + GIT_TAG: ${{ inputs.git_tag }} + REF_NAME: ${{ github.ref_name }} + EVENT_NAME: ${{ github.event_name }} run: | - TAG="${{ github.event_name == 'workflow_dispatch' && inputs.git_tag || github.ref_name }}" + if [[ "$EVENT_NAME" == "workflow_dispatch" && -n "$GIT_TAG" ]]; then + TAG="$GIT_TAG" + else + TAG="$REF_NAME" + fi echo "version=${TAG#v}" >> "$GITHUB_OUTPUT" - name: Prepare OpenTofu deployment @@ -112,7 +128,7 @@ jobs: SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }} - name: Plan infrastructure - run: tofu plan -input=false -no-color + run: mise run opentofu -- plan -input=false -no-color - name: Apply infrastructure - run: tofu apply -input=false -auto-approve + run: mise run opentofu -- apply -input=false -auto-approve diff --git a/.github/workflows/cloudflare-web-dev.yml b/.github/workflows/cloudflare-web-dev.yml index 35ffa572c..25acfaea8 100644 --- a/.github/workflows/cloudflare-web-dev.yml +++ b/.github/workflows/cloudflare-web-dev.yml @@ -62,7 +62,7 @@ jobs: SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }} - name: Plan infrastructure - run: tofu plan -input=false -no-color + run: mise run opentofu -- plan -input=false -no-color - name: Apply infrastructure - run: tofu apply -input=false -auto-approve + run: mise run opentofu -- apply -input=false -auto-approve diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index bdb1d0bd5..07e14f503 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -58,6 +58,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false # Add any setup steps before running the `github/codeql-action/init` action. # This includes steps like installing compilers or runtimes (`actions/setup-node` diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 82d8d00c9..e8f1afcd5 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -49,8 +49,8 @@ jobs: id: release_tag shell: bash run: | - if [[ "${{ github.event_name }}" == "workflow_dispatch" && -n "${{ inputs.git_tag }}" ]]; then - TAG="${{ inputs.git_tag }}" + if [[ "${{ github.event_name }}" == "workflow_dispatch" && -n "${INPUTS_GIT_TAG}" ]]; then + TAG="${INPUTS_GIT_TAG}" else TAG="${GITHUB_REF#refs/tags/}" fi @@ -65,6 +65,8 @@ jobs: echo "value=" >> "$GITHUB_OUTPUT" echo "is_release=false" >> "$GITHUB_OUTPUT" fi + env: + INPUTS_GIT_TAG: ${{ inputs.git_tag }} - name: Extract metadata id: meta diff --git a/.github/workflows/flake-lock-fix.yml b/.github/workflows/flake-lock-fix.yml index c7b844e72..fdf800a84 100644 --- a/.github/workflows/flake-lock-fix.yml +++ b/.github/workflows/flake-lock-fix.yml @@ -42,17 +42,20 @@ jobs: - name: Get GitHub App User ID id: get-user-id - run: echo "user-id=$(gh api "/users/${{ steps.app-token.outputs.app-slug }}[bot]" --jq .id)" >> "$GITHUB_OUTPUT" + run: echo "user-id=$(gh api "/users/${STEPS_APP_TOKEN_OUTPUTS_APP_SLUG}[bot]" --jq .id)" >> "$GITHUB_OUTPUT" env: GH_TOKEN: ${{ steps.app-token.outputs.token }} + STEPS_APP_TOKEN_OUTPUTS_APP_SLUG: ${{ steps.app-token.outputs.app-slug }} - name: Configure bot git identity run: | - git config --global user.name '${{ steps.app-token.outputs.app-slug }}[bot]' - git config --global user.email '${{ steps.get-user-id.outputs.user-id }}+${{ steps.app-token.outputs.app-slug }}[bot]@users.noreply.github.com' + git config --global user.name '${STEPS_APP_TOKEN_OUTPUTS_APP_SLUG}[bot]' + git config --global user.email '${STEPS_GET_USER_ID_OUTPUTS_USER_ID}+${STEPS_APP_TOKEN_OUTPUTS_APP_SLUG}[bot]@users.noreply.github.com' gh auth setup-git env: GH_TOKEN: ${{ steps.app-token.outputs.token }} + STEPS_APP_TOKEN_OUTPUTS_APP_SLUG: ${{ steps.app-token.outputs.app-slug }} + STEPS_GET_USER_ID_OUTPUTS_USER_ID: ${{ steps.get-user-id.outputs.user-id }} - name: Commit and push if changed if: steps.check.outcome == 'failure' diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml index 60573416b..29ae03c5d 100644 --- a/.github/workflows/prepare-release.yml +++ b/.github/workflows/prepare-release.yml @@ -20,6 +20,8 @@ jobs: with: app-id: ${{ secrets.APP_ID }} private-key: ${{ secrets.APP_PRIVATE_KEY }} + permission-contents: write + permission-pull-requests: write - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -29,12 +31,8 @@ jobs: - uses: fregante/setup-git-user@024bc0b8e177d7e77203b48dab6fb45666854b35 # v2.0.2 - - uses: knope-dev/action@19617851f9f13ab2f27a05989c55efb18aca3675 # v2.1.2 - with: - version: 0.22.3 - - name: Prepare Release - run: knope prepare-release --verbose + run: mise run knope -- prepare-release --verbose env: GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e6e5f9d7f..6eca8284b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,6 +20,7 @@ jobs: with: app-id: ${{ secrets.APP_ID }} private-key: ${{ secrets.APP_PRIVATE_KEY }} + permission-contents: write - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -27,11 +28,7 @@ jobs: persist-credentials: true token: ${{ steps.generate-token.outputs.token }} - - uses: knope-dev/action@19617851f9f13ab2f27a05989c55efb18aca3675 # v2.1.2 - with: - version: 0.22.3 - - name: Create Release - run: knope release --verbose + run: mise run knope -- release --verbose env: GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }} diff --git a/.github/workflows/rust-quality.yml b/.github/workflows/rust-quality.yml index f7fdd08f0..98679c094 100644 --- a/.github/workflows/rust-quality.yml +++ b/.github/workflows/rust-quality.yml @@ -20,17 +20,19 @@ jobs: runs-on: ubuntu-latest permissions: contents: read + env: + CARGO_INCREMENTAL: 0 + CARGO_TERM_COLOR: always steps: - name: Checkout repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - - name: Setup Rust - uses: dtolnay/rust-toolchain@2c7215f132e9ebf062739d9130488b56d53c060c # 2c7215f132e9ebf062739d9130488b56d53c060c + - name: Setup mise + uses: jdx/mise-action@dad1bfd3df957f44999b559dd69dc1671cb4e9ea # v4.2.1 with: - toolchain: stable - components: rustfmt + cache: true - name: Check Rust formatting run: cargo fmt --manifest-path src-tauri/Cargo.toml -- --check @@ -40,6 +42,9 @@ jobs: runs-on: ubuntu-22.04 permissions: contents: read + env: + CARGO_INCREMENTAL: 0 + CARGO_TERM_COLOR: always steps: - name: Checkout repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -60,11 +65,10 @@ jobs: libxdo-dev \ pkg-config - - name: Setup Rust - uses: dtolnay/rust-toolchain@2c7215f132e9ebf062739d9130488b56d53c060c # 2c7215f132e9ebf062739d9130488b56d53c060c + - name: Setup mise + uses: jdx/mise-action@dad1bfd3df957f44999b559dd69dc1671cb4e9ea # v4.2.1 with: - toolchain: stable - components: clippy + cache: true - name: Cache Rust build uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 diff --git a/.github/workflows/tauri-build.yml b/.github/workflows/tauri-build.yml index c0e0db11b..6957eaada 100644 --- a/.github/workflows/tauri-build.yml +++ b/.github/workflows/tauri-build.yml @@ -120,7 +120,7 @@ jobs: - name: macOS platform: macos-latest asset-platform: macos-universal - rust-targets: aarch64-apple-darwin,x86_64-apple-darwin + rust-targets: aarch64-apple-darwin x86_64-apple-darwin args: --target universal-apple-darwin bundle_path: src-tauri/target/universal-apple-darwin/release/bundle - name: Windows @@ -140,6 +140,8 @@ jobs: VERSION: ${{ needs.setup-release.outputs.version }} VITE_APP_VERSION: ${{ needs.setup-release.outputs.version }} VITE_IS_RELEASE_TAG: ${{ needs.setup-release.outputs.nightly == 'true' && 'true' || '' }} + CARGO_INCREMENTAL: 0 + CARGO_TERM_COLOR: always NODE_OPTIONS: --max-old-space-size=8192 TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} @@ -173,11 +175,10 @@ jobs: - name: Setup app uses: ./.github/actions/setup - - name: Setup Rust - uses: dtolnay/rust-toolchain@2c7215f132e9ebf062739d9130488b56d53c060c # 2c7215f132e9ebf062739d9130488b56d53c060c - with: - toolchain: stable - targets: ${{ matrix.rust-targets }} + - name: Add Rust targets + if: ${{ matrix.rust-targets != '' }} + shell: bash + run: rustup target add ${{ matrix.rust-targets }} - name: Cache Rust build uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 @@ -329,7 +330,10 @@ jobs: VERSION: ${{ needs.setup-release.outputs.version }} VITE_APP_VERSION: ${{ needs.setup-release.outputs.version }} VITE_IS_RELEASE_TAG: ${{ needs.setup-release.outputs.nightly == 'true' && 'true' || '' }} + CARGO_INCREMENTAL: 0 + CARGO_TERM_COLOR: always NODE_OPTIONS: --max-old-space-size=8192 + RUST_TARGETS: aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android ANDROID_KEY_BASE64: ${{ secrets.ANDROID_KEY_BASE64 }} ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }} ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }} @@ -352,11 +356,9 @@ jobs: - name: Setup Android SDK uses: android-actions/setup-android@40fd30fb8d7440372e1316f5d1809ec01dcd3699 # v4.0.1 - - name: Setup Rust - uses: dtolnay/rust-toolchain@2c7215f132e9ebf062739d9130488b56d53c060c # 2c7215f132e9ebf062739d9130488b56d53c060c - with: - toolchain: stable - targets: aarch64-linux-android,armv7-linux-androideabi,i686-linux-android,x86_64-linux-android + - name: Add Rust targets + shell: bash + run: rustup target add $RUST_TARGETS - name: Cache Rust build uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 @@ -435,6 +437,9 @@ jobs: VERSION: ${{ needs.setup-release.outputs.version }} VITE_APP_VERSION: ${{ needs.setup-release.outputs.version }} VITE_IS_RELEASE_TAG: ${{ needs.setup-release.outputs.nightly == 'true' && 'true' || '' }} + CARGO_INCREMENTAL: 0 + CARGO_TERM_COLOR: always + RUST_TARGETS: aarch64-apple-ios NODE_OPTIONS: --max-old-space-size=8192 steps: - name: Checkout repository @@ -446,11 +451,9 @@ jobs: - name: Setup app uses: ./.github/actions/setup - - name: Setup Rust - uses: dtolnay/rust-toolchain@2c7215f132e9ebf062739d9130488b56d53c060c # 2c7215f132e9ebf062739d9130488b56d53c060c - with: - toolchain: stable - targets: aarch64-apple-ios + - name: Add Rust targets + shell: bash + run: rustup target add $RUST_TARGETS - name: Cache Rust build uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 @@ -498,15 +501,18 @@ jobs: shell: bash env: GH_TOKEN: ${{ github.token }} - run: gh release upload "$TAG" "${{ steps.ipa.outputs.path }}" --clobber + STEPS_IPA_OUTPUTS_PATH: ${{ steps.ipa.outputs.path }} + run: gh release upload "$TAG" "${STEPS_IPA_OUTPUTS_PATH}" --clobber - name: Update AltStore/SideStore source shell: bash env: GH_TOKEN: ${{ github.token }} REPO: ${{ github.repository }} + STEPS_IPA_OUTPUTS_NAME: ${{ steps.ipa.outputs.name }} + STEPS_IPA_OUTPUTS_SIZE: ${{ steps.ipa.outputs.size }} run: | - DOWNLOAD_URL="https://github.com/$REPO/releases/download/$TAG/${{ steps.ipa.outputs.name }}" + DOWNLOAD_URL="https://github.com/$REPO/releases/download/$TAG/${STEPS_IPA_OUTPUTS_NAME}" DATE="$(date -u +'%Y-%m-%dT%H:%M:%SZ')" if gh release download "$TAG" --pattern 'altstore-source.json' --dir . --clobber 2>/dev/null; then echo "Using existing altstore-source.json from release $TAG" @@ -514,7 +520,7 @@ jobs: echo "Using repo altstore-source.json" fi node .github/scripts/update-altstore-source.mjs \ - altstore-source.json "$VERSION" "$VERSION" "${{ steps.ipa.outputs.size }}" "$DOWNLOAD_URL" "$DATE" "Sable $VERSION" + altstore-source.json "$VERSION" "$VERSION" "${STEPS_IPA_OUTPUTS_SIZE}" "$DOWNLOAD_URL" "$DATE" "Sable $VERSION" gh release upload "$TAG" altstore-source.json --clobber updater-manifest: @@ -546,8 +552,9 @@ jobs: shell: bash env: GH_TOKEN: ${{ github.token }} + NEEDS_SETUP_RELEASE_OUTPUTS_NIGHTLY: ${{ needs.setup-release.outputs.nightly }} run: | - if [ "${{ needs.setup-release.outputs.nightly }}" = "true" ]; then + if [ "${NEEDS_SETUP_RELEASE_OUTPUTS_NIGHTLY}" = "true" ]; then gh release view "$TAG" --json assets \ | jq -r --arg cutoff "$STARTED_AT" \ '.assets[] | select(.updatedAt <= $cutoff and (.name | endswith(".sig"))) | .name' \ diff --git a/.github/zizmor.yml b/.github/zizmor.yml new file mode 100644 index 000000000..191a75c29 --- /dev/null +++ b/.github/zizmor.yml @@ -0,0 +1,4 @@ +rules: + cache-poisoning: + remap: + severity: informational diff --git a/mise.toml b/mise.toml index 3cfa1a944..3d7fafb9d 100644 --- a/mise.toml +++ b/mise.toml @@ -29,7 +29,7 @@ description = "Run all linting, typechecking, formatting, and dead code checks" alias = "l" run = ["tsc", "oxlint .", "oxfmt --check .", "knip"] -[tasks.lint-fix] +[tasks."lint:fix"] description = "Fix lint issues, format, and run typecheck and dead code checks" alias = "lf" run = ["oxlint . --fix", "oxfmt .", "knip --fix"] @@ -40,10 +40,16 @@ alias = "t" run = "vitest" raw = true -[tasks.document-change] +[tasks.knope] +run = "knope" +raw_args = true +hide = true +tools = { "cargo:knope" = "0.23.0", cargo-binstall = "1.20.1" } + +[tasks."knope:document-change"] description = "Document a change with knope" -alias = "doc" -run = "knope document-change" +alias = ["doc", "doc"] +run = { task = "knope", args = ["document-change"] } [tasks."cargo:lint"] description = "Check Rust formatting and lint with Clippy" @@ -51,7 +57,7 @@ alias = ["cl", "cargo-lint"] dir = "src-tauri" run = ["cargo fmt --check", "cargo clippy --all-targets --all-features -- -D warnings"] -[tasks."cargo:lint-fix"] +[tasks."cargo:lint:fix"] description = "Fix Rust formatting and lint issues" alias = ["clf", "cargo-lint-fix"] dir = "src-tauri" @@ -63,3 +69,25 @@ alias = ["ct", "cargo-test"] dir = "src-tauri" run = "cargo test" raw = true + +[tasks."actions:pin"] +description = "Pin GitHub Actions to SHA commit hashes" +run = "pinact run" +tools = { "pinact" = "latest" } + +[tasks."actions:audit"] +description = "Audit GitHub Actions for security issues" +run = "zizmor .github/workflows" +tools = { "zizmor" = "latest" } + +[tasks."actions:update"] +description = "Update pinned GitHub Actions to latest SHAs" +run = "pinact run -u" +tools = { "pinact" = "latest" } + + +[tasks.opentofu] +run = "tofu" +raw_args = true +hide = true +tools = { "opentofu" = "1.11.5" } \ No newline at end of file From 913f12e934ce294bacfdc1dc10116a831044c353 Mon Sep 17 00:00:00 2001 From: hazre Date: Wed, 22 Jul 2026 07:23:34 +0200 Subject: [PATCH 09/11] chore: use devEngines for node version Signed-off-by: hazre --- .node-version | 1 - .npmrc | 0 .nvmrc | 1 - package.json | 5 ++--- 4 files changed, 2 insertions(+), 5 deletions(-) delete mode 100644 .node-version create mode 100644 .npmrc delete mode 100644 .nvmrc diff --git a/.node-version b/.node-version deleted file mode 100644 index 32f8c50de..000000000 --- a/.node-version +++ /dev/null @@ -1 +0,0 @@ -24.13.1 diff --git a/.npmrc b/.npmrc new file mode 100644 index 000000000..e69de29bb diff --git a/.nvmrc b/.nvmrc deleted file mode 100644 index a4a7a41bc..000000000 --- a/.nvmrc +++ /dev/null @@ -1 +0,0 @@ -v24.14.0 diff --git a/package.json b/package.json index c0c479bfe..c408c464b 100644 --- a/package.json +++ b/package.json @@ -150,9 +150,8 @@ "vitest": "^4.1.9", "wrangler": "^4.106.0" }, - "engines": { - "node": "24.x", - "pnpm": ">=10" + "devEngines": { + "runtime": { "name": "node", "version": "24.x" } }, "packageManager": "pnpm@10.32.1+sha512.a706938f0e89ac1456b6563eab4edf1d1faf3368d1191fc5c59790e96dc918e4456ab2e67d613de1043d2e8c81f87303e6b40d4ffeca9df15ef1ad567348f2be" } From 3b4b6c9f0dcdbfda5c628a70fb6c5d918080374c Mon Sep 17 00:00:00 2001 From: hazre Date: Wed, 22 Jul 2026 07:37:18 +0200 Subject: [PATCH 10/11] chore: update pnpm lock file Signed-off-by: hazre --- pnpm-lock.yaml | 174 ++++++++++++++++++++----------------------------- 1 file changed, 70 insertions(+), 104 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9f8fc1757..4ac5e2a67 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,7 +5,15 @@ settings: excludeLinksFromLockfile: false overrides: + brace-expansion: '>=1.1.12' + esbuild: '>=0.25.0' + flatted: '>=3.4.2' jsdom>undici: ^7.28.0 + lodash: '>=4.17.23' + minimatch: '>=10.2.3' + rollup: '>=4.59.0' + serialize-javascript: '>=7.0.3' + undici: '>=7.24.0' importers: @@ -254,16 +262,16 @@ importers: version: 0.2.3(esbuild@0.28.1) '@rollup/plugin-inject': specifier: ^5.0.5 - version: 5.0.5(rollup@2.80.0) + version: 5.0.5(rollup@4.62.0) '@rollup/plugin-wasm': specifier: ^6.2.2 - version: 6.2.2(rollup@2.80.0) + version: 6.2.2(rollup@4.62.0) '@sableclient/sable-call-embedded': specifier: 1.1.7 version: 1.1.7 '@sentry/vite-plugin': specifier: ^5.3.0 - version: 5.3.0(rollup@2.80.0) + version: 5.3.0(rollup@4.62.0) '@tauri-apps/cli': specifier: 2.11.4 version: 2.11.4 @@ -338,7 +346,7 @@ importers: version: 7.3.5(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.48.0)(yaml@2.9.0) vite-plugin-compression2: specifier: ^2.5.3 - version: 2.5.3(rollup@2.80.0) + version: 2.5.3(rollup@4.62.0) vite-plugin-pwa: specifier: ^1.3.0 version: 1.3.0(vite@7.3.5(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.48.0)(yaml@2.9.0))(workbox-build@7.4.0(@types/babel__core@7.20.5))(workbox-window@7.4.0) @@ -347,10 +355,10 @@ importers: version: 3.4.0(vite@7.3.5(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.48.0)(yaml@2.9.0)) vite-plugin-svgr: specifier: 4.5.0 - version: 4.5.0(rollup@2.80.0)(typescript@5.9.3)(vite@7.3.5(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.48.0)(yaml@2.9.0)) + version: 4.5.0(rollup@4.62.0)(typescript@5.9.3)(vite@7.3.5(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.48.0)(yaml@2.9.0)) vite-plugin-top-level-await: specifier: ^1.6.0 - version: 1.6.0(@swc/helpers@0.5.23)(rollup@2.80.0)(vite@7.3.5(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.48.0)(yaml@2.9.0)) + version: 1.6.0(@swc/helpers@0.5.23)(rollup@4.62.0)(vite@7.3.5(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.48.0)(yaml@2.9.0)) vitest: specifier: ^4.1.9 version: 4.1.9(@types/node@24.13.2)(@vitest/coverage-v8@4.1.9)(@vitest/ui@4.1.9)(jsdom@29.1.1(@noble/hashes@2.2.0))(vite@7.3.5(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.48.0)(yaml@2.9.0)) @@ -1052,7 +1060,7 @@ packages: '@esbuild-plugins/node-globals-polyfill@0.2.3': resolution: {integrity: sha512-r3MIryXDeXDOZh7ih1l/yE9ZLORCd5e8vWg02azWRGj5SPTuoh69A2AIyn0Z31V/kHBfZ4HgWJ+OK3GTTwLmnw==} peerDependencies: - esbuild: '*' + esbuild: '>=0.25.0' '@esbuild/aix-ppc64@0.27.7': resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==} @@ -2313,7 +2321,7 @@ packages: peerDependencies: '@babel/core': ^7.0.0 '@types/babel__core': ^7.1.9 - rollup: ^1.20.0||^2.0.0 + rollup: '>=4.59.0' peerDependenciesMeta: '@types/babel__core': optional: true @@ -2322,7 +2330,7 @@ packages: resolution: {integrity: sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==} engines: {node: '>=14.0.0'} peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + rollup: '>=4.59.0' peerDependenciesMeta: rollup: optional: true @@ -2331,7 +2339,7 @@ packages: resolution: {integrity: sha512-tgg6b91pAybXHJQMAAwW9VuWBO6Thi+q7BCNARLwSqlmsHz0XYURtGvh/AuwSADXSI4h/2uHbs7s4FzlZDGSGA==} engines: {node: '>=14.0.0'} peerDependencies: - rollup: ^2.78.0||^3.0.0||^4.0.0 + rollup: '>=4.59.0' peerDependenciesMeta: rollup: optional: true @@ -2339,13 +2347,13 @@ packages: '@rollup/plugin-replace@2.4.2': resolution: {integrity: sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==} peerDependencies: - rollup: ^1.20.0 || ^2.0.0 + rollup: '>=4.59.0' '@rollup/plugin-terser@0.4.4': resolution: {integrity: sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==} engines: {node: '>=14.0.0'} peerDependencies: - rollup: ^2.0.0||^3.0.0||^4.0.0 + rollup: '>=4.59.0' peerDependenciesMeta: rollup: optional: true @@ -2354,7 +2362,7 @@ packages: resolution: {integrity: sha512-10monEYsBp3scM4/ND4LNH5Rxvh3e/cVeL3jWTgZ2SrQ+BmUoQcopVQvnaMcOnykb1VkxUFuDAN+0FnpTFRy2A==} engines: {node: '>=14.0.0'} peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + rollup: '>=4.59.0' peerDependenciesMeta: rollup: optional: true @@ -2363,7 +2371,7 @@ packages: resolution: {integrity: sha512-gpC4R1G9Ni92ZIRTexqbhX7U+9estZrbhP+9SRb0DW9xpB9g7j34r+J2hqrcW/lRI7dJaU84MxZM0Rt82tqYPQ==} engines: {node: '>=14.0.0'} peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + rollup: '>=4.59.0' peerDependenciesMeta: rollup: optional: true @@ -2372,13 +2380,13 @@ packages: resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==} engines: {node: '>= 8.0.0'} peerDependencies: - rollup: ^1.20.0||^2.0.0 + rollup: '>=4.59.0' '@rollup/pluginutils@5.4.0': resolution: {integrity: sha512-MfPp06CjRLfXQ3wY0R8vJDYBy/MvVcc9OulEfR0B8Iv9ko+GCNaRZ+EpJYFl27LhKsZK0o420sYCRHCjfCgeUg==} engines: {node: '>=14.0.0'} peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + rollup: '>=4.59.0' peerDependenciesMeta: rollup: optional: true @@ -2621,7 +2629,7 @@ packages: resolution: {integrity: sha512-hgPGPYdQJ/G1cGYOxAb7d4z3V+/k/E5/P/5TFPEEBLuIbFFk+JG0CISUDJdzXJjO382Lb99PBJuXGbueBmO79w==} engines: {node: '>= 18'} peerDependencies: - rollup: '>=3.2.0' + rollup: '>=4.59.0' peerDependenciesMeta: rollup: optional: true @@ -3214,9 +3222,6 @@ packages: badwords-list@2.0.1-4: resolution: {integrity: sha512-FxfZUp7B9yCnesNtFQS9v6PvZdxTYa14Q60JR6vhjdQdWI4naTjJIyx22JzoER8ooeT8SAAKoHLjKfCV7XgYUQ==} - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - balanced-match@4.0.4: resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} engines: {node: 18 || 20 || >=22} @@ -3248,9 +3253,6 @@ packages: blurhash@2.0.5: resolution: {integrity: sha512-cRygWd7kGBQO3VEhPiTgq4Wc43ctsM+o46urrmPOiuAe+07fzlSB9OJVdpgDL0jPqXUVQ9ht7aq7kxOeJHRK+w==} - brace-expansion@2.1.1: - resolution: {integrity: sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==} - brace-expansion@5.0.6: resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==} engines: {node: 18 || 20 || >=22} @@ -4291,10 +4293,6 @@ packages: resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} engines: {node: 18 || 20 || >=22} - minimatch@5.1.9: - resolution: {integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==} - engines: {node: '>=10'} - minipass@7.1.3: resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} engines: {node: '>=16 || 14 >=14.17'} @@ -4514,9 +4512,6 @@ packages: raf-schd@4.0.3: resolution: {integrity: sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==} - randombytes@2.1.0: - resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} - react-aria@3.50.0: resolution: {integrity: sha512-S0Os6QZk33fzUAKu1QLT9afoUaCBt1ZNdoiq0n2YMVgKIdNIQS8zxiZ8O9hYE6QyDkHKjD6q39LQZ+qaSAIgjw==} peerDependencies: @@ -4672,11 +4667,6 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} hasBin: true - rollup@2.80.0: - resolution: {integrity: sha512-cIFJOD1DESzpjOBl763Kp1AH7UE/0fcdHe6rZXUdQ9c50uvgigvW97u3IcSeBwOkgqL/PXPBktBCh0KEu5L8XQ==} - engines: {node: '>=10.0.0'} - hasBin: true - rollup@4.62.0: resolution: {integrity: sha512-nc72Wgq62I7rtDV4izT5/aaS0zxy3kttkinf9586ApknY3jZO9NYsmtc24fUckA0X7Q2v+ML4a15pdUlV5V/jA==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -4686,9 +4676,6 @@ packages: resolution: {integrity: sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==} engines: {node: '>=0.4'} - safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - safe-push-apply@1.0.0: resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} engines: {node: '>= 0.4'} @@ -4720,8 +4707,9 @@ packages: engines: {node: '>=10'} hasBin: true - serialize-javascript@6.0.2: - resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + serialize-javascript@7.0.7: + resolution: {integrity: sha512-YAy8Od6KV+uuwUuU50np8fGB/Aues6Y0nAhA9y/hId74PlKUcme4pXcBD46NWKr1Q4osN/iseZ17YqO1XfmI8g==} + engines: {node: '>=20.0.0'} set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} @@ -5171,7 +5159,7 @@ packages: peerDependencies: '@types/node': ^20.19.0 || >=22.12.0 '@vitejs/devtools': ^0.1.18 - esbuild: ^0.27.0 || ^0.28.0 + esbuild: '>=0.25.0' jiti: '>=1.21.0' less: ^4.0.0 sass: ^1.70.0 @@ -7004,73 +6992,73 @@ snapshots: '@rolldown/pluginutils@1.0.1': {} - '@rollup/plugin-babel@5.3.1(@babel/core@7.29.7)(@types/babel__core@7.20.5)(rollup@2.80.0)': + '@rollup/plugin-babel@5.3.1(@babel/core@7.29.7)(@types/babel__core@7.20.5)(rollup@4.62.0)': dependencies: '@babel/core': 7.29.7 '@babel/helper-module-imports': 7.29.7 - '@rollup/pluginutils': 3.1.0(rollup@2.80.0) - rollup: 2.80.0 + '@rollup/pluginutils': 3.1.0(rollup@4.62.0) + rollup: 4.62.0 optionalDependencies: '@types/babel__core': 7.20.5 transitivePeerDependencies: - supports-color - '@rollup/plugin-inject@5.0.5(rollup@2.80.0)': + '@rollup/plugin-inject@5.0.5(rollup@4.62.0)': dependencies: - '@rollup/pluginutils': 5.4.0(rollup@2.80.0) + '@rollup/pluginutils': 5.4.0(rollup@4.62.0) estree-walker: 2.0.2 magic-string: 0.30.21 optionalDependencies: - rollup: 2.80.0 + rollup: 4.62.0 - '@rollup/plugin-node-resolve@15.3.1(rollup@2.80.0)': + '@rollup/plugin-node-resolve@15.3.1(rollup@4.62.0)': dependencies: - '@rollup/pluginutils': 5.4.0(rollup@2.80.0) + '@rollup/pluginutils': 5.4.0(rollup@4.62.0) '@types/resolve': 1.20.2 deepmerge: 4.3.1 is-module: 1.0.0 resolve: 1.22.12 optionalDependencies: - rollup: 2.80.0 + rollup: 4.62.0 - '@rollup/plugin-replace@2.4.2(rollup@2.80.0)': + '@rollup/plugin-replace@2.4.2(rollup@4.62.0)': dependencies: - '@rollup/pluginutils': 3.1.0(rollup@2.80.0) + '@rollup/pluginutils': 3.1.0(rollup@4.62.0) magic-string: 0.25.9 - rollup: 2.80.0 + rollup: 4.62.0 - '@rollup/plugin-terser@0.4.4(rollup@2.80.0)': + '@rollup/plugin-terser@0.4.4(rollup@4.62.0)': dependencies: - serialize-javascript: 6.0.2 + serialize-javascript: 7.0.7 smob: 1.6.2 terser: 5.48.0 optionalDependencies: - rollup: 2.80.0 + rollup: 4.62.0 - '@rollup/plugin-virtual@3.0.2(rollup@2.80.0)': + '@rollup/plugin-virtual@3.0.2(rollup@4.62.0)': optionalDependencies: - rollup: 2.80.0 + rollup: 4.62.0 - '@rollup/plugin-wasm@6.2.2(rollup@2.80.0)': + '@rollup/plugin-wasm@6.2.2(rollup@4.62.0)': dependencies: - '@rollup/pluginutils': 5.4.0(rollup@2.80.0) + '@rollup/pluginutils': 5.4.0(rollup@4.62.0) optionalDependencies: - rollup: 2.80.0 + rollup: 4.62.0 - '@rollup/pluginutils@3.1.0(rollup@2.80.0)': + '@rollup/pluginutils@3.1.0(rollup@4.62.0)': dependencies: '@types/estree': 0.0.39 estree-walker: 1.0.1 picomatch: 2.3.2 - rollup: 2.80.0 + rollup: 4.62.0 - '@rollup/pluginutils@5.4.0(rollup@2.80.0)': + '@rollup/pluginutils@5.4.0(rollup@4.62.0)': dependencies: '@types/estree': 1.0.9 estree-walker: 2.0.2 picomatch: 4.0.4 optionalDependencies: - rollup: 2.80.0 + rollup: 4.62.0 '@rollup/rollup-android-arm-eabi@4.62.0': optional: true @@ -7244,20 +7232,20 @@ snapshots: '@sentry/browser-utils': 10.63.0 '@sentry/core': 10.63.0 - '@sentry/rollup-plugin@5.3.0(rollup@2.80.0)': + '@sentry/rollup-plugin@5.3.0(rollup@4.62.0)': dependencies: '@sentry/bundler-plugin-core': 5.3.0 magic-string: 0.30.21 optionalDependencies: - rollup: 2.80.0 + rollup: 4.62.0 transitivePeerDependencies: - encoding - supports-color - '@sentry/vite-plugin@5.3.0(rollup@2.80.0)': + '@sentry/vite-plugin@5.3.0(rollup@4.62.0)': dependencies: '@sentry/bundler-plugin-core': 5.3.0 - '@sentry/rollup-plugin': 5.3.0(rollup@2.80.0) + '@sentry/rollup-plugin': 5.3.0(rollup@4.62.0) transitivePeerDependencies: - encoding - rollup @@ -7900,8 +7888,6 @@ snapshots: badwords-list@2.0.1-4: {} - balanced-match@1.0.2: {} - balanced-match@4.0.4: {} base-x@5.0.1: {} @@ -7922,10 +7908,6 @@ snapshots: blurhash@2.0.5: {} - brace-expansion@2.1.1: - dependencies: - balanced-match: 1.0.2 - brace-expansion@5.0.6: dependencies: balanced-match: 4.0.4 @@ -8368,7 +8350,7 @@ snapshots: filelist@1.0.6: dependencies: - minimatch: 5.1.9 + minimatch: 10.2.5 fill-range@7.1.1: dependencies: @@ -9021,10 +9003,6 @@ snapshots: dependencies: brace-expansion: 5.0.6 - minimatch@5.1.9: - dependencies: - brace-expansion: 2.1.1 - minipass@7.1.3: {} mlly@1.8.2: @@ -9283,10 +9261,6 @@ snapshots: raf-schd@4.0.3: {} - randombytes@2.1.0: - dependencies: - safe-buffer: 5.2.1 - react-aria@3.50.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@internationalized/date': 3.12.2 @@ -9472,10 +9446,6 @@ snapshots: '@rolldown/binding-win32-arm64-msvc': 1.0.3 '@rolldown/binding-win32-x64-msvc': 1.0.3 - rollup@2.80.0: - optionalDependencies: - fsevents: 2.3.3 - rollup@4.62.0: dependencies: '@types/estree': 1.0.9 @@ -9515,8 +9485,6 @@ snapshots: has-symbols: 1.1.0 isarray: 2.0.5 - safe-buffer@5.2.1: {} - safe-push-apply@1.0.0: dependencies: es-errors: 1.3.0 @@ -9546,9 +9514,7 @@ snapshots: semver@7.8.4: {} - serialize-javascript@6.0.2: - dependencies: - randombytes: 2.1.0 + serialize-javascript@7.0.7: {} set-function-length@1.2.2: dependencies: @@ -9976,9 +9942,9 @@ snapshots: - tsx - yaml - vite-plugin-compression2@2.5.3(rollup@2.80.0): + vite-plugin-compression2@2.5.3(rollup@4.62.0): dependencies: - '@rollup/pluginutils': 5.4.0(rollup@2.80.0) + '@rollup/pluginutils': 5.4.0(rollup@4.62.0) tar-mini: 0.2.0 transitivePeerDependencies: - rollup @@ -10002,9 +9968,9 @@ snapshots: tinyglobby: 0.2.17 vite: 7.3.5(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.48.0)(yaml@2.9.0) - vite-plugin-svgr@4.5.0(rollup@2.80.0)(typescript@5.9.3)(vite@7.3.5(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.48.0)(yaml@2.9.0)): + vite-plugin-svgr@4.5.0(rollup@4.62.0)(typescript@5.9.3)(vite@7.3.5(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.48.0)(yaml@2.9.0)): dependencies: - '@rollup/pluginutils': 5.4.0(rollup@2.80.0) + '@rollup/pluginutils': 5.4.0(rollup@4.62.0) '@svgr/core': 8.1.0(typescript@5.9.3) '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.9.3)) vite: 7.3.5(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.48.0)(yaml@2.9.0) @@ -10013,9 +9979,9 @@ snapshots: - supports-color - typescript - vite-plugin-top-level-await@1.6.0(@swc/helpers@0.5.23)(rollup@2.80.0)(vite@7.3.5(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.48.0)(yaml@2.9.0)): + vite-plugin-top-level-await@1.6.0(@swc/helpers@0.5.23)(rollup@4.62.0)(vite@7.3.5(@types/node@24.13.2)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.48.0)(yaml@2.9.0)): dependencies: - '@rollup/plugin-virtual': 3.0.2(rollup@2.80.0) + '@rollup/plugin-virtual': 3.0.2(rollup@4.62.0) '@swc/core': 1.15.41(@swc/helpers@0.5.23) '@swc/wasm': 1.15.41 uuid: 10.0.0 @@ -10185,10 +10151,10 @@ snapshots: '@babel/core': 7.29.7 '@babel/preset-env': 7.29.7(@babel/core@7.29.7) '@babel/runtime': 7.29.7 - '@rollup/plugin-babel': 5.3.1(@babel/core@7.29.7)(@types/babel__core@7.20.5)(rollup@2.80.0) - '@rollup/plugin-node-resolve': 15.3.1(rollup@2.80.0) - '@rollup/plugin-replace': 2.4.2(rollup@2.80.0) - '@rollup/plugin-terser': 0.4.4(rollup@2.80.0) + '@rollup/plugin-babel': 5.3.1(@babel/core@7.29.7)(@types/babel__core@7.20.5)(rollup@4.62.0) + '@rollup/plugin-node-resolve': 15.3.1(rollup@4.62.0) + '@rollup/plugin-replace': 2.4.2(rollup@4.62.0) + '@rollup/plugin-terser': 0.4.4(rollup@4.62.0) '@surma/rollup-plugin-off-main-thread': 2.2.3 ajv: 8.20.0 common-tags: 1.8.2 @@ -10197,7 +10163,7 @@ snapshots: glob: 11.1.0 lodash: 4.18.1 pretty-bytes: 5.6.0 - rollup: 2.80.0 + rollup: 4.62.0 source-map: 0.8.0-beta.0 stringify-object: 3.3.0 strip-comments: 2.0.1 From 33aec3babe061aedc52683c0514a0089a48e9e9d Mon Sep 17 00:00:00 2001 From: hazre Date: Wed, 22 Jul 2026 07:47:07 +0200 Subject: [PATCH 11/11] style: fix formatting Signed-off-by: hazre --- .github/dependabot.yml | 2 +- mise.toml | 2 +- package.json | 5 ++++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 497e619ee..60224d4ef 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -68,4 +68,4 @@ updates: groups: docker: patterns: - - '*' \ No newline at end of file + - '*' diff --git a/mise.toml b/mise.toml index 3d7fafb9d..9112674a1 100644 --- a/mise.toml +++ b/mise.toml @@ -90,4 +90,4 @@ tools = { "pinact" = "latest" } run = "tofu" raw_args = true hide = true -tools = { "opentofu" = "1.11.5" } \ No newline at end of file +tools = { "opentofu" = "1.11.5" } diff --git a/package.json b/package.json index c408c464b..181d6124a 100644 --- a/package.json +++ b/package.json @@ -151,7 +151,10 @@ "wrangler": "^4.106.0" }, "devEngines": { - "runtime": { "name": "node", "version": "24.x" } + "runtime": { + "name": "node", + "version": "24.x" + } }, "packageManager": "pnpm@10.32.1+sha512.a706938f0e89ac1456b6563eab4edf1d1faf3368d1191fc5c59790e96dc918e4456ab2e67d613de1043d2e8c81f87303e6b40d4ffeca9df15ef1ad567348f2be" }