Isolate CI database journey and stabilize E2E dependency cache
ci / module boundaries / boundaries (push) Successful in 7s
ci / db / db (push) Failing after 29s
ci / api / api (push) Successful in 52s
ci / ts / ts (packages + web) (push) Successful in 4m22s

This commit is contained in:
mrleo1nid committed 2026-10-30 11:05:13 +03:00
1 parent 82bf015283
commit bbd629dcf8
3 files changed
+45 -4

No files matched your search

+9
View File
@@ -4,6 +4,15 @@ import { defineConfig } from 'vite';
export default defineConfig({
plugins: [react()],
// Keep Vitest's dependency cache separate from the browser test server.
cacheDir: process.env.VITE_E2E === '1' ? 'node_modules/.vite-e2e' : undefined,
optimizeDeps: process.env.VITE_E2E === '1' ? {
// Lazy routes and workers must be scanned before browsers cache React chunks.
// Late discovery otherwise mixes cached and newly optimized React instances
// across full document navigations when HMR is disabled.
entries: ['index.html', 'src/**/*.{ts,tsx}', '!src/**/*.test.{ts,tsx}', '!src/**/*.d.ts', '!src/test/**'],
include: ['react', 'react-dom', 'react-dom/client', 'react/jsx-runtime', 'react/jsx-dev-runtime'],
} : undefined,
build: {
target: 'es2022',
},
+30
View File
@@ -26,6 +26,7 @@ import (
"time"
"github.com/google/uuid"
"github.com/jackc/pgx/v5"
"github.com/redis/go-redis/v9"
"github.com/stretchr/testify/require"
@@ -120,6 +121,7 @@ func TestUserJourney(t *testing.T) {
if dbURL == "" {
t.Skip("TEST_DATABASE_URL is not set")
}
dbURL = userJourneyDatabase(t, dbURL)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
@@ -133,6 +135,7 @@ func TestUserJourney(t *testing.T) {
t.Setenv("DATABASE_URL", dbURL)
t.Setenv("REDIS_URL", os.Getenv("TEST_REDIS_URL"))
t.Setenv("BOOTSTRAP_ADMIN_PASSWORD", "admin")
t.Setenv("BOOTSTRAP_ADMIN_USERNAME", "admin")
t.Setenv("MUSICBRAINZ_ENABLED", "false") // public provider availability is covered by explicit live tests
cfg, err := config.Load[config.API]()
require.NoError(t, err)
@@ -172,6 +175,7 @@ func TestUserJourney(t *testing.T) {
BootstrapRequired bool `json:"bootstrap_required"`
}
c.ok("GET", "/api/v1/server-info", nil, &info)
require.True(t, info.BootstrapRequired, "user journey requires a fresh database before the first admin login")
var tokens struct {
AccessToken string `json:"access_token"`
User struct {
@@ -376,3 +380,29 @@ func TestUserJourney(t *testing.T) {
})
fmt.Println("user journey ok")
}
// Other integration packages deliberately create users and catalog fixtures.
// The bootstrap journey needs a new database, without modifying those fixtures.
// TEST_DATABASE_URL must use a role with CREATEDB (the CI Postgres owner does).
func userJourneyDatabase(t *testing.T, address string) string {
t.Helper()
ctx := context.Background()
admin, err := db.Connect(ctx, address)
require.NoError(t, err)
t.Cleanup(admin.Close)
name := "pipu_journey_" + strings.ReplaceAll(uuid.NewString(), "-", "")
identifier := pgx.Identifier{name}.Sanitize()
_, err = admin.Exec(ctx, "CREATE DATABASE "+identifier)
require.NoError(t, err)
t.Cleanup(func() {
cleanup, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
_, err := admin.Exec(cleanup, "DROP DATABASE "+identifier+" WITH (FORCE)")
require.NoError(t, err)
})
dsn, err := url.Parse(address)
require.NoError(t, err)
require.Contains(t, []string{"postgres", "postgresql"}, dsn.Scheme)
dsn.Path = "/" + name
return dsn.String()
}
@@ -25,16 +25,18 @@ func TestUploadedArtistPortraitStagingLifetime(t *testing.T) {
ctx := context.Background()
pool, err := db.Connect(ctx, address)
require.NoError(t, err)
defer pool.Close()
t.Cleanup(pool.Close)
require.NoError(t, db.Migrate(ctx, pool))
store := NewStore(pool)
author := uuid.New()
_, err = pool.Exec(ctx, `INSERT INTO users(id,username,password_hash,role) VALUES($1,$2,'x','admin')`, author, "portrait-"+author.String())
require.NoError(t, err)
t.Cleanup(func() {
_, _ = pool.Exec(ctx, `DELETE FROM upload_batches WHERE author_id=$1`, author)
_, _ = pool.Exec(ctx, `DELETE FROM users WHERE id=$1`, author)
_ = store.ReconcileQuota(ctx)
_, err := pool.Exec(ctx, `DELETE FROM upload_batches WHERE author_id=$1`, author)
require.NoError(t, err)
_, err = pool.Exec(ctx, `DELETE FROM users WHERE id=$1`, author)
require.NoError(t, err)
require.NoError(t, store.ReconcileQuota(ctx))
})
svc := NewService(store, nil, nil, nil, nil, nil, library.FPCalc{}, Config{StagingDir: t.TempDir()}, slog.New(slog.DiscardHandler))
owner := auth.WithPrincipal(ctx, auth.Principal{UserID: author, Role: auth.RoleAdmin})