Merge upstream/main (v2.7.0) into fork

This commit is contained in:
2026-08-22 17:09:49 +07:00
1057 changed files with 479543 additions and 50189 deletions
+8
View File
@@ -37,6 +37,14 @@ updates:
major-updates:
update-types:
- "major"
ignore:
# typescript-eslint declares `typescript: >=4.8.4 <6.1.0`, and TypeScript 7
# removed `ts.Extension`, which @typescript-eslint/typescript-estree reads
# at import time. Bumping to 7 makes `eslint .` fail to load its own config,
# so `npm run lint` cannot run at all. Drop this once typescript-eslint
# supports TypeScript 7.
- dependency-name: "typescript"
update-types: ["version-update:semver-major"]
# Docker base images (docker/Dockerfile + docker-compose / compose-dev)
- package-ecosystem: "docker"
+5 -8
View File
@@ -28,7 +28,7 @@ jobs:
fetch-depth: 1
- name: Setup Node.js
uses: actions/setup-node@v6
uses: actions/setup-node@v7
with:
node-version-file: ".nvmrc"
@@ -67,7 +67,7 @@ jobs:
fetch-depth: 1
- name: Setup Node.js
uses: actions/setup-node@v6
uses: actions/setup-node@v7
with:
node-version-file: ".nvmrc"
cache: "npm"
@@ -78,11 +78,8 @@ jobs:
- name: Run ESLint
run: npx eslint .
- name: Run Prettier check
run: npx prettier --check .
- name: Type check
run: npx tsc --noEmit
run: npm run type-check
- name: Run unit tests
run: npm run test
@@ -121,7 +118,7 @@ jobs:
CHANGES=$(git log --oneline --no-merges "${{ steps.prev.outputs.sha }}..${{ needs.prep.outputs.sha }}" -- . ':!package-lock.json' | sed 's/^/- /')
fi
if [ -z "$CHANGES" ]; then
CHANGES="- No new commits since the last beta (or this is the first beta build)."
CHANGES="- No new commits since the last beta."
fi
cat > BETA_RELEASE_BODY.md << EOF
@@ -157,7 +154,7 @@ jobs:
docker:
needs: [prep, verify, create-release]
if: ${{ always() && needs.prep.outputs.dev_branch != '' && (needs.create-release.result == 'success' || needs.create-release.result == 'skipped') }}
if: ${{ always() && needs.prep.outputs.dev_branch != '' && needs.verify.result == 'success' && (needs.create-release.result == 'success' || needs.create-release.result == 'skipped') }}
uses: ./.github/workflows/docker.yml
with:
version: ${{ needs.prep.outputs.beta_version }}
+83
View File
@@ -0,0 +1,83 @@
name: Crowdin Sync
on:
schedule:
- cron: "0 6 * * *"
workflow_dispatch:
inputs:
branch:
description: "Branch to sync translations into"
required: false
type: string
permissions:
contents: write
jobs:
crowdin:
runs-on: blacksmith-2vcpu-ubuntu-2404
steps:
- name: Resolve target branch
id: branch
run: |
BRANCH="${{ inputs.branch }}"
if [ -z "$BRANCH" ]; then
BRANCH="${{ github.event.repository.default_branch }}"
fi
echo "name=$BRANCH" >> "$GITHUB_OUTPUT"
- name: Checkout branch
uses: actions/checkout@v7
with:
ref: ${{ steps.branch.outputs.name }}
fetch-depth: 0
token: ${{ secrets.GHCR_TOKEN }}
- name: Setup Node.js
uses: actions/setup-node@v7
with:
node-version-file: ".nvmrc"
- name: Upload sources to Crowdin
uses: crowdin/github-action@v2
with:
upload_sources: true
upload_translations: false
download_translations: false
create_pull_request: false
push_translations: false
token: ${{ secrets.CROWDIN_API_KEY }}
project_id: "858252"
env:
CROWDIN_API_TOKEN: ${{ secrets.CROWDIN_API_KEY }}
- name: Machine pre-translate untranslated strings
env:
CROWDIN_API_KEY: ${{ secrets.CROWDIN_API_KEY }}
run: node scripts/crowdin-pretranslate.cjs
- name: Download translations from Crowdin
uses: crowdin/github-action@v2
with:
upload_sources: false
upload_translations: false
download_translations: true
create_pull_request: false
push_translations: false
token: ${{ secrets.CROWDIN_API_KEY }}
project_id: "858252"
env:
CROWDIN_API_TOKEN: ${{ secrets.CROWDIN_API_KEY }}
- name: Commit translations
run: |
git config user.name "LukeGus"
git config user.email "bugattiguy527@gmail.com"
git add src/ui/locales/translated
if git diff --cached --quiet; then
echo "No translation changes to commit."
exit 0
fi
git commit -m "chore: sync Crowdin translations"
git push origin HEAD:"${{ steps.branch.outputs.name }}"
+1
View File
@@ -43,6 +43,7 @@ on:
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 20
permissions:
contents: read
packages: write
+73 -10
View File
@@ -72,11 +72,48 @@ jobs:
fetch-depth: 1
- name: Setup Node.js
uses: actions/setup-node@v6
uses: actions/setup-node@v7
with:
node-version-file: ".nvmrc"
cache: "npm"
- name: Install Spectre-mitigated MSVC libraries
shell: pwsh
run: |
# node-pty's binding.gyp sets SpectreMitigation, so MSBuild refuses to
# build without these. They are not on the runner image by default.
$vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
$installPath = & $vswhere -latest -products * -property installationPath
if (-not $installPath) { throw "Visual Studio installation not found" }
# Derive the toolset version from the installed MSVC so the component
# id keeps matching when the runner image bumps the compiler.
$toolsetDir = Get-ChildItem -Path "$installPath\VC\Tools\MSVC" -Directory |
Sort-Object Name -Descending | Select-Object -First 1
if (-not $toolsetDir) { throw "No MSVC toolset found under $installPath" }
$parts = $toolsetDir.Name.Split(".")
$shortVer = "$($parts[0]).$($parts[1].Substring(0,2))"
Write-Host "MSVC toolset $($toolsetDir.Name) -> component version $shortVer"
$installer = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vs_installer.exe"
$components = @(
"Microsoft.VisualStudio.Component.VC.$shortVer.17.14.x86.x64.Spectre",
"Microsoft.VisualStudio.Component.VC.Runtimes.x86.x64.Spectre"
)
$args = @("modify", "--installPath", "`"$installPath`"", "--quiet", "--norestart", "--nocache")
foreach ($c in $components) { $args += @("--add", $c) }
Write-Host "Installing: $($components -join ', ')"
$proc = Start-Process -FilePath $installer -ArgumentList $args -Wait -PassThru -NoNewWindow
if ($proc.ExitCode -ne 0 -and $proc.ExitCode -ne 3010) {
Write-Host "vs_installer exited with $($proc.ExitCode); verifying libraries anyway"
}
$found = Get-ChildItem -Path "$installPath\VC\Tools\MSVC" -Recurse -Filter "*.lib" -ErrorAction SilentlyContinue |
Where-Object { $_.FullName -match "\\spectre\\" } | Select-Object -First 1
if (-not $found) { throw "Spectre-mitigated libraries still missing after install" }
Write-Host "Spectre libs present: $($found.FullName)"
- name: Install dependencies
run: npm ci
@@ -166,7 +203,7 @@ jobs:
fetch-depth: 1
- name: Setup Node.js
uses: actions/setup-node@v6
uses: actions/setup-node@v7
with:
node-version-file: ".nvmrc"
cache: "npm"
@@ -380,7 +417,7 @@ jobs:
fetch-depth: 1
- name: Setup Node.js
uses: actions/setup-node@v6
uses: actions/setup-node@v7
with:
node-version-file: ".nvmrc"
cache: "npm"
@@ -559,7 +596,7 @@ jobs:
CHECKSUM=$(shasum -a 256 "$DMG_PATH" | awk '{print $1}')
mkdir -p homebrew-generated
cp packaging/Casks/termix.rb homebrew-generated/termix.rb
cp Casks/termix.rb homebrew-generated/termix.rb
sed -i '' "s/VERSION_PLACEHOLDER/$VERSION/g" homebrew-generated/termix.rb
sed -i '' "s/CHECKSUM_PLACEHOLDER/$CHECKSUM/g" homebrew-generated/termix.rb
@@ -894,7 +931,7 @@ jobs:
mkdir -p homebrew-submission/Casks/t
cp packaging/Casks/termix.rb homebrew-submission/Casks/t/termix.rb
cp Casks/termix.rb homebrew-submission/Casks/t/termix.rb
sed -i '' "s/VERSION_PLACEHOLDER/$VERSION/g" homebrew-submission/Casks/t/termix.rb
sed -i '' "s/CHECKSUM_PLACEHOLDER/$CHECKSUM/g" homebrew-submission/Casks/t/termix.rb
@@ -966,7 +1003,7 @@ jobs:
fetch-depth: 1
- name: Setup Node.js
uses: actions/setup-node@v6
uses: actions/setup-node@v7
with:
node-version-file: ".nvmrc"
cache: "npm"
@@ -1075,13 +1112,21 @@ jobs:
default_platform(:mac)
lane :fetch_build_number do
number = app_store_build_number(
live: false,
live_number = app_store_build_number(
live: true,
platform: "osx",
api_key_path: "/tmp/asc_keys/api_key.json",
app_identifier: "com.karmaa.termix",
version: "$APP_VERSION",
initial_build_number: 0,
)
pending_number = app_store_build_number(
live: false,
platform: "osx",
api_key_path: "/tmp/asc_keys/api_key.json",
app_identifier: "com.karmaa.termix",
initial_build_number: 0,
)
number = [live_number, pending_number].max
File.write("$OUT_FILE", number.to_s)
end
EOF
@@ -1109,6 +1154,18 @@ jobs:
BUILD_VERSION="${{ steps.build_number.outputs.build_version || github.run_number }}"
npm run build && npx electron-builder --mac mas --universal --config.buildVersion="$BUILD_VERSION"
- name: Generate App Store release notes
id: asc_notes
if: steps.check_certs.outputs.has_certs == 'true' && steps.check_asc_creds.outputs.has_credentials == 'true'
run: |
META_DIR="$RUNNER_TEMP/asc_metadata"
rm -rf "$META_DIR"
node scripts/generate-appstore-notes.cjs \
--notes RELEASE_NOTES.md \
--out-dir "$META_DIR" \
--locales "en-US"
echo "metadata_path=$META_DIR" >> "$GITHUB_OUTPUT"
- name: Upload and submit to Mac App Store
if: steps.check_certs.outputs.has_certs == 'true' && steps.check_asc_creds.outputs.has_credentials == 'true'
run: |
@@ -1125,10 +1182,16 @@ jobs:
--pkg "$PKG_FILE" \
--api_key_path "$API_KEY_JSON" \
--app_version "$VERSION" \
--skip_metadata true \
--platform osx \
--app_identifier "com.karmaa.termix" \
--skip_metadata false \
--metadata_path "${{ steps.asc_notes.outputs.metadata_path }}" \
--skip_screenshots true \
--skip_app_version_update false \
--submit_for_review true \
--automatic_release true \
--precheck_include_in_app_purchases false \
--submission_information "{\"export_compliance_uses_encryption\": false}" \
--force true
- name: Clean up keychains
+1 -1
View File
@@ -13,7 +13,7 @@ jobs:
uses: actions/checkout@v7
- name: Setup Node.js
uses: actions/setup-node@v6
uses: actions/setup-node@v7
with:
node-version-file: ".nvmrc"
cache: "npm"
+79 -4
View File
@@ -16,7 +16,7 @@ jobs:
uses: actions/checkout@v7
- name: Setup Node.js
uses: actions/setup-node@v6
uses: actions/setup-node@v7
with:
node-version-file: ".nvmrc"
cache: "npm"
@@ -24,14 +24,89 @@ jobs:
- name: Install dependencies
run: npm ci
- name: Run ESLint
run: npx eslint .
- name: Lint
# npm run lint, not npx eslint — the script also checks that the
# generated dialect schemas match schema.ts, which eslint cannot see.
run: npm run lint
- name: Run Prettier check
run: npx prettier --check .
- name: Type check
run: npx tsc --noEmit
run: npm run type-check
- name: Build
run: npm run build
database-dialects:
name: Postgres and MySQL
runs-on: blacksmith-2vcpu-ubuntu-2404
# The test suite only ever sees SQLite. Everything that differs per engine —
# the RETURNING replacements, the read-then-write transactions, the
# migrations themselves — is only covered here, against real servers.
services:
postgres:
image: postgres:16
env:
POSTGRES_USER: termix
POSTGRES_PASSWORD: termix
POSTGRES_DB: termix_test
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
mysql:
image: mysql:8
env:
MYSQL_ROOT_PASSWORD: termix
MYSQL_DATABASE: termix_test
MYSQL_USER: termix
MYSQL_PASSWORD: termix
ports:
- 3306:3306
options: >-
--health-cmd "mysqladmin ping -h 127.0.0.1 -ptermix"
--health-interval 10s
--health-timeout 5s
--health-retries 10
steps:
- name: Checkout code
uses: actions/checkout@v7
- name: Setup Node.js
uses: actions/setup-node@v7
with:
node-version-file: ".nvmrc"
cache: "npm"
- name: Install dependencies
run: npm ci
# Each run applies the migrations to an empty database first, so a
# migration that does not apply cleanly fails the build.
- name: Verify Postgres
run: npm run verify:dialect -- postgres://termix:termix@127.0.0.1:5432/termix_test
- name: Verify MySQL
run: npm run verify:dialect -- mysql://termix:termix@127.0.0.1:3306/termix_test
# The same repository suite the SQLite run executes, pointed at each
# engine. This is where a dialect difference in a query shows up as a
# failing assertion rather than as a bug report.
- name: Repository tests on Postgres
env:
TEST_DIALECT: postgres
TEST_DATABASE_URL: postgres://termix:termix@127.0.0.1:5432/termix_test
run: npx vitest run src/backend/tests/database/repositories --no-file-parallelism
- name: Repository tests on MySQL
env:
TEST_DIALECT: mysql
TEST_DATABASE_URL: mysql://termix:termix@127.0.0.1:3306/termix_test
run: npx vitest run src/backend/tests/database/repositories --no-file-parallelism
+21 -13
View File
@@ -44,7 +44,7 @@ jobs:
fetch-depth: 1
- name: Setup Node.js
uses: actions/setup-node@v6
uses: actions/setup-node@v7
with:
node-version-file: ".nvmrc"
@@ -92,7 +92,7 @@ jobs:
token: ${{ secrets.GHCR_TOKEN }}
- name: Setup Node.js
uses: actions/setup-node@v6
uses: actions/setup-node@v7
with:
node-version-file: ".nvmrc"
cache: "npm"
@@ -144,7 +144,7 @@ jobs:
token: ${{ secrets.GHCR_TOKEN }}
- name: Setup Node.js
uses: actions/setup-node@v6
uses: actions/setup-node@v7
with:
node-version-file: ".nvmrc"
@@ -225,7 +225,7 @@ jobs:
fetch-depth: 1
- name: Setup Node.js
uses: actions/setup-node@v6
uses: actions/setup-node@v7
with:
node-version-file: ".nvmrc"
@@ -304,7 +304,7 @@ jobs:
fetch-depth: 1
- name: Setup Node.js
uses: actions/setup-node@v6
uses: actions/setup-node@v7
with:
node-version-file: ".nvmrc"
@@ -395,10 +395,10 @@ jobs:
git fetch origin main
git checkout -B main origin/main
sed -i "s|version \".*\"|version \"$VERSION\"|g" packaging/Casks/termix.rb
sed -i "s|sha256 \".*\"|sha256 \"$DMG_SHA256\"|g" packaging/Casks/termix.rb
sed -i "s|version \".*\"|version \"$VERSION\"|g" Casks/termix.rb
sed -i "s|sha256 \".*\"|sha256 \"$DMG_SHA256\"|g" Casks/termix.rb
git add packaging/Casks/termix.rb
git add Casks/termix.rb
if git diff --cached --quiet; then
echo "Cask already up to date."
exit 0
@@ -420,7 +420,7 @@ jobs:
path: termix
- name: Setup Node.js
uses: actions/setup-node@v6
uses: actions/setup-node@v7
with:
node-version-file: "termix/.nvmrc"
cache: "npm"
@@ -443,13 +443,21 @@ jobs:
- name: Create docs release branch
working-directory: docs-repo
run: git checkout -B "dev-${{ needs.prep.outputs.version }}"
run: |
BRANCH="dev-${{ needs.prep.outputs.version }}"
if git ls-remote --exit-code origin "refs/heads/$BRANCH" >/dev/null 2>&1; then
echo "Reusing existing docs branch $BRANCH."
git checkout -B "$BRANCH" "origin/$BRANCH"
else
git checkout -B "$BRANCH"
fi
- name: Overwrite OpenAPI spec and regenerate API docs
working-directory: docs-repo
run: |
cp ../termix/openapi.json static/openapi.json
npm ci
npm run docusaurus clean-api-docs termix
npm run docusaurus gen-api-docs termix
- name: Commit and push docs branch
@@ -471,7 +479,7 @@ jobs:
git add -A
git commit -m "feat: update API docs for ${{ needs.prep.outputs.version }}"
git push --force origin "dev-${{ needs.prep.outputs.version }}"
git push origin "dev-${{ needs.prep.outputs.version }}"
- name: Open and squash-merge docs PR
if: ${{ inputs.mode != 'Dry run' }}
@@ -513,7 +521,7 @@ jobs:
fetch-depth: 1
- name: Setup Node.js
uses: actions/setup-node@v6
uses: actions/setup-node@v7
with:
node-version-file: ".nvmrc"
@@ -534,7 +542,7 @@ jobs:
docs,
publish-youtube,
]
if: ${{ always() && (inputs.mode == 'Everything' || inputs.mode == 'Skip submit') && needs.merge-to-main.result == 'success' && needs.electron-release.result == 'success' }}
if: ${{ always() && (inputs.mode == 'Everything' || inputs.mode == 'Skip submit') && needs.merge-to-main.result == 'success' && needs.docs.result == 'success' }}
runs-on: blacksmith-2vcpu-ubuntu-2404
steps:
- name: Checkout repository