mirror of
https://github.com/YuzuZensai/Termix.git
synced 2026-09-13 10:49:03 +00:00
Merge upstream/main (v2.7.0) into fork
This commit is contained in:
@@ -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 }}
|
||||
|
||||
@@ -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 }}"
|
||||
@@ -43,6 +43,7 @@ on:
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user