Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Misskey backend のテスト構成、`.config/test.yml` の前提、e2e テス

## 前提: `.config/test.yml`

backend のテストスクリプト (`test` / `test:e2e` / `test:fed`) はすべて内部で `cross-env NODE_ENV=test pnpm compile-config` を実行し、`.config/test.yml` を読み込む ([packages/backend/package.json](../../../../../packages/backend/package.json), [packages/backend/scripts/compile_config.js](../../../../../packages/backend/scripts/compile_config.js))。**未作成だとテスト自体が起動しない**。
backend のテストスクリプト (`test` / `test:e2e` / `test:fed`) はすべて `.config/test.yml` を読み込む。**未作成だとテスト自体が起動しない。**

未作成なら以下を 1 回だけ手動コピーする (どちらでも可):

Expand All @@ -27,7 +27,6 @@ cp .github/misskey/test.yml .config/test.yml
補足:

- ルートの `pnpm start:test` (Cypress 用にテストサーバーを起動するコマンド) を使う経路では実行時に `ncp` で自動コピーされる ([package.json](../../../../../package.json))。それ以外で backend テストを直接走らせる時は上記の手動コピーが必要
- すでに `.config/test.yml` があれば各テストスクリプトの内部 `compile-config` で十分なので、追加で `pnpm --filter backend compile-config` を叩く必要はない
- `pnpm start:test` は backend e2e テスト (`pnpm --filter backend test:e2e`) の前提ではない (ポート競合の元になるため使わないこと)

## テスト種別と実行コマンド
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ node .claude/skills/working-on-backend/scripts/prepare-generate.mjs
スクリプトがやること:

- `pnpm build-pre` → `built/meta.json` を生成 (`loadConfig()` が要求)
- `pnpm --filter backend compile-config` → `built/.config.json` を生成 (`ormconfig.js` の `loadConfig()` が要求するのはこれ。ソースの `.config/default.yml` はその入力なので、無ければ `.config/example.yml` から作っておく)
- `pnpm --filter backend build` → エンティティを `built/` に反映 (CLI は `built/` を読む)
- `docker compose -f compose.local-db.yml up -d --wait db` → ローカル DB (postgres) を起動。`--wait` は Docker Compose v2.1.1 (2021-11) 以降が必要 (v2 の `docker compose` 前提。EOL の `docker-compose` v1 は対象外)

Expand Down
11 changes: 4 additions & 7 deletions .claude/skills/working-on-backend/scripts/prepare-generate.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ function step(msg) { console.log(`\n==> ${msg}`); }
function run(cmd) { console.log(`$ ${cmd}`); execSync(cmd, { stdio: 'inherit' }); }
function fail(msg) { console.error(`ERROR: ${msg}`); process.exit(1); }

step('1/5 設定ファイルの確認');
step('1/4 設定ファイルの確認');
if (!existsSync('.config/default.yml')) {
fail([
'.config/default.yml が存在しません。',
Expand All @@ -46,16 +46,13 @@ if (!existsSync('.config/docker.env')) {
}
console.log('OK: .config/default.yml と .config/docker.env あり');

step('2/5 built/meta.json の生成 (build-pre)');
step('2/4 built/meta.json の生成 (build-pre)');
run('pnpm build-pre');

step('3/5 設定のコンパイル (compile-config -> built/.config.json)');
run('pnpm --filter backend compile-config');

step('4/5 backend のビルド (エンティティを built/ へ反映)');
step('3/4 backend のビルド (エンティティを built/ へ反映)');
run('pnpm --filter backend build');

step('5/5 ローカル DB の起動 (postgres のみ・healthcheck 完了まで待機)');
step('4/4 ローカル DB の起動 (postgres のみ・healthcheck 完了まで待機)');
// migration:generate が必要とするのは postgres だけ。db サービスに絞れば meilisearch.env 等が無くても動く。
// --wait は compose の pg_isready healthcheck 完了まで待つ。直後の migration:generate が
// DB 未起動で失敗しないために必須。--wait は Docker Compose v2.1.1 (2021-11) で導入されており、
Expand Down
2 changes: 1 addition & 1 deletion .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
- Migration 差分検査: `pnpm --filter backend check-migrations`
- `misskey-js` 再生成 (API 変更後必須): `pnpm build-misskey-js-with-types`

**注意:** backend テスト (`test` / `test:e2e` / `test:fed`) 実行前に `.config/test.yml` が必要。未作成の場合は `ncp .github/misskey/test.yml .config/test.yml` (または `cp .github/misskey/test.yml .config/test.yml`) を実行してから走らせる。各テストスクリプトが内部で `cross-env NODE_ENV=test pnpm compile-config` を呼ぶため、コピー済みであれば追加の compile-config は不要。
**注意:** backend テスト (`test` / `test:e2e` / `test:fed`) 実行前に `.config/test.yml` が必要。未作成の場合は `ncp .github/misskey/test.yml .config/test.yml` (または `cp .github/misskey/test.yml .config/test.yml`) を実行してから走らせる。

変更範囲に応じて最も近いコマンドから優先して検証し、必要なら全体コマンドに広げること。

Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/get-backend-memory.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,6 @@ jobs:
run: git diff --exit-code pnpm-lock.yaml
- name: Copy Configure
run: cp .github/misskey/test.yml .config/default.yml
- name: Compile Configure
run: pnpm compile-config
- name: Build
run: pnpm build
- name: Run migrations
Expand Down
7 changes: 3 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,14 @@
],
"private": true,
"scripts": {
"compile-config": "cd packages/backend && pnpm compile-config",
"build-pre": "node scripts/build-pre.mjs",
"build-assets": "node ./scripts/build-assets.mjs",
"build": "pnpm build-pre && pnpm -r build && pnpm build-assets",
"build-storybook": "pnpm --filter frontend build-storybook",
"build-misskey-js-with-types": "pnpm build-pre && pnpm --filter backend... --filter=!misskey-js build && pnpm --filter backend generate-api-json --no-build && ncp packages/backend/built/api.json packages/misskey-js/generator/api.json && pnpm --filter misskey-js update-autogen-code && pnpm --filter misskey-js build && pnpm --filter misskey-js api",
"start": "cd packages/backend && pnpm compile-config && node ./built/entry.js",
"start:inspect": "cd packages/backend && pnpm compile-config && node --inspect ./built/entry.js",
"start:test": "ncp ./.github/misskey/test.yml ./.config/test.yml && cd packages/backend && cross-env NODE_ENV=test pnpm compile-config && cross-env NODE_ENV=test node ./built/entry.js",
"start": "pnpm check:connect && cd packages/backend && node ./built/entry.js",
"start:inspect": "cd packages/backend && node --inspect ./built/entry.js",
"start:test": "ncp ./.github/misskey/test.yml ./.config/test.yml && cd packages/backend && cross-env NODE_ENV=test node ./built/entry.js",
"cli": "cd packages/backend && pnpm cli",
"init": "pnpm migrate",
"migrate": "cd packages/backend && pnpm migrate",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/

import {loadConfig} from "./js/migration-config.js";

export class MigrateSomeConfigFileSettingsToMeta1746949539915 {
name = 'MigrateSomeConfigFileSettingsToMeta1746949539915'

async up(queryRunner) {
const config = loadConfig();
// $1 cannot be used in ALTER TABLE queries
await queryRunner.query(`ALTER TABLE "meta" ADD "proxyRemoteFiles" boolean NOT NULL DEFAULT TRUE`);
await queryRunner.query(`ALTER TABLE "meta" ADD "signToActivityPubGet" boolean NOT NULL DEFAULT TRUE`);
await queryRunner.query(`ALTER TABLE "meta" ADD "allowExternalApRedirect" boolean NOT NULL DEFAULT TRUE`);
await queryRunner.query(`ALTER TABLE "meta" ADD "proxyRemoteFiles" boolean NOT NULL DEFAULT ${config.proxyRemoteFiles}`);
await queryRunner.query(`ALTER TABLE "meta" ADD "signToActivityPubGet" boolean NOT NULL DEFAULT ${config.signToActivityPubGet}`);
await queryRunner.query(`ALTER TABLE "meta" ADD "allowExternalApRedirect" boolean NOT NULL DEFAULT ${!config.disallowExternalApRedirect}`);
}

async down(queryRunner) {
Expand Down
31 changes: 31 additions & 0 deletions packages/backend/migration/js/migration-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/

import { path as configYamlPath } from '../../built/config.js';
import * as yaml from 'js-yaml';
import fs from "node:fs";

export function isConcurrentIndexMigrationEnabled() {
return process.env.MISSKEY_MIGRATION_CREATE_INDEX_CONCURRENTLY === '1';
}

let loadedConfigCache = undefined;

function loadConfigInternal() {
const config = yaml.load(fs.readFileSync(configYamlPath, 'utf-8'));

return {
disallowExternalApRedirect: Boolean(config.disallowExternalApRedirect ?? false),
proxyRemoteFiles: Boolean(config.proxyRemoteFiles ?? false),
signToActivityPubGet: Boolean(config.signToActivityPubGet ?? true),
}
}

export function loadConfig() {
if (loadedConfigCache === undefined) {
loadedConfigCache = loadConfigInternal();
}
return loadedConfigCache;
}
5 changes: 2 additions & 3 deletions packages/backend/ormconfig.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { DataSource } from 'typeorm';
import { loadConfig } from './built/config.js';
import { entities } from './built/postgres.js';

const isConcurrentIndexMigrationEnabled = process.env.MISSKEY_MIGRATION_CREATE_INDEX_CONCURRENTLY === '1';
import { isConcurrentIndexMigrationEnabled } from "./migration/js/migration-config.js";

const config = loadConfig();

Expand All @@ -16,5 +15,5 @@ export default new DataSource({
extra: config.db.extra,
entities: entities,
migrations: ['migration/*.js'],
migrationsTransactionMode: isConcurrentIndexMigrationEnabled ? 'each' : 'all',
migrationsTransactionMode: isConcurrentIndexMigrationEnabled() ? 'each' : 'all',
});
33 changes: 16 additions & 17 deletions packages/backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,30 @@
"node": "^22.15.0 || ^24.10.0"
},
"scripts": {
"start": "pnpm compile-config && node ./built/entry.js",
"start:inspect": "pnpm compile-config && node --inspect ./built/entry.js",
"start:test": "cross-env NODE_ENV=test pnpm compile-config && cross-env NODE_ENV=test node ./built/entry.js",
"migrate": "pnpm compile-config && pnpm typeorm migration:run -d ormconfig.js",
"revert": "pnpm compile-config && pnpm typeorm migration:revert -d ormconfig.js",
"cli": "pnpm compile-config && node ./built/cli.js",
"check:connect": "pnpm compile-config && node ./scripts/check_connect.js",
"compile-config": "node ./scripts/compile_config.js",
"start": "node ./built/entry.js",
"start:inspect": "node --inspect ./built/entry.js",
"start:test": "cross-env NODE_ENV=test node ./built/entry.js",
"migrate": "pnpm typeorm migration:run -d ormconfig.js",
"revert": "pnpm typeorm migration:revert -d ormconfig.js",
"cli": "node ./built/cli.js",
"check:connect": "node ./scripts/check_connect.js",
"build": "rolldown -c",
"build:unit": "rolldown -c --sourcemap",
"build:e2e": "rolldown -c --e2e",
"build:tsc": "tsgo -p tsconfig.json && tsc-alias -p tsconfig.json",
"watch": "pnpm compile-config && node ./scripts/watch.mjs",
"watch": "node ./scripts/watch.mjs",
"restart": "pnpm build && pnpm start",
"dev": "pnpm compile-config && rolldown -c --watch",
"dev": "rolldown -c --watch",
"typecheck": "tsgo --noEmit && tsgo -p test --noEmit && tsgo -p test-federation --noEmit",
"eslint": "eslint --quiet \"{src,test-federation}/**/*.ts\"",
"lint": "pnpm typecheck && pnpm eslint",
"test": "pnpm build:unit && cross-env NODE_ENV=test pnpm compile-config && vitest --config vitest.config.unit.ts",
"test:e2e": "pnpm build:e2e && cross-env NODE_ENV=test pnpm compile-config && vitest --config vitest.config.e2e.ts",
"test:fed": "cross-env NODE_ENV=test pnpm compile-config && vitest --config vitest.config.fed.ts",
"test-and-coverage": "pnpm build:unit && cross-env NODE_ENV=test pnpm compile-config && vitest --coverage --config vitest.config.unit.ts",
"test-and-coverage:e2e": "pnpm build:e2e && cross-env NODE_ENV=test pnpm compile-config && vitest --coverage --config vitest.config.e2e.ts",
"test": "pnpm build:unit && vitest --config vitest.config.unit.ts",
"test:e2e": "pnpm build:e2e && vitest --config vitest.config.e2e.ts",
"test:fed": "vitest --config vitest.config.fed.ts",
"test-and-coverage": "pnpm build:unit && vitest --coverage --config vitest.config.unit.ts",
"test-and-coverage:e2e": "pnpm build:e2e && vitest --coverage --config vitest.config.e2e.ts",
"check-migrations": "node scripts/check_migrations_clean.js",
"generate-api-json": "pnpm compile-config && node ./scripts/generate_api_json.js"
"generate-api-json": "node ./scripts/generate_api_json.js"
},
"optionalDependencies": {
"@tensorflow/tfjs": "4.22.0",
Expand Down Expand Up @@ -105,6 +104,7 @@
"ip-cidr": "4.0.2",
"ipaddr.js": "2.4.0",
"is-svg": "6.1.0",
"js-yaml": "4.1.1",
"json5": "2.2.3",
"jsonld": "9.0.0",
"juice": "11.1.1",
Expand Down Expand Up @@ -191,7 +191,6 @@
"eslint-plugin-import": "2.32.0",
"execa": "9.6.1",
"fkill": "10.0.3",
"js-yaml": "4.1.1",
"pid-port": "2.1.1",
"rolldown": "1.0.3",
"simple-oauth2": "5.1.0",
Expand Down
54 changes: 0 additions & 54 deletions packages/backend/scripts/compile_config.js

This file was deleted.

20 changes: 10 additions & 10 deletions packages/backend/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import * as fs from 'node:fs';
import { fileURLToPath } from 'node:url';
import { dirname, resolve } from 'node:path';
import * as yaml from 'js-yaml';
import { type FastifyServerOptions } from 'fastify';
import type * as Sentry from '@sentry/node';
import type * as SentryVue from '@sentry/vue';
Expand Down Expand Up @@ -235,23 +236,22 @@ const configDir = resolve(rootDir, '.config');
/** Path of built directory */
const projectBuiltDir = resolve(rootDir, 'built');

const compiledConfigFilePathForTest = resolve(projectBuiltDir, '._config_.json');

export const compiledConfigFilePath = fs.existsSync(compiledConfigFilePathForTest)
? compiledConfigFilePathForTest
: resolve(projectBuiltDir, '.config.json');
/**
* Path of configuration file
*/
export const path = process.env.MISSKEY_CONFIG_YML
? resolve(configDir, process.env.MISSKEY_CONFIG_YML)
: process.env.NODE_ENV === 'test'
? resolve(configDir, 'test.yml')
: resolve(configDir, 'default.yml');

export function loadConfig(): Config {
if (!fs.existsSync(compiledConfigFilePath)) {
throw new Error('Compiled configuration file not found. Try running \'pnpm compile-config\'.');
}

const meta = JSON.parse(fs.readFileSync(resolve(projectBuiltDir, 'meta.json'), 'utf-8'));

const frontendManifestExists = fs.existsSync(resolve(projectBuiltDir, '_frontend_vite_/manifest.json'));
const frontendEmbedManifestExists = fs.existsSync(resolve(projectBuiltDir, '_frontend_embed_vite_/manifest.json'));

const config = JSON.parse(fs.readFileSync(compiledConfigFilePath, 'utf-8')) as Source;
const config = yaml.load(fs.readFileSync(path, 'utf-8')) as Source;

const url = tryCreateUrl(config.url ?? process.env.MISSKEY_URL ?? '');
const version = meta.version;
Expand Down
2 changes: 0 additions & 2 deletions packages/backend/test-federation/.config/dummy.yml

This file was deleted.

29 changes: 0 additions & 29 deletions packages/backend/test-federation/.config/example.config.json

This file was deleted.

23 changes: 23 additions & 0 deletions packages/backend/test-federation/.config/example.default.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
url: https://${HOST}/
port: 3000
db:
host: db.${HOST}
port: 5432
db: misskey
user: postgres
pass: postgres
dbReplications: false
trustProxy: true
redis:
host: redis.test
port: 6379
id: 'aidx'
proxyBypassHosts:
- api.deepl.com
- api-free.deepl.com
- www.recaptcha.net
- hcaptcha.com
- challenges.cloudflare.com
allowedPrivateNetworks:
- 127.0.0.1/32
- 172.20.0.0/16
4 changes: 2 additions & 2 deletions packages/backend/test-federation/compose.a.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ services:
- internal_network_a
volumes:
- type: bind
source: ./.config/a.test.config.json
target: /misskey/built/._config_.json
source: ./.config/a.test.default.yml
target: /misskey/.config/default.yml
read_only: true

db.a.test:
Expand Down
4 changes: 2 additions & 2 deletions packages/backend/test-federation/compose.b.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ services:
- internal_network_b
volumes:
- type: bind
source: ./.config/b.test.config.json
target: /misskey/built/._config_.json
source: ./.config/b.test.default.yml
target: /misskey/.config/default.yml
read_only: true

db.b.test:
Expand Down
Loading
Loading