mirror of
https://github.com/zkldi/Tachi.git
synced 2026-09-26 17:07:58 +03:00
* fix: resize profile images on upload and add cache headers Profile pictures were stored at original upload size (up to 1 MB) but only ever displayed at 32–128 px, so every page load downloaded the full original image. Additionally, no Cache-Control headers were set anywhere in the pipeline, forcing a fresh round-trip through the API redirect and CDN on every page view. - Resize JPEG/PNG pfps to max 256×256 and banners to max 1920×1080 via sharp before storing; re-encode to WebP at 85% quality (GIFs skipped to preserve the animated-GIF easter egg) - Hash the resized buffer so the CDN path reflects what's on disk - Set ContentType and CacheControl: immutable on S3 PutObject so CDN edges and browsers cache the objects indefinitely (safe because paths are content-addressed via SHA-256) - Add Cache-Control: public, max-age=3600, stale-while-revalidate=86400 to the GET /pfp and GET /banner redirect responses so browsers cache the userId→CDN-URL mapping and skip the API hop on repeat visits Fixes #1553 * chore: apply biome formatting * chore: generate ImportTimestop kanel type * feat: add backfill-media script to migrate existing profile images One-off script that reads every user's existing pfp and banner from S3, runs them through the same sharp resize/WebP pipeline as new uploads, stores the result under the new content-addressed key with immutable cache headers, and updates custom_pfp_location/custom_banner_location in the DB. Features: - --dry-run flag to preview changes without writing anything - Skips objects already at optimal size (idempotent) - Gracefully handles missing S3 objects (logs + skips) - Summary stats at the end - Reads S3 config from CLI args or TACHI_CDN_SAVE_LOCATION_* env vars * chore: apply biome formatting to backfill-media * fix: resize animated GIFs to animated WebP via sharp animated:true * test: rewrite change-pfp/banner tests as real S3 + sharp integration Remove the CDN mock entirely. Tests now pass real image buffers through sharp and verify the stored S3 object via CDNRetrieve: - PNG/JPEG input → assert stored object is WebP, dimensions ≤256×256, smaller than the original - GIF input → assert stored object is WebP - Hash returned from the action == SHA256 of the stored WebP bytes (not the original upload) - Delete tests upload a real pfp then delete it and verify CDNRetrieve throws afterwards Also move change-pfp.test.ts from the isolated vitest project back to the default pool now that it no longer uses vi.mock. * chore: apply biome formatting to test file * fix: use POSTGRES_TEST_HOST env var in bot vitest setup Both vitest.globalSetup.ts and vitest.setup.ts hardcoded 'tachi-postgres' (the dev server), but just bot-db-test-template-reset creates the template on 'tachi-postgres-test' (the tmpfs test server). Workers then failed to clone the template because they were looking on the wrong host. Mirrors the pattern already used in the server package: process.env.POSTGRES_TEST_HOST ?? 'tachi-postgres-test' * fix: update pfp router tests for WebP resize pipeline The PUT tests were comparing the stored S3 bytes directly to the original upload buffer. Since we now resize and re-encode to WebP, this always fails. Also, following the mockApi redirect to fetch the bytes added a slow supertest round-trip. Replace with: read custom_pfp_location from the DB after PUT, fetch the stored object directly via CDNRetrieve, and assert it is smaller than the original (non-deterministic WebP compression makes exact byte comparison inappropriate). * fix: update banner router tests for WebP resize pipeline * fix: tests * fix: ci
121 lines
3.4 KiB
Plaintext
121 lines
3.4 KiB
Plaintext
check:
|
|
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
source .scripts/multi_evaluator.sh
|
|
|
|
evaluate "just fmt-check"
|
|
evaluate "bun run --filter '*' lint -- --quiet"
|
|
evaluate "just typecheck"
|
|
evaluate "bun .scripts/ts_machete.js"
|
|
evaluate "bun .scripts/ts_autoinherit.js --check"
|
|
|
|
post_evaluate
|
|
|
|
typecheck:
|
|
bun run --elide-lines=0 --filter '!tachi-seeds-scripts' typecheck
|
|
|
|
typecheck-sequential:
|
|
bun run --elide-lines=0 --filter '!tachi-seeds-scripts' typecheck
|
|
|
|
fix:
|
|
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
just gen
|
|
bun run --elide-lines=0 --filter '*' lint-fix -- --quiet
|
|
.scripts/ts_autoinherit.js
|
|
just fmt
|
|
|
|
# Automatically fix any issues we can in the codebase and then
|
|
# make a commit for them
|
|
autofix:
|
|
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
# Only generate a commit if the repo is clean
|
|
SHOULD_COMMIT=0
|
|
if [ -z "$(git status --porcelain)" ]; then
|
|
SHOULD_COMMIT=1
|
|
fi
|
|
|
|
just fix
|
|
|
|
if [ $SHOULD_COMMIT -eq 1 ]; then
|
|
git add .
|
|
git commit -m "chore: autofix"
|
|
fi
|
|
|
|
fmt:
|
|
bun biome format --write
|
|
bun prettier --write --list-different .
|
|
|
|
fmt-check:
|
|
bun biome format
|
|
bun prettier --check .
|
|
|
|
test FILTER="*":
|
|
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
source .scripts/multi_evaluator.sh
|
|
|
|
evaluate "just test-typescript '{{FILTER}}'"
|
|
|
|
post_evaluate
|
|
|
|
test-typescript FILTER="*":
|
|
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
export POSTGRES_TEST_HOST="tachi-postgres-test"
|
|
export POSTGRES_TEST_URL="postgresql://tachi:tachi@${POSTGRES_TEST_HOST}"
|
|
bun run --elide-lines=0 --sequential --filter '{{FILTER}}' test -- --reporter=default --reporter=junit --outputFile.junit=test-results/junit.xml
|
|
|
|
# Summarize Vitest v8 coverage across workspaces (see typescript/coverage-tools).
|
|
coverage-report *ARGS:
|
|
bun run --filter tachi-coverage-tools report -- {{ARGS}}
|
|
|
|
|
|
# Run all parity suites, or a single one if a name is given.
|
|
test-parity suite="":
|
|
TACHI_SERVER=https://localhost:8080 bun vitest run {{ if suite != "" { "tests/" + suite + ".test.ts" } else { "" } }}
|
|
|
|
# ==> Orchestration of parallel db tests
|
|
|
|
# Create (or recreate) the bot test template database with all migrations applied.
|
|
# Workers clone from this template rather than re-running migrations each time.
|
|
# Targets the dedicated tmpfs `tachi-postgres-test` server (override via
|
|
# POSTGRES_TEST_URL).
|
|
bot-db-test-template-reset:
|
|
#!/bin/bash
|
|
set -euo pipefail
|
|
export POSTGRES_URL="{{POSTGRES_TEST_URL}}/tachi_bot_test_template"
|
|
tachidb database drop
|
|
tachidb database create
|
|
tachidb migrate run
|
|
|
|
# Create (or recreate) the server test template database with all migrations applied.
|
|
# Workers clone from this template rather than re-running migrations each time.
|
|
# Targets the dedicated tmpfs `tachi-postgres-test` server (override via
|
|
# POSTGRES_TEST_URL).
|
|
server-db-test-template-reset:
|
|
#!/bin/bash
|
|
set -euo pipefail
|
|
export POSTGRES_URL="{{POSTGRES_TEST_URL}}/tachi_server_test_template"
|
|
tachidb database drop
|
|
tachidb database create
|
|
tachidb migrate run
|
|
|
|
# <== End of parallel db test justscripts
|
|
|
|
# Score-import HTTP load tests against a live server (multipart /api/v1/import/file).
|
|
# See typescript/server/src/load-tests/README.md
|
|
load-test-score-import *ARGS:
|
|
cd typescript/server && bun run load-test:score-import -- {{ARGS}}
|
|
|
|
# Seed N dev users + API tokens (submit_score); writes one token per line to OUTPUT_FILE.
|
|
# Uses the server package env (.env); same Postgres as a local tachi-server.
|
|
load-test-score-import-seed-tokens COUNT OUTPUT_FILE:
|
|
cd typescript/server && bun run src/load-tests/seed-stress-api-tokens.ts {{COUNT}} {{OUTPUT_FILE}}
|