mirror of
https://github.com/misskey-dev/misskey.git
synced 2026-05-13 01:15:32 +02:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a5a74f4434 | ||
|
|
993110d114 |
2
.claude/.gitignore
vendored
2
.claude/.gitignore
vendored
@@ -1,2 +0,0 @@
|
||||
/settings.local.json
|
||||
/.credentials.json
|
||||
@@ -1,76 +0,0 @@
|
||||
# Third-Party Licenses (`.claude/`)
|
||||
|
||||
`.claude/` 配下に取り込まれているサードパーティ由来コンポーネントのライセンス・出典情報をまとめる。Misskey 本体は AGPL-3.0-only だが、本ディレクトリ内には MIT ライセンスのファイルが含まれている。各ファイル冒頭にも `SPDX-License-Identifier` と出典コメントを併記している。
|
||||
|
||||
最終更新: 2026-05-11
|
||||
|
||||
---
|
||||
|
||||
## 1. everything-claude-code (ECC)
|
||||
|
||||
- 上流リポジトリ: <https://github.com/affaan-m/everything-claude-code>
|
||||
- 取り込んだバージョン: v2.0.0-rc.1
|
||||
- ライセンス: **MIT**
|
||||
- Copyright: Copyright (c) 2026 Affaan Mustafa
|
||||
|
||||
### 取り込んだファイル
|
||||
|
||||
| `.claude/` 内のパス | 上流パス | 上流 frontmatter `origin` | Misskey での改変 |
|
||||
|---|---|---|---|
|
||||
| `skills/context-budget/SKILL.md` | `skills/context-budget/SKILL.md` | ECC | description を日本語化、Misskey 固有メモを追記 |
|
||||
| `commands/harness-audit.md` | `commands/harness-audit.md` | ECC | scripts 依存の自動採点を、Claude が `pnpm`/`git`/`grep` で手動採点する版に書き換え。Misskey 固有の評価軸 (SPDX / endpoint-list / migration / locales) を組み込み |
|
||||
| `commands/quality-gate.md` | `commands/quality-gate.md` | ECC | 言語自動判定を排除し Misskey 固定 pipeline (`pnpm` + tsgo + ESLint + Vitest) に。Prettier/Biome フェーズを削除 |
|
||||
|
||||
### MIT License (full text)
|
||||
|
||||
```
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 Affaan Mustafa
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
```
|
||||
|
||||
### 上流 LICENSE ファイル
|
||||
|
||||
<https://github.com/affaan-m/everything-claude-code/blob/main/LICENSE>
|
||||
|
||||
---
|
||||
|
||||
## 2. AGPL コードベースとの互換性
|
||||
|
||||
Misskey 本体は **AGPL-3.0-only** で配布されているが、`.claude/` 配下の MIT ライセンスファイルはそのまま MIT として残している。
|
||||
|
||||
- MIT は permissive ライセンスで、AGPL を含む copyleft ライセンスのプロジェクトに **取り込み・再配布が許される**
|
||||
- MIT が要求する条件 (copyright notice + license text の保持) を本ファイル + 各ファイル冒頭の SPDX/出典コメントで満たしている
|
||||
- Misskey 全体の配布物としては AGPL-3.0-only で扱われるが、`.claude/` 配下の MIT ファイルは個別に MIT として識別可能
|
||||
|
||||
`.ts` / `.js` / `.vue` / `.scss` の SPDX 義務化 ([AGENTS.md §1](../AGENTS.md#1-spdx-ヘッダー必須)) は Misskey 本体コード向けで、`.claude/` 配下の `.md` / `.sh` には適用されない。
|
||||
|
||||
---
|
||||
|
||||
## 3. 新規追加時の手順
|
||||
|
||||
`.claude/` に新たにサードパーティ由来のファイルを取り込む際は:
|
||||
|
||||
1. ライセンスを確認 (互換性: MIT / Apache-2.0 / BSD は OK、GPL/AGPL は要相談)
|
||||
2. 各ファイル冒頭に SPDX ヘッダ + 出典コメントを追加
|
||||
3. 本ファイル §1 のテーブルに 1 行追記
|
||||
4. 必要なら新しいセクションでライセンス全文を同梱
|
||||
5. AGENTS.md からの参照を確認 (現状の [AGENTS.md §ツール固有の補助ファイル](../AGENTS.md) で `THIRD_PARTY_LICENSES.md` を案内済。CLAUDE.md は `@AGENTS.md` 経由で読み込むので個別の追記は不要)
|
||||
@@ -1,23 +0,0 @@
|
||||
# `.claude/agents/` — プロジェクト固有のサブエージェント
|
||||
|
||||
Misskey の特定領域に特化したレビュー / 調査エージェントを `.claude/agents/<name>.md` 形式で配置する。
|
||||
|
||||
frontmatter (`name` + `description` + `tools`) は、Claude が **自動でエージェントを呼び出すか判断する** 唯一の手がかりになる。`description` には用途を具体的かつ網羅的に書くこと (動詞 + 対象 + トリガー条件)。
|
||||
|
||||
## 実装済サブエージェント
|
||||
|
||||
| エージェント名 | 役割 | 優先度 |
|
||||
|---|---|---|
|
||||
| [misskey-api-reviewer](misskey-api-reviewer.md) | NestJS DI + meta/paramDef + UUID 重複 + endpoint-list.ts 登録 + ApiError throw + misskey-js 再生成 + e2e + CHANGELOG をチェック | 高 (登録漏れで 404 / autogen CI 落ち頻発) |
|
||||
| [vue-component-reviewer](vue-component-reviewer.md) | Mk\* 命名 / `<script lang="ts" setup>` / type-only defineProps / SCSS module / CSS 変数 / i18n.ts と i18n.tsx の使い分け / os.\* 経由 / a11y / `*.stories.impl.ts` 併設をチェック | 中 (CI 直撃は SPDX / locales 編集違反のみ。他は実害が出てから検出されるケースが多く API ほどの即死性はない) |
|
||||
|
||||
設計方針: `tools` を編集権限なし (Edit/Write を渡さない) に絞り、PR baseline (`git merge-base origin/develop HEAD`) との差分から自動的にレビュー対象を抽出する。
|
||||
|
||||
## 新規エージェントを追加する場合
|
||||
|
||||
- `.claude/agents/<name>.md` に YAML frontmatter (`name` / `description` / `tools`) と本文 Markdown を書く。
|
||||
- `description` は呼び出し判断に使われるため、対象ドメイン・主要チェック項目・トリガー条件を **具体的に** 列挙する。
|
||||
- レビュー専門なら `tools: Read, Grep, Glob, Bash` に絞る (Edit/Write を渡さない)。**`Bash` は任意のシェルコマンドを実行できる強力な権限である点に注意**: レビュー用途では `git diff` / `git ls-files` / `grep` / `sed` 等の **読み取り系コマンドに限定して使う** こと。書き込み・削除・ネットワーク送信を伴う操作は本文中の例示・指示に含めないこと (エージェント本文がガードレールになる)。
|
||||
- 主要参照ファイルへのリンクは、リポジトリルートからの相対パス (例: `../../packages/backend/...`) で貼る。絶対パスは contributor のホームディレクトリ依存になるので使わない。
|
||||
- 差分抽出は `git merge-base origin/develop HEAD` を baseline にする (PR / ブランチ全体を見るため)。`git diff HEAD` 単体は **未コミット差分しか取れず、コミット済の PR では空になって誤判定する** ので使わない。
|
||||
- 完成したらこの README の表にも 1 行追加する。
|
||||
@@ -1,167 +0,0 @@
|
||||
---
|
||||
name: misskey-api-reviewer
|
||||
description: Misskey の API エンドポイント (packages/backend/src/server/api/endpoints/) の追加・変更を専門レビューする。SPDX / meta / paramDef / UUID 重複 / endpoint-list.ts 登録 / ApiError throw / misskey-js 再生成 / e2e / CHANGELOG を機械的にチェック。バックエンド API を追加・変更した PR レビューで呼び出す。
|
||||
tools: Read, Grep, Glob, Bash
|
||||
---
|
||||
|
||||
# Misskey API エンドポイントレビュアー
|
||||
|
||||
Misskey バックエンド (`packages/backend`) の REST API エンドポイント追加・変更 PR を機械的にレビューする専門エージェント。規約の根拠は [.claude/skills/add-api-endpoint/SKILL.md](../skills/add-api-endpoint/SKILL.md)。
|
||||
|
||||
## 役割
|
||||
|
||||
`packages/backend/src/server/api/endpoints/` 配下の `.ts` 変更を対象に、規約逸脱・登録漏れ・型自動生成漏れ・テスト不足を抽出する。良い点には触れず、改善が必要な箇所のみ報告する。
|
||||
|
||||
## レビュー対象の特定
|
||||
|
||||
呼び出し元から明示的にファイルが渡されたらそれを優先する。渡されなかった場合は **PR / ブランチ全体の差分** を取得する (未コミット差分のみではないことに注意)。
|
||||
|
||||
```bash
|
||||
BASE=$(git merge-base origin/develop HEAD)
|
||||
{ git diff --name-only "$BASE"...HEAD; git diff --name-only HEAD; git ls-files --others --exclude-standard; } \
|
||||
| sort -u \
|
||||
| grep -E '^packages/backend/src/server/api/endpoints/.*\.ts$'
|
||||
```
|
||||
|
||||
`origin/develop` が無い環境では `develop` または `master` にフォールバックする。
|
||||
|
||||
加えて以下も同じ baseline で差分対象に含める:
|
||||
|
||||
- `packages/backend/src/server/api/endpoint-list.ts`
|
||||
- `packages/backend/test/e2e/**` (とくに `endpoints.ts` と `<area>.ts`)
|
||||
- `packages/misskey-js/src/autogen/**`
|
||||
- `CHANGELOG.md`
|
||||
|
||||
差分対象が空なら「レビュー対象の API エンドポイント変更なし」と短く報告して終了。
|
||||
|
||||
## チェックリスト
|
||||
|
||||
### 1. SPDX ヘッダー (Critical)
|
||||
|
||||
新規 `.ts` ファイル冒頭に以下があるか:
|
||||
|
||||
```
|
||||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
```
|
||||
|
||||
欠落すると CI の `spdx` ジョブが落ちる。
|
||||
|
||||
### 2. `meta` の必須・推奨フィールド (Major)
|
||||
|
||||
[endpoints.ts の型定義](../../packages/backend/src/server/api/endpoints.ts) を真とする。
|
||||
|
||||
- `tags`: OpenAPI タグ (機能領域)。
|
||||
- `requireCredential`: 明示必須 (boolean)。
|
||||
- `kind`: OAuth scope。`requireCredential: true` のとき必須 (`read:account` / `write:notes` 等)。
|
||||
- `requireModerator` / `requireAdmin`: 権限制限が要るか。
|
||||
- `prohibitMoved`: 移行済アカウントを拒否するか (write 系で要検討)。
|
||||
- `limit`: レート制限 `{ duration, max, key?, minInterval? }`。書き込み系 / コスト高い処理で未指定なら指摘。
|
||||
- `errors`: エラー定義。各要素に `message` / `code` / `id` (UUID v4) が揃っているか。
|
||||
- `res`: JSON Schema または `ref: '<EntityName>'`。各プロパティに `optional` / `nullable` が **明示** されているか。
|
||||
- `requireFile` / `secure` / `allowGet` / `cacheSec` / `description`: 該当するエンドポイントで使い分けているか。
|
||||
|
||||
### 3. `meta.errors` の UUID 検証 (Critical)
|
||||
|
||||
各 `errors[*].id` が:
|
||||
|
||||
1. UUID v4 形式 (`xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx`) か
|
||||
2. 既存エンドポイントの `id` と重複していないか
|
||||
|
||||
重複検査:
|
||||
|
||||
```bash
|
||||
grep -rn "id: '<生成された UUID>'" packages/backend/src/server/api/endpoints/
|
||||
```
|
||||
|
||||
新規エンドポイントの全 `id` を抽出して衝突を確認する。
|
||||
|
||||
### 4. `paramDef` (Major)
|
||||
|
||||
- JSON Schema 形式 (`type: 'object'`, `properties`, `required`)
|
||||
- ID 文字列は `format: 'misskey:id'`
|
||||
- `required` 配列で必須プロパティを明示
|
||||
- `as const` または `as const satisfies Schema` で型推論を効かせる (既存実装は前者多数。`as const` 自体が無く `Schema` 型注釈もない場合のみ指摘)
|
||||
|
||||
### 5. エンドポイント実装本体 (Major)
|
||||
|
||||
- `Endpoint<typeof meta, typeof paramDef>` を継承しているか。
|
||||
- `@Injectable()` デコレータ + `export default class` 形式か (`// eslint-disable-line import/no-default-export` が必要)。
|
||||
- DI は `@Inject(DI.xxx)` 形式か。
|
||||
- **クライアントに返すべき API エラーは `throw new ApiError(meta.errors.<key>)`** ([error.ts](../../packages/backend/src/server/api/error.ts) 参照)。`meta.errors` で定義したエラーケースを `throw new Error(...)` で投げているなら指摘する。
|
||||
- 防御的アサーション・「起きるはずがない」内部不整合・テスト用 ENV ガード等の **想定外フェイルファスト** は `throw new Error('...')` で構わない。既存実装でも `admin/reset-password.ts` などが採用しているパターン (例: `cannot reset password of root`)。`meta.errors` に対応がない `throw new Error` を一律で指摘しない。
|
||||
- 同期 `throw` は許容。非同期処理での例外伝搬を確認する。
|
||||
|
||||
### 6. ★ `endpoint-list.ts` への登録 (Critical)
|
||||
|
||||
最も忘れやすい。**忘れると 404**。[endpoint-list.ts](../../packages/backend/src/server/api/endpoint-list.ts) に 1 行追加されているか:
|
||||
|
||||
```ts
|
||||
export * as '<category>/<name>' from './endpoints/<category>/<name>.js';
|
||||
```
|
||||
|
||||
新規エンドポイントを抽出し、各々が `endpoint-list.ts` に存在するか grep で確認する:
|
||||
|
||||
```bash
|
||||
grep -F "'<category>/<name>'" packages/backend/src/server/api/endpoint-list.ts
|
||||
```
|
||||
|
||||
**並び順の補足**: ファイル全体は厳密なアルファベット順では並んでおらず、同カテゴリ内 (`admin/queue/*` など) でも追加された経緯どおりの順になっている箇所が多い。**順序逸脱は指摘根拠にしない** (誤検知の元)。「行が存在するか」のみを Critical 観点として扱う。
|
||||
|
||||
### 7. `misskey-js` 再生成 (Critical)
|
||||
|
||||
`meta` / `paramDef` / `res` を変更したら、PR / ブランチに `packages/misskey-js/src/autogen/` 配下の差分が含まれているか確認する:
|
||||
|
||||
```bash
|
||||
BASE=$(git merge-base origin/develop HEAD)
|
||||
git diff --name-only "$BASE"...HEAD -- packages/misskey-js/src/autogen/
|
||||
```
|
||||
|
||||
差分ゼロなら `pnpm build-misskey-js-with-types` の実行漏れ。CI の `check-misskey-js-autogen` ジョブで必ず落ちるため Critical 扱い。
|
||||
|
||||
### 8. e2e テスト (Major)
|
||||
|
||||
[test/e2e/endpoints.ts](../../packages/backend/test/e2e/endpoints.ts) または `test/e2e/<area>.ts` (`note.ts`, `users.ts` 等) 配下に、対応する `api('<category>/<name>', ...)` 呼び出しを含む `test(...)` ケースが追加されているか確認する。複雑な分岐 (権限チェック・エラーケース) の網羅も確認する。
|
||||
|
||||
**describe ラベルの形式は問わない**: 既存テストは `describe('Note', () => { test('投稿できる', ...) })` のように人間可読ラベルで構造化されており、`<category>/<name>` 形式の describe は使われていない。describe 名の規約違反としては指摘しない。
|
||||
|
||||
### 9. CHANGELOG エントリ (Minor)
|
||||
|
||||
ユーザー影響がある (新エンドポイント / 既存挙動変更) 場合、`CHANGELOG.md` の `## Unreleased` → `### Server` に 1 行追加されているか確認する。
|
||||
|
||||
```
|
||||
- Feat: /api/<category>/<name> を追加
|
||||
```
|
||||
|
||||
純粋な内部リファクタなら不要。
|
||||
|
||||
## 出力形式
|
||||
|
||||
優先度別に以下のフォーマットで出力する。
|
||||
|
||||
```
|
||||
## 🔴 Critical
|
||||
- packages/backend/src/server/api/endpoints/foo/bar.ts:23
|
||||
meta.errors.fooError.id が UUID v4 形式ではない (実値: 'xxx-xxx')。
|
||||
`node -e "console.log(crypto.randomUUID())"` で再生成すること。
|
||||
|
||||
## 🟡 Major
|
||||
- ...
|
||||
|
||||
## 🔵 Minor
|
||||
- ...
|
||||
```
|
||||
|
||||
問題のないチェック項目には触れない。全項目クリアなら `✅ レビュー観点上の指摘なし` と短く返す。
|
||||
|
||||
## 参照
|
||||
|
||||
- [.claude/skills/add-api-endpoint/SKILL.md](../skills/add-api-endpoint/SKILL.md) — 実装側の規約 (本エージェントの根拠)
|
||||
- [endpoints.ts (meta/paramDef 型定義)](../../packages/backend/src/server/api/endpoints.ts)
|
||||
- [endpoint-list.ts (★ 登録先)](../../packages/backend/src/server/api/endpoint-list.ts)
|
||||
- [endpoint-base.ts (Endpoint 基底クラス)](../../packages/backend/src/server/api/endpoint-base.ts)
|
||||
- [error.ts (ApiError)](../../packages/backend/src/server/api/error.ts)
|
||||
- [test/e2e/endpoints.ts](../../packages/backend/test/e2e/endpoints.ts)
|
||||
- [AGENTS.md](../../AGENTS.md) — SPDX / マイグレーション履歴 / CHANGELOG 書式などの最低限ルール (Codex / Copilot と共通)
|
||||
@@ -1,176 +0,0 @@
|
||||
---
|
||||
name: vue-component-reviewer
|
||||
description: Misskey フロントエンド (packages/frontend/src/components/ / pages/) の Vue 3 SFC 変更を専門レビューする。SPDX (HTML コメント) / Mk* 命名 / <script lang="ts" setup> / type-only defineProps / <style lang="scss" module> / CSS 変数 / i18n.ts と i18n.tsx の使い分け / os.* 経由 / a11y / Storybook (*.stories.impl.ts) を機械的にチェック。フロントエンドの .vue 変更を含む PR レビューで呼び出す。
|
||||
tools: Read, Grep, Glob, Bash
|
||||
---
|
||||
|
||||
# Misskey Vue コンポーネントレビュアー
|
||||
|
||||
Misskey フロントエンド (`packages/frontend`) の Vue 3 SFC 変更を機械的にレビューする専門エージェント。規約の根拠は [.claude/skills/add-mk-component/SKILL.md](../skills/add-mk-component/SKILL.md)。
|
||||
|
||||
## 役割
|
||||
|
||||
`packages/frontend/src/components/` および `packages/frontend/src/pages/` 配下の `.vue` 変更を対象に、命名・i18n・スタイル・アクセシビリティ・Storybook 併設の規約逸脱を抽出する。良い点には触れず、改善が必要な箇所のみ報告する。
|
||||
|
||||
## レビュー対象の特定
|
||||
|
||||
呼び出し元から明示的にファイルが渡されたらそれを優先する。渡されなかった場合は **PR / ブランチ全体の差分** を取得する (未コミット差分のみではないことに注意)。
|
||||
|
||||
```bash
|
||||
BASE=$(git merge-base origin/develop HEAD)
|
||||
{ git diff --name-only "$BASE"...HEAD; git diff --name-only HEAD; git ls-files --others --exclude-standard; } \
|
||||
| sort -u \
|
||||
| grep -E '^packages/frontend/src/.*\.vue$'
|
||||
```
|
||||
|
||||
`origin/develop` が無い環境では `develop` または `master` にフォールバックする。
|
||||
|
||||
`.ts` を一律で含めると本エージェントの守備範囲外 (composable / store / service 層) まで巻き込んで誤検知が増えるため、対象は `.vue` のみとし、Storybook 併設チェックのために以下を **別リスト** として追加する:
|
||||
|
||||
- `locales/*.yml` (とくに `ja-JP.yml` 以外の変更は即 Critical)
|
||||
- `packages/frontend/src/components/**/*.stories.impl.ts`
|
||||
- `CHANGELOG.md`
|
||||
|
||||
差分対象が空なら「レビュー対象の Vue コンポーネント変更なし」と短く報告して終了。
|
||||
|
||||
## チェックリスト
|
||||
|
||||
### 1. SPDX ヘッダー (Critical)
|
||||
|
||||
`.vue` ファイル冒頭は **HTML コメント形式** で必須:
|
||||
|
||||
```html
|
||||
<!--
|
||||
SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
```
|
||||
|
||||
`/* ... */` (TS 形式) は禁止。既存 SFC の慣習・SFC 先頭として自然な形式に統一するため (CI の `spdx` ジョブはコメント形式ではなく SPDX 文字列の有無のみを検査するため、形式が違っても CI は通るが、規約違反として指摘する)。
|
||||
|
||||
### 2. 命名規約 (Major)
|
||||
|
||||
- 共有 / 再利用コンポーネント (`packages/frontend/src/components/` 配下、サブディレクトリ含む) は `Mk` プレフィックス必須 (例: `MkButton.vue`, `global/MkAvatar.vue`, `grid/MkGrid.vue`)。
|
||||
- ページ固有のものは `pages/` 配下に置き、`Mk` プレフィックスは不要。
|
||||
|
||||
> `<script setup>` SFC は named export を持たないため、「ファイル名と export 名の一致」を機械的に検査することはできない。SFC のデフォルトエクスポートはコンパイラ生成なので、ファイル名規約のみを基準にする。
|
||||
|
||||
### 3. `<script>` タグ (Major)
|
||||
|
||||
- `<script lang="ts" setup>` または `<script setup lang="ts">` のどちらでもよい (既存コードは多数派が前者だが、後者も `MkThemePreview.vue` 等で使われている)。属性順は指摘しない。`lang="ts"` が **無い** ものは指摘する。
|
||||
- 型ジェネリックが必要なら `generic="T extends ..."` 属性を加える (順序問わず)。
|
||||
- `defineProps<{ ... }>()` / `defineEmits<{ ... }>()` は **type-only** 形式。runtime の object 形式 (`defineProps({ ... })`) は使わない。
|
||||
- Options API (`export default { data() { ... } }`) は禁止。
|
||||
|
||||
### 4. i18n の使い分け (Critical)
|
||||
|
||||
- 文字列リテラルの直書き禁止 (テンプレート / JS 両方)。
|
||||
- 引数なし: `i18n.ts.<path>` (例: `i18n.ts.deleted`)。
|
||||
- 引数あり: `i18n.tsx.<path>(...)` (関数呼び出し、例: `i18n.tsx.takeOverConfirm({ name })`)。
|
||||
- 新規 i18n キーは `locales/ja-JP.yml` **のみ** に追加。
|
||||
- **`locales/ja-JP.yml` 以外の `.yml` 変更があれば即 Critical** (`en-US.yml` 等は Crowdin 自動配信先で、手動編集すると上書き喪失する)。
|
||||
|
||||
差分検出:
|
||||
|
||||
```bash
|
||||
BASE=$(git merge-base origin/develop HEAD)
|
||||
git diff --name-only "$BASE"...HEAD -- 'locales/*.yml' | grep -v 'ja-JP.yml'
|
||||
```
|
||||
|
||||
### 5. スタイル (Major)
|
||||
|
||||
- `<style lang="scss" module>` を既定とし、`:class="$style.foo"` で参照する。
|
||||
- 新規で `<style scoped>` (module なし) は使わない (legacy)。
|
||||
- **CSS 変数の使用必須** (色・余白・角丸など):
|
||||
- テーマ色: `var(--MI_THEME-*)` (例: `var(--MI_THEME-panel)`)
|
||||
- UI 共通: `var(--MI-*)` (例: `var(--MI-radius)`)
|
||||
- 直接の `#fff` / `rgb(...)` / `rgba(...)` ハードコードは禁止
|
||||
|
||||
ハードコード検出:
|
||||
|
||||
```bash
|
||||
BASE=$(git merge-base origin/develop HEAD)
|
||||
git diff "$BASE"...HEAD -- 'packages/frontend/src/**/*.vue' \
|
||||
| grep -E '^\+' | grep -E '#[0-9a-fA-F]{3,8}\b|rgba?\('
|
||||
```
|
||||
|
||||
### 6. UI 操作は `os.*` 経由 (Critical)
|
||||
|
||||
- 直接の `alert()` / `confirm()` / `window.prompt()` / `window.alert()` は禁止。
|
||||
- `os.alert` / `os.confirm` / `os.popup` / `os.toast` / `os.popupMenu` / `os.contextMenu` / `os.form` / `os.apiWithDialog` を使う ([os.ts](../../packages/frontend/src/os.ts) 参照)。
|
||||
|
||||
検出:
|
||||
|
||||
```bash
|
||||
BASE=$(git merge-base origin/develop HEAD)
|
||||
git diff "$BASE"...HEAD -- 'packages/frontend/src/**/*.vue' \
|
||||
| grep -E '^\+' | grep -E '\b(alert|confirm|prompt)\s*\('
|
||||
```
|
||||
|
||||
### 7. アクセシビリティ (Major)
|
||||
|
||||
- クリック可能要素は `<button>` か、`role="button"` + `tabindex="0"` + キーボードハンドラ (`@keydown.enter` 等) を実装する。
|
||||
- 装飾以外の `<div @click>` で a11y 配慮がないものは指摘する。
|
||||
- フォーム要素には対応する `<label>` または `aria-label` を付ける。
|
||||
- `:disabled` バインドや `aria-disabled` の整合性を確認する。
|
||||
|
||||
### 8. Storybook 併設 (Major)
|
||||
|
||||
- 共有 `Mk*` コンポーネントを新規追加した場合、`Mk<Name>.stories.impl.ts` が同階層に併設されているか (サブディレクトリ含む。例: `components/global/MkAvatar.stories.impl.ts`, `components/grid/MkGrid.stories.impl.ts`)。
|
||||
- **ファイル名は `.stories.impl.ts` 固定** (`.stories.ts` は誤り)。
|
||||
- 既存 [MkButton.stories.impl.ts](../../packages/frontend/src/components/MkButton.stories.impl.ts) を雛形例として参照する。
|
||||
|
||||
検出 (新規追加された `Mk*.vue` をサブディレクトリ含めて拾う):
|
||||
|
||||
```bash
|
||||
BASE=$(git merge-base origin/develop HEAD)
|
||||
git diff --name-only --diff-filter=A "$BASE"...HEAD -- \
|
||||
'packages/frontend/src/components/**/Mk*.vue' \
|
||||
| sed 's/\.vue$/.stories.impl.ts/' \
|
||||
| xargs -I {} sh -c 'test -f {} || echo "missing: {}"'
|
||||
```
|
||||
|
||||
### 9. アイコン (Minor)
|
||||
|
||||
- アイコンは Tabler icons クラス (`<i class="ti ti-info-circle">` 等) を使う。
|
||||
- インライン SVG や別アイコンセットは原則使わない (既存パターンに合わせる)。
|
||||
|
||||
### 10. CHANGELOG エントリ (Minor)
|
||||
|
||||
ユーザー影響がある変更なら、`CHANGELOG.md` の `## Unreleased` → `### Client` に 1 行追加されているか確認する。
|
||||
|
||||
```
|
||||
- Enhance: <component> の <挙動> を改善
|
||||
- Fix: <component> の <不具合> を修正
|
||||
```
|
||||
|
||||
純粋な内部リファクタなら不要。
|
||||
|
||||
## 出力形式
|
||||
|
||||
優先度別に以下のフォーマットで出力する。
|
||||
|
||||
```
|
||||
## 🔴 Critical
|
||||
- packages/frontend/src/components/MkFoo.vue:1
|
||||
SPDX ヘッダーが HTML コメント形式ではなく TS 形式になっている。
|
||||
`<!-- ... -->` で書き直すこと。
|
||||
|
||||
## 🟡 Major
|
||||
- ...
|
||||
|
||||
## 🔵 Minor
|
||||
- ...
|
||||
```
|
||||
|
||||
問題のないチェック項目には触れない。全項目クリアなら `✅ レビュー観点上の指摘なし` と短く返す。
|
||||
|
||||
## 参照
|
||||
|
||||
- [.claude/skills/add-mk-component/SKILL.md](../skills/add-mk-component/SKILL.md) — 実装側の規約 (本エージェントの根拠)
|
||||
- [.claude/skills/add-i18n-key/SKILL.md](../skills/add-i18n-key/SKILL.md) — i18n キー追加のルール
|
||||
- [os.ts](../../packages/frontend/src/os.ts) — UI 操作 API
|
||||
- [MkButton.vue](../../packages/frontend/src/components/MkButton.vue)
|
||||
- [MkInput.vue](../../packages/frontend/src/components/MkInput.vue) — generic SFC 例
|
||||
- [MkButton.stories.impl.ts](../../packages/frontend/src/components/MkButton.stories.impl.ts) — Storybook 雛形
|
||||
- [AGENTS.md](../../AGENTS.md) — SPDX / locales 編集制限 / CHANGELOG 書式などの最低限ルール (Codex / Copilot と共通)
|
||||
@@ -1,38 +0,0 @@
|
||||
# `.claude/commands/` — プロジェクト固有のスラッシュコマンド
|
||||
|
||||
Misskey 開発で繰り返し使うワークフローを `/command-name` で呼び出せるよう、`.claude/commands/<name>.md` 形式で配置している。
|
||||
|
||||
## 実装済みコマンド
|
||||
|
||||
### Misskey オリジナル
|
||||
|
||||
| コマンド | 用途 | 典型ユースケース |
|
||||
| --- | --- | --- |
|
||||
| [`/check-misskey-js`](./check-misskey-js.md) | `pnpm build-misskey-js-with-types` を走らせ、`packages/misskey-js/src/autogen/` の差分を報告 | backend の API endpoint を追加・変更した直後 |
|
||||
| [`/changelog-add`](./changelog-add.md) | `CHANGELOG.md` の `## Unreleased` 配下、対応するサブセクションに 1 行追記 | ユーザー影響のある変更をコミットする直前 |
|
||||
| [`/migrate-new`](./migrate-new.md) | TypeORM `migration:create` の薄いラッパー (拡張子変換 + SPDX 付与 + `check-migrations` で pending DDL 検出) | 手書き SQL / データ移行用に空雛形が欲しい時 |
|
||||
|
||||
### ECC ([everything-claude-code](https://github.com/affaan-m/everything-claude-code)) 由来 (MIT)
|
||||
|
||||
ECC の MIT ライセンスファイルを Misskey の規約に合わせて再構成したもの。出典は [.claude/THIRD_PARTY_LICENSES.md](../THIRD_PARTY_LICENSES.md) を参照。
|
||||
|
||||
| コマンド | 用途 | 典型ユースケース |
|
||||
| --- | --- | --- |
|
||||
| [`/quality-gate`](./quality-gate.md) | `pnpm lint` + 各パッケージの unit test を順次実行する軽量品質ゲート | 完了前の軽量チェック (重い E2E は CI 側に委譲) |
|
||||
| [`/harness-audit`](./harness-audit.md) | `.claude/` ハーネスを 7 カテゴリで採点し改善優先度を提示 | 設定の点検 / 新しい skill / agent / hook を入れた後 |
|
||||
|
||||
## 使い分け
|
||||
|
||||
- **`/migrate-new` vs [`create-migration` skill](../skills/create-migration/SKILL.md)**:
|
||||
- 雛形だけ素早く欲しい → `/migrate-new`
|
||||
- エンティティ差分から自動生成、または CONCURRENTLY などの注意点を含めて完全に誘導してほしい → `create-migration` skill (`migration:generate`)
|
||||
- **`/changelog-add` vs 手動編集**:
|
||||
- サブセクションの placeholder `-` 置換や、過去リリースセクションへの誤編集を避けるため、原則コマンドを使う。
|
||||
- **`/quality-gate` のスコープ**:
|
||||
- 編集途中の軽量チェック (lint + unit test) は `/quality-gate` で十分。重い e2e / federation / Cypress は CI 側で実行されるため、ローカルでは原則回さない。
|
||||
|
||||
## 新規追加時の方針
|
||||
|
||||
- 既存の `superpowers` / `pr-review-toolkit` などのプラグイン提供スラッシュコマンドで足りる場合は新規追加しない。
|
||||
- frontmatter には最低限 `description` を指定し、引数を取るなら `argument-hint`、可能なら `allowed-tools` も指定する (permission prompt を最小化するため)。
|
||||
- 長時間ビルド (2 分超) を伴うコマンドはインライン `` !`<cmd>` `` を使わず、本文で `Bash` ツール呼び出し時の `timeout` を指示する。
|
||||
@@ -1,49 +0,0 @@
|
||||
---
|
||||
description: CHANGELOG.md の Unreleased セクションに 1 行追記する
|
||||
argument-hint: <general|client|server> <Prefix>: <description>
|
||||
allowed-tools: Bash(awk:*), Bash(git diff:*), Read, Edit
|
||||
---
|
||||
|
||||
## 引数
|
||||
|
||||
引数: `$ARGUMENTS`
|
||||
|
||||
## 現在の Unreleased セクション
|
||||
|
||||
!`awk '/^## Unreleased/,/^## [0-9]/' CHANGELOG.md`
|
||||
|
||||
## タスク
|
||||
|
||||
1. **引数の解析**
|
||||
`$ARGUMENTS` を以下の形式として解釈する:
|
||||
- 第 1 トークン: scope = `general` / `client` / `server` のいずれか (case-insensitive)
|
||||
- 残り: エントリ本文。`Enhance:` / `Fix:` / `Feat:` のいずれかで始まる前提
|
||||
- 不正な scope や、Prefix が見当たらない場合はエラー終了し、ユーザーに `argument-hint` の書式を提示する
|
||||
|
||||
scope は次のように見出しに変換する: `general` → `### General` / `client` → `### Client` / `server` → `### Server`。
|
||||
|
||||
2. **対象サブセクションの状態判定**
|
||||
上の context (現在の Unreleased セクション) を見て、対象サブセクションが以下のどちらかを判定する:
|
||||
- **空 (placeholder のみ)**: 見出し直下に `-` 単独行のみがある状態
|
||||
- **既存エントリあり**: `- Enhance: ...` / `- Fix: ...` / `- Feat: ...` の行が 1 つ以上ある状態
|
||||
|
||||
3. **CHANGELOG.md の編集**
|
||||
`Read` で CHANGELOG.md 全体を確認した後、`Edit` ツールで以下のように更新する:
|
||||
|
||||
- **空の場合**: 該当サブセクションの placeholder `-` 行を `- <整形済みエントリ>` で置換する。例: `### General\n-\n` → `### General\n- Enhance: 新しい機能\n`
|
||||
- **既存ありの場合**: 既存エントリ群の **末尾** (次の空行直前) に新エントリを **append** する。順序入れ替えはしない。
|
||||
|
||||
`Edit` の `old_string` には、置換対象のサブセクション付近のユニークな文脈 (見出し + 直後の数行) を含め、誤マッチを防ぐ。
|
||||
|
||||
4. **不可侵の徹底**
|
||||
- `## Unreleased` 以下の対象サブセクションのみ編集する。
|
||||
- `## 2026.x.x` 以下の過去リリースセクションは絶対に変更しない ([AGENTS.md §CHANGELOG](../../AGENTS.md#changelog) 参照)。
|
||||
|
||||
5. **結果確認**
|
||||
`git diff CHANGELOG.md` を実行し、想定通り 1 行のみ追加されていることを表示して、ユーザーに確認させる。
|
||||
|
||||
## 例
|
||||
|
||||
- `/changelog-add server Fix: 通知が遅延する問題を修正` → `### Server` 末尾に追記
|
||||
- `/changelog-add client Enhance: ノートの表示を改善` → `### Client` 末尾に追記
|
||||
- `/changelog-add general Feat: 新機能の追加` → `### General` 末尾に追記 (placeholder 置換)
|
||||
@@ -1,42 +0,0 @@
|
||||
---
|
||||
description: backend の API 変更後に misskey-js を再生成し、生成物の差分を報告する
|
||||
allowed-tools: Bash(pnpm build-misskey-js-with-types:*), Bash(git status:*), Bash(git diff:*), Bash(git branch:*)
|
||||
---
|
||||
|
||||
## 概要
|
||||
|
||||
backend の API endpoint やスキーマを変更した後、`packages/misskey-js/src/autogen/` の自動生成型を最新化するためのコマンド。内部で `pnpm build-misskey-js-with-types` (backend build → `api.json` 生成 → misskey-js 型生成 → ビルド → API extractor) を一括実行する。
|
||||
|
||||
## 現在の状態 (再生成前)
|
||||
|
||||
- 現ブランチ: !`git branch --show-current`
|
||||
- 既存の misskey-js 関連変更: !`git status --short -- packages/misskey-js/`
|
||||
|
||||
## タスク
|
||||
|
||||
以下の手順を順番に実行してください。
|
||||
|
||||
1. **再生成の実行**
|
||||
`Bash` ツールで以下のコマンドを `timeout: 600000` (10 分) を指定して実行する。内部で backend ビルドと型再生成を行うため、デフォルトの 2 分タイムアウトでは不足する。
|
||||
|
||||
```bash
|
||||
pnpm build-misskey-js-with-types
|
||||
```
|
||||
|
||||
2. **差分の確認**
|
||||
完了後、以下を実行して `packages/misskey-js/src/autogen/` の差分を確認する (`built/` は `.gitignore` 対象なので追跡対象外):
|
||||
|
||||
```bash
|
||||
git status --short -- packages/misskey-js/
|
||||
git diff --stat -- packages/misskey-js/src/autogen/
|
||||
```
|
||||
|
||||
3. **結果報告**
|
||||
- **差分なし** → 「backend の変更は misskey-js の公開型に影響していません」と報告する。追加コミットは不要。
|
||||
- **差分あり** → 変更ファイル一覧をユーザーに示し、`git add packages/misskey-js/src/autogen/` で再生成物もコミット対象に含めるよう案内する。`api.json` の差分が大きい場合は、API endpoint 側の `meta` / `paramDef` / `res` 定義を確認するよう促す。
|
||||
|
||||
## 注意
|
||||
|
||||
- このコマンドは **backend 編集後の確認** が目的。backend を変更していないのに走らせると、ビルドキャッシュ次第で no-op になる。
|
||||
- 実行中は `packages/backend/built/` や `packages/misskey-js/built/` などの中間生成物が更新されるが、これらは `.gitignore` 対象。
|
||||
- 生成物以外 (`packages/misskey-js/src/` のうち `autogen/` 以外) に予期せぬ差分が出た場合は、ローカルの編集が混入している可能性があるため、一旦中止して原因を調査する。
|
||||
@@ -1,146 +0,0 @@
|
||||
---
|
||||
description: Misskey の .claude/ ハーネス (skills/agents/commands) を 7 カテゴリで採点する確定的な監査。
|
||||
argument-hint: "[repo|skills|commands|agents]"
|
||||
---
|
||||
|
||||
<!--
|
||||
SPDX-License-Identifier: MIT
|
||||
SPDX-FileCopyrightText: 2026 Affaan Mustafa and everything-claude-code contributors
|
||||
|
||||
出典 (upstream): https://github.com/affaan-m/everything-claude-code (v2.0.0-rc.1)
|
||||
upstream path: commands/harness-audit.md
|
||||
upstream license: MIT — https://github.com/affaan-m/everything-claude-code/blob/main/LICENSE
|
||||
project-level notice: see .claude/THIRD_PARTY_LICENSES.md (Misskey 内サードパーティ一覧 + MIT 全文)
|
||||
|
||||
Imported into Misskey .claude/ on 2026-05-10. The 7-category rubric and output contract are derived from the upstream ECC version (MIT). The runtime layer was substantially reimplemented for Misskey: the upstream relies on scripts/harness-audit.js to mechanically score, while this version asks Claude to score directly with pnpm/git/grep, and adds Misskey-specific evaluation axes (SPDX coverage / endpoint-list 登録漏れ / migration 順序 / ja-JP.yml 整合).
|
||||
|
||||
note: 元 ECC 版は scripts/harness-audit.js (専用 Node スクリプト) で機械採点していたが、Misskey は ECC plugin runtime に依存しない方針なので、Claude が直接ファイルを読んで採点する手動運用版に書き換えた。Misskey 固有の重要観点 (SPDX 適用率 / endpoint-list 登録漏れ / migration 順序 / ja-JP.yml 整合) を評価軸として明示的に組み込んでいる。
|
||||
-->
|
||||
|
||||
# /harness-audit — Misskey ハーネス監査
|
||||
|
||||
Misskey リポジトリの `.claude/` 構成を 7 カテゴリで採点し、改善優先度を提示する。
|
||||
|
||||
## Usage
|
||||
|
||||
`/harness-audit [scope]`
|
||||
|
||||
- `scope` (任意): `repo` (default) / `skills` / `commands` / `agents`
|
||||
|
||||
## 評価カテゴリ (各 0-10)
|
||||
|
||||
| # | カテゴリ | 評価軸 |
|
||||
| --- | --- | --- |
|
||||
| 1 | Tool Coverage | skill / agent / command の数、欠けているワークフロー段、重複なし |
|
||||
| 2 | Context Efficiency | frontmatter description の冗長度、SKILL.md の長さ分布、重複情報、CLAUDE.md の肥大化 |
|
||||
| 3 | Quality Gates | Stop / PreToolUse / PostToolUse hook の整備、`/quality-gate` 等の完了前ゲートの有無、自動 lint/typecheck |
|
||||
| 4 | Memory Persistence | docs/* の同期状態を評価。プロジェクト側 `.claude/memory/` は未採用方針 (auto-memory はユーザーホーム側で自動運用) のため、ここを採点起点にせず既定 5/10 から開始する |
|
||||
| 5 | Eval Coverage | testing.md の網羅、Misskey 固有の e2e/fed/Storybook/Cypress 適用ガイド |
|
||||
| 6 | Security Guardrails | SPDX 規約適用、migration 不変性ルール、ja-JP.yml 限定編集ルール、secrets 検出 |
|
||||
| 7 | Cost Efficiency | enabledPlugins の重複・過剰、context-budget の整備、MCP 過剰登録なし |
|
||||
|
||||
## Misskey 固有の確認項目 (採点根拠コマンド)
|
||||
|
||||
採点時に以下を実コマンドで確認する。各項目の **属するカテゴリ** は項目内に明記する (#1-#3 は Security Guardrails、#4 は Tool Coverage、#5 は Quality Gates):
|
||||
|
||||
```bash
|
||||
# 1. [Security Guardrails] SPDX 適用率 (新規ファイル想定の汎用チェック)
|
||||
# - node_modules を prune で除外
|
||||
# - packages/misskey-js は MIT サブパッケージなので AGPL ヘッダーを持たない (AGENTS.md §1) → 除外
|
||||
# - built/ なども除外
|
||||
# 候補にはなお *.config.{ts,js} / *eslint* / *.d.ts のような CI 上 SPDX 対象外
|
||||
# (.github/workflows/check-spdx-license-id.yml の exclude 参照) も混ざるため、
|
||||
# 上位に出たファイルが「新規追加した実コード」かどうかは目視判定する。
|
||||
find packages \
|
||||
\( -type d \( -name node_modules -o -name built -o -name dist -o -path 'packages/misskey-js' \) -prune \) \
|
||||
-o -type f \( -name '*.ts' -o -name '*.js' -o -name '*.vue' -o -name '*.scss' \) -print \
|
||||
| xargs -r grep -L 'SPDX-License-Identifier: AGPL-3.0-only' | head -20
|
||||
# → 上位に新規実コードが無ければ満点
|
||||
|
||||
# 2. [Security Guardrails] ja-JP.yml 以外の locales が直近で手動編集されていないか
|
||||
# --pretty=format: でコミットヘッダ行を抑止し、ファイル名行のみを残してから grep する。
|
||||
# Crowdin の自動同期 commit でも他言語 yml は更新されるため、出力が 0 行になることは少ない。
|
||||
# 出力があった場合は、author / commit message を確認し Crowdin 由来か手動編集かを判定する:
|
||||
# git log --since='30 days ago' --pretty=format:'%h %an %s' -- locales/<file>.yml
|
||||
git log --since='30 days ago' --pretty=format: --name-only -- 'locales/*.yml' \
|
||||
| grep -v '^$' | grep -v 'ja-JP.yml' | sort -u
|
||||
# → 出力が無い、または全て Crowdin 由来 commit なら満点
|
||||
|
||||
# 3. [Security Guardrails] migration の pending DDL 検査 (TypeORM schema builder)
|
||||
pnpm --filter backend check-migrations
|
||||
# → 0 errors (= "All migrations are clean.") なら満点
|
||||
|
||||
# 4. [Tool Coverage] endpoint-list.ts 登録漏れ (新規 endpoint がリストにない場合)
|
||||
# endpoints/ は再帰構造 (notes/create.ts, admin/announcements/create.ts 等) で 400+ ファイルあるため、
|
||||
# endpoint-list.ts も `export * as '<category>/<name>' from './endpoints/<category>/<name>.js';` 形式で
|
||||
# 1 ファイル 1 行登録される。両者の行数を「再帰 .ts 数」と「export * as 行数」で比較する。
|
||||
# e2e / 単体テストは endpoint ではないので *.test.ts を除外する。
|
||||
endpoint_files=$(find packages/backend/src/server/api/endpoints -type f -name '*.ts' ! -name '*.test.ts' | wc -l)
|
||||
list_entries=$(grep -cE "^export \* as " packages/backend/src/server/api/endpoint-list.ts)
|
||||
echo "endpoints (recursive): $endpoint_files / endpoint-list.ts entries: $list_entries"
|
||||
# 差分が 0 なら満点。差分が出たら、登録漏れの具体特定:
|
||||
comm -23 \
|
||||
<(find packages/backend/src/server/api/endpoints -type f -name '*.ts' ! -name '*.test.ts' \
|
||||
| sed -E 's|.*/endpoints/||;s|\.ts$||' | sort -u) \
|
||||
<(grep -oE "^export \* as '[^']+'" packages/backend/src/server/api/endpoint-list.ts \
|
||||
| sed -E "s/^export \* as '([^']+)'/\1/" | sort -u)
|
||||
# 出力された行が登録漏れの endpoint。0 行なら満点。
|
||||
|
||||
# 5. [Quality Gates] console.log の混入
|
||||
grep -rn 'console\.\(log\|debug\)' packages/backend/src packages/frontend/src 2>/dev/null \
|
||||
| grep -v 'node_modules\|test\|.spec\.\|.test\.' | wc -l
|
||||
# → 0 が理想
|
||||
```
|
||||
|
||||
## 出力契約
|
||||
|
||||
以下を返す:
|
||||
|
||||
1. `overall_score` / `max_score` (repo は 70 点満点)
|
||||
2. カテゴリごとのスコア + 具体的な根拠
|
||||
3. 失敗チェック項目と該当ファイルパス
|
||||
4. Top 3 改善アクション
|
||||
5. 次に適用を推奨する skill / 手順
|
||||
|
||||
## サンプル出力
|
||||
|
||||
```text
|
||||
Harness Audit (repo): 55/70
|
||||
|
||||
Tool Coverage: 9/10 (skills 5, agents 2, commands 5 — 偏りなし)
|
||||
Context Efficiency: 8/10 (description 平均 3-5 行、肥大なし)
|
||||
Quality Gates: 5/10 (Stop hook 共有設定に未登録 / `/quality-gate` あり)
|
||||
Memory Persistence: 5/10 (プロジェクト側 memory/ 未採用方針 = 既定値)
|
||||
Eval Coverage: 7/10 (testing.md 網羅、Storybook 一部抜け)
|
||||
Security Guardrails: 10/10 (SPDX 100%, locales OK, migrations clean)
|
||||
Cost Efficiency: 8/10 (context-budget 導入済 / MCP 0)
|
||||
|
||||
Failed Checks:
|
||||
- packages/frontend/src/.../X.vue で SPDX 欠落 (Security Guardrails)
|
||||
- console.log が backend に 3 件 (Quality Gates)
|
||||
- 共有 Stop hook なし (Quality Gates) — 各 contributor が `.claude/settings.local.json` で opt-in する方針なら減点しなくて良い
|
||||
|
||||
Top 3 Actions:
|
||||
1) [Security Guardrails] SPDX 欠落 1 ファイルを修正:
|
||||
packages/frontend/src/.../X.vue
|
||||
2) [Quality Gates] backend の console.log 3 件を logger に置換。
|
||||
git grep "console\.log" packages/backend/src
|
||||
3) [Cost Efficiency] enabledPlugins から未使用のものを外す。
|
||||
.claude/docs/plugins.md と照合。
|
||||
|
||||
Suggested next skills to apply:
|
||||
- /quality-gate で完了前に lint + unit test を回す
|
||||
- context-budget で plugin 由来の overhead を確認
|
||||
```
|
||||
|
||||
## 採点の信頼性
|
||||
|
||||
- 確定的: 同じ commit / 同じ `.claude/` 構成なら同じスコア
|
||||
- ヒューリスティクス: 「description の冗長度」のような主観項目は同一基準で機械的に判定
|
||||
- スクリプト不要: `pnpm` と `git`、`grep`/`find` 等の標準ツールのみ
|
||||
|
||||
## 参考: ECC オリジナルとの差分
|
||||
|
||||
- ECC 版は `node scripts/harness-audit.js` を直叩きする運用で、ECC リポジトリ全体に閉じた採点だった。
|
||||
- Misskey 版は **Misskey の規約 (SPDX/migration/locales/endpoint-list)** を Security 採点に組み込み、`pnpm` ベースの実コマンドで根拠を取る方式に再設計。
|
||||
- 結果として ECC への依存はゼロ。
|
||||
@@ -1,81 +0,0 @@
|
||||
---
|
||||
description: TypeORM migration の空雛形を生成する。スキーマ差分から自動生成したい時は create-migration skill を使うこと
|
||||
argument-hint: <PascalCaseName>
|
||||
allowed-tools: Bash(pnpm:*), Bash(ls:*), Bash(test:*), Bash(head:*), Read, Edit
|
||||
---
|
||||
|
||||
## 引数
|
||||
|
||||
引数: `$ARGUMENTS`
|
||||
|
||||
## タスク
|
||||
|
||||
1. **PascalCaseName の検証**
|
||||
`$ARGUMENTS` が `^[A-Z][A-Za-z0-9]+$` に一致するか確認する。一致しない場合はエラー終了し、`AddFooBar` / `BirthdayIndex` のような形式を案内する。
|
||||
|
||||
2. **既存ファイルの存在確認**
|
||||
|
||||
```bash
|
||||
ls packages/backend/migration/*$ARGUMENTS.{js,ts} 2>/dev/null
|
||||
```
|
||||
|
||||
既に同名 (タイムスタンプ違い) のファイルが存在する場合、上書きせずユーザーに別名を促す。
|
||||
|
||||
3. **TypeORM 公式 CLI で空雛形を生成 (`-o --esm` 必須)**
|
||||
`create-migration` skill の方針に従い、`Date.now()` を手書きするのではなく TypeORM CLI を使う。`-o --esm` で **最初から JS(ESM) を生成** させ、後続の `.ts → .js` 変換や `import { MigrationInterface }` 削除といった TS 固有構文の除去を不要にする (`-o --esm` を付けないと `.ts` + CommonJS / `implements MigrationInterface` 付きで生成され、Misskey の `ormconfig.js` (`migration/*.js` のみロード) と既存 migration スタイルに合わない):
|
||||
|
||||
```bash
|
||||
pnpm --filter backend exec typeorm migration:create -o --esm migration/$ARGUMENTS
|
||||
```
|
||||
|
||||
出力: `packages/backend/migration/<UnixMs>-<PascalCaseName>.js`
|
||||
|
||||
4. **生成ファイルパスの取得**
|
||||
後続ステップで使うパスを変数に受ける (`<ms>` を手書きしない):
|
||||
|
||||
```bash
|
||||
dst=$(ls -t packages/backend/migration/*$ARGUMENTS.js | head -1)
|
||||
```
|
||||
|
||||
以降のステップでは `$dst` を編集対象として扱う。完成後の典型的な形は次のようになる (参考: [packages/backend/migration/1767169026317-birthday-index.js](../../packages/backend/migration/1767169026317-birthday-index.js)):
|
||||
|
||||
```js
|
||||
export class <PascalCaseName><ms> {
|
||||
name = '<PascalCaseName><ms>'
|
||||
|
||||
async up(queryRunner) {
|
||||
}
|
||||
|
||||
async down(queryRunner) {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
5. **SPDX ヘッダーの追加**
|
||||
`Edit` ツールで、ファイル冒頭に以下を挿入する。CI の `spdx` ジョブが失敗するため必須:
|
||||
|
||||
```js
|
||||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
```
|
||||
|
||||
6. **migration の pending DDL 検査**
|
||||
|
||||
```bash
|
||||
pnpm --filter backend check-migrations
|
||||
```
|
||||
|
||||
TypeORM schema builder で pending DDL を検出する検査 ([scripts/check_migrations_clean.js](../../packages/backend/scripts/check_migrations_clean.js))。空雛形を作っただけの段階ではエンティティ差分との不整合が残る場合があるため、`up`/`down` を埋めた後にも再実行して 0 件になるか確認する。
|
||||
|
||||
7. **結果報告**
|
||||
- 生成ファイルパスを示す。
|
||||
- `up()` / `down()` の中身が空であることを伝え、SQL を書く必要があると案内する。
|
||||
- `down()` を空のまま放置すると本番ロールバック時に詰むため、必ず `up` の完全な巻き戻しを実装するよう促す。
|
||||
- 詳細な手順 (`migration:generate` を使うべきケース、CONCURRENTLY などの注意点) は `create-migration` skill を参照するよう案内する。
|
||||
|
||||
## 注意
|
||||
|
||||
- このコマンドは **空雛形を素早く出して手書きする** 用途。エンティティ (`packages/backend/src/models/*.ts`) を変更した差分から SQL を自動生成したい場合は、このコマンドではなく `create-migration` skill 経由で `migration:generate` を使うこと。
|
||||
- マージ済み migration ファイルは絶対に編集しない ([AGENTS.md §3](../../AGENTS.md#3-マージ済み-migration-を絶対に編集しない))。
|
||||
@@ -1,122 +0,0 @@
|
||||
---
|
||||
description: Misskey の lint / typecheck / 高速テストを順に実行して品質ゲートを通すコマンド。完了前の軽量検証用。
|
||||
argument-hint: "[repo|backend|frontend|<path/to/file.ts>]"
|
||||
---
|
||||
|
||||
<!--
|
||||
SPDX-License-Identifier: MIT
|
||||
SPDX-FileCopyrightText: 2026 Affaan Mustafa and everything-claude-code contributors
|
||||
|
||||
出典 (upstream): https://github.com/affaan-m/everything-claude-code (v2.0.0-rc.1)
|
||||
upstream path: commands/quality-gate.md
|
||||
upstream license: MIT — https://github.com/affaan-m/everything-claude-code/blob/main/LICENSE
|
||||
project-level notice: see .claude/THIRD_PARTY_LICENSES.md (Misskey 内サードパーティ一覧 + MIT 全文)
|
||||
|
||||
Imported into Misskey .claude/ on 2026-05-10. Pipeline 概念 (lint → typecheck → test) は upstream ECC 版から借用 (MIT)。実コマンド層は Misskey の pnpm + tsgo + ESLint + Vitest に固定し、formatter (Prettier/Biome) フェーズは削除した。
|
||||
|
||||
note: 元 ECC 版は言語自動判定 + format/lint/type のジェネリック版だったが、Misskey 専用に pnpm + tsgo + ESLint + Vitest の組み合わせに固定。重い test:e2e / test:fed は含まない (CI 側で実行される)。
|
||||
-->
|
||||
|
||||
# /quality-gate — Misskey 軽量品質ゲート
|
||||
|
||||
`/quality-gate [scope]`
|
||||
|
||||
完了前の **軽量** 品質チェック。重い E2E / 連合テスト (test:e2e / test:fed / Cypress) は CI 側で実行されるため、本コマンドには含めない。
|
||||
|
||||
## Scope
|
||||
|
||||
- `repo` (default) — 全パッケージ
|
||||
- `backend` — `packages/backend` のみ
|
||||
- `frontend` — `packages/frontend` のみ
|
||||
- `path/to/file.ts` — 単一ファイルへの ESLint --fix のみ
|
||||
|
||||
## Pipeline
|
||||
|
||||
### Repo scope (全部)
|
||||
|
||||
各パッケージの `lint` スクリプト実体は `pnpm typecheck && pnpm eslint` ([packages/backend/package.json](../../packages/backend/package.json), [packages/frontend/package.json](../../packages/frontend/package.json)) で、ルートの `pnpm lint` は `pnpm --no-bail -r lint` (= 全パッケージで lint を `--no-bail` で実行)。**typecheck は lint に含まれている**ため、通常はこの 2 コマンドで十分:
|
||||
|
||||
```bash
|
||||
# 1. Lint (= typecheck + ESLint、全パッケージ。--no-bail で最初の失敗で止まらず全結果を集める)
|
||||
pnpm lint
|
||||
|
||||
# 2. Unit test (高速、e2e は含まない)
|
||||
pnpm --filter backend test
|
||||
pnpm --filter frontend test
|
||||
```
|
||||
|
||||
#### 詳細を分けて見たい時のみ (optional)
|
||||
|
||||
lint がまとめて失敗していて typecheck の結果だけ単独で見たい場合は、以下を個別に回す。**通常は不要** (lint の出力を読めば足りる):
|
||||
|
||||
```bash
|
||||
pnpm --filter backend typecheck # tsgo 単体
|
||||
pnpm --filter frontend typecheck # vue-tsc 単体 (Vue SFC の型を見るため)
|
||||
```
|
||||
|
||||
### Backend scope
|
||||
|
||||
`pnpm --filter backend lint` は内部で `pnpm typecheck && pnpm eslint` を実行する ([packages/backend/package.json](../../packages/backend/package.json)) ので、`lint` を回せば typecheck も終わる。軽量ゲートでは typecheck の二重実行を避けるため `lint` + `test` のみ:
|
||||
|
||||
```bash
|
||||
pnpm --filter backend lint
|
||||
pnpm --filter backend test
|
||||
```
|
||||
|
||||
`tsgo` の出力を単独で見たい時のみ optional で `pnpm --filter backend typecheck` を別途回す。
|
||||
|
||||
### Frontend scope
|
||||
|
||||
`pnpm --filter frontend lint` も内部で `pnpm typecheck && pnpm eslint` を実行する ([packages/frontend/package.json](../../packages/frontend/package.json)) ため、軽量ゲートでは Backend 同様に `lint` + `test` のみ:
|
||||
|
||||
```bash
|
||||
pnpm --filter frontend lint
|
||||
pnpm --filter frontend test
|
||||
```
|
||||
|
||||
`vue-tsc` の出力を単独で見たい時のみ optional で `pnpm --filter frontend typecheck` を別途回す。
|
||||
|
||||
### Single file scope
|
||||
|
||||
```bash
|
||||
pnpm exec eslint --fix <path>
|
||||
```
|
||||
|
||||
## Output
|
||||
|
||||
実行したフェーズの pass/fail と件数を集計する。標準パイプラインは `pnpm lint` (typecheck 内包) と unit test のみなので、デフォルトの出力は以下のようになる:
|
||||
|
||||
```text
|
||||
Quality Gate (repo):
|
||||
|
||||
Lint: PASS (0 errors, 2 warnings)
|
||||
Backend ut: PASS (412/412)
|
||||
Frontend ut: PASS (87/87)
|
||||
|
||||
→ 完了前の軽量チェック OK。重い e2e / 連合テストは CI 側で実行される。
|
||||
```
|
||||
|
||||
`#### 詳細を分けて見たい時のみ (optional)` で個別 typecheck (`pnpm --filter backend typecheck` / `pnpm --filter frontend typecheck`) も回した場合のみ、その結果を追加行として表示する:
|
||||
|
||||
```text
|
||||
Quality Gate (repo):
|
||||
|
||||
Lint: PASS (0 errors, 2 warnings)
|
||||
Backend tc: PASS (0 errors) # optional 実行時のみ
|
||||
Frontend tc: PASS (0 errors) # optional 実行時のみ
|
||||
Backend ut: PASS (412/412)
|
||||
Frontend ut: PASS (87/87)
|
||||
```
|
||||
|
||||
失敗時は最初に落ちたフェーズで停止して詳細を見せる。
|
||||
|
||||
## 関連 skill / コマンド
|
||||
|
||||
- `/check-misskey-js` コマンド — API 変更時の misskey-js 再生成
|
||||
- [AGENTS.md §必須コマンド](../../AGENTS.md#必須コマンド) — pnpm コマンド一覧の正典
|
||||
|
||||
## 元 ECC 版との差分
|
||||
|
||||
- ジェネリックな言語自動判定を排除し、Misskey 固定 pipeline に。
|
||||
- formatter フェーズなし (Misskey は ESLint --fix のみ採用)。
|
||||
- e2e / federation / Cypress は重いため除外し CI 側に委譲。
|
||||
@@ -1,18 +0,0 @@
|
||||
# Misskey – Claude Code 補助ドキュメント
|
||||
|
||||
ルート `CLAUDE.md` には書かれていないが、開発時に参照すると便利な情報を分野別にまとめている。**Claude は必要になったタイミングで該当ファイルを Read すれば良い** (auto-load しない)。
|
||||
|
||||
## 索引
|
||||
|
||||
| ファイル | いつ読むか |
|
||||
|---|---|
|
||||
| [architecture.md](./architecture.md) | パッケージ構成・ビルド構造を把握したい時 / 新パッケージを跨ぐ変更を計画する時 |
|
||||
| [backend.md](./backend.md) | `packages/backend` を編集する時 (NestJS / TypeORM / API endpoint / migration) |
|
||||
| [frontend.md](./frontend.md) | `packages/frontend` を編集する時 (Vue 3 / Mk* / i18n / SCSS Modules / `os.ts`) |
|
||||
| [testing.md](./testing.md) | テストを書く・走らせる時 (Vitest 構成、Cypress、Storybook) |
|
||||
| [plugins.md](./plugins.md) | 有効化済の Claude Code プラグインの用途を確認したい時 |
|
||||
|
||||
## 補足: ルール vs ドキュメント
|
||||
|
||||
- 事故直結ルール (SPDX / locales / migration) と必須コマンド・CHANGELOG 書式は、リポジトリルートの [AGENTS.md](../../AGENTS.md) に集約されている。Claude Code は CLAUDE.md からの `@AGENTS.md` で常時コンテキストに乗せる。Codex / Copilot も同じファイルを読む。
|
||||
- `.claude/docs/*.md` (このディレクトリ) は **オンデマンド参照**。Claude が「知っておいた方が良いが常に持つ必要はない」内容をここに置く。
|
||||
@@ -1,47 +0,0 @@
|
||||
# アーキテクチャ概要
|
||||
|
||||
## モノレポ構成 (pnpm workspaces)
|
||||
|
||||
pnpm workspace の正は [pnpm-workspace.yaml](../../pnpm-workspace.yaml) で、以下 11 パッケージと、`packages/misskey-js` 内の sub-workspace `packages/misskey-js/generator` (型生成用の内部ジェネレータ。直接編集しない) で構成される。`package.json` の `workspaces` 配列も併記しているが、実体は pnpm-workspace.yaml が読まれる:
|
||||
|
||||
| パッケージ | 役割 |
|
||||
|---|---|
|
||||
| `packages/backend` | NestJS 11 + Fastify 5 + TypeORM 0.3 (PostgreSQL) + Redis。HTTP/WebSocket/ActivityPub サーバー本体。 |
|
||||
| `packages/frontend` | Vue 3.5 + Vite。Web クライアント本体。 |
|
||||
| `packages/frontend-embed` | 埋め込み専用ビュー (ノート単体プレビュー等)。 |
|
||||
| `packages/frontend-shared` | frontend と frontend-embed で共有するユーティリティ・コンポーネント。 |
|
||||
| `packages/frontend-builder` | フロントエンドビルド支援 (Vite plugin など)。 |
|
||||
| `packages/sw` | Service Worker。 |
|
||||
| `packages/misskey-js` | JS/TS クライアント SDK (MIT サブパッケージ)。`src/autogen/` 配下のみ backend の OpenAPI から `pnpm build-misskey-js-with-types` で自動生成され、それ以外 (`src/index.ts` / `src/api.ts` 等) は手書き保守する。autogen 配下を直接編集しないこと。 |
|
||||
| `packages/misskey-reversi` | 内蔵リバーシゲームのロジック。 |
|
||||
| `packages/misskey-bubble-game` | 内蔵バブルゲームのロジック。 |
|
||||
| `packages/i18n` | locales 読み込み/型生成のサポート。 |
|
||||
| `packages/icons-subsetter` | アイコンのサブセット化ツール。 |
|
||||
|
||||
その他に `packages/shared` (workspaces には含まれないが共有ファイル置き場) もある。
|
||||
|
||||
## 重要な依存関係
|
||||
|
||||
```
|
||||
frontend ── misskey-js (auto-generated) ── backend (OpenAPI)
|
||||
▲
|
||||
└── frontend-embed, sw も依存
|
||||
```
|
||||
|
||||
- backend の API (meta / paramDef / response) を変更したら **必ず** `pnpm build-misskey-js-with-types` を実行し、misskey-js の生成物を更新する。忘れると CI の `check-misskey-js-autogen` ジョブが落ちる。
|
||||
|
||||
## ビルドツール
|
||||
|
||||
- **Backend**: `rolldown` (Rust 製・Rollup 互換 API のバンドラ) でバンドル。型チェックは `tsgo` (TypeScript native preview)。
|
||||
- **Frontend**: Vite。型チェックは `vue-tsc`。
|
||||
- **Lint**: ESLint 9 (Flat Config) + `@misskey-dev/eslint-plugin`。
|
||||
|
||||
## 国際化
|
||||
|
||||
- `locales/` 直下に 40 言語の YAML (ja-JP.yml + 他 39 言語)。
|
||||
- **`ja-JP.yml` のみ手動編集可** (Crowdin 経由で他言語へ自動配信)。
|
||||
- フロントエンドからの参照は引数なしか引数ありかで使い分ける。詳細は [frontend.md](./frontend.md#国際化-i18n)。
|
||||
|
||||
## ライセンス
|
||||
|
||||
リポジトリ本体は AGPL-3.0-only。**AGPL-3.0-only 管轄かつ SPDX CI 対象ディレクトリ** の新規 `.ts` / `.js` / `.cjs` / `.mjs` / `.vue` / `.scss` / `.html` ファイルには冒頭に SPDX ヘッダー必須。`packages/misskey-js` は MIT サブパッケージなので AGPL ヘッダーを一律に付けない。条件と除外の詳細は [AGENTS.md §1](../../AGENTS.md#1-spdx-ヘッダー必須) 参照。
|
||||
@@ -1,124 +0,0 @@
|
||||
# Backend (`packages/backend`) 規約
|
||||
|
||||
NestJS 11 + Fastify 5 + TypeORM 0.3 (PostgreSQL) + Redis。
|
||||
|
||||
## アーキテクチャ
|
||||
|
||||
- **DI コンテナ**: NestJS の `@Injectable()` サービス + Repository (TypeORM) パターン。
|
||||
- **DI トークン**: `@/di-symbols.js` の `DI` から `@Inject(DI.xxx)` で注入。
|
||||
- **ビルド**: `rolldown -c` で `built/` にバンドル。型チェックは `tsgo`。
|
||||
|
||||
## API エンドポイント
|
||||
|
||||
### 配置
|
||||
|
||||
`packages/backend/src/server/api/endpoints/<category>/<name>.ts` (一部はトップ直下)。
|
||||
|
||||
### 三点セット (`endpoints/ping.ts` 参照)
|
||||
|
||||
各エンドポイントファイルは以下の 3 つを export する:
|
||||
|
||||
```ts
|
||||
export const meta = {
|
||||
tags: ['<tag>'],
|
||||
requireCredential: true, // または false (必ず明示)
|
||||
requireModerator: false, // 必要なら true
|
||||
kind: 'read:account', // OAuth scope
|
||||
res: {
|
||||
type: 'object',
|
||||
optional: false, nullable: false,
|
||||
properties: { /* ... */ },
|
||||
},
|
||||
errors: {
|
||||
sampleError: {
|
||||
message: 'Sample error message.',
|
||||
code: 'SAMPLE_ERROR',
|
||||
id: 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx', // UUID v4 (`x`=hex, `y`=8/9/a/b)。`crypto.randomUUID()` で生成し、他エンドポイントと重複させない
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: { /* JSON Schema */ },
|
||||
required: [],
|
||||
} as const;
|
||||
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
constructor(
|
||||
// @Inject(DI.xxx) private xxxRepository: XxxRepository,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
// 実装。エラーは throw new ApiError(meta.errors.xxx);
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 注意点
|
||||
|
||||
- **公開 API エラーとしてクライアントに返したいものは `throw new ApiError(meta.errors.<key>)` を使う**。`meta.errors` に列挙して `ApiError` でラップしないと misskey-js 側の型に出ず、レスポンスも 500 になる。
|
||||
- 一方で **想定外の例外 (DB 不整合 / 下層サービスの bug 等) は握り潰さず再 throw する**。既存 endpoint も「期待される業務エラーは `ApiError` に変換し、それ以外は `throw err;` で再 throw」の二段構え (例: [`endpoints/i/pin.ts`](../../packages/backend/src/server/api/endpoints/i/pin.ts) の `catch` 節)。生 `throw` を全面禁止すると未知例外が 200 で潰れて debug 困難になる。
|
||||
- `meta.errors.<key>.id` は **UUID** 形式。新規追加時は他エンドポイントと重複しないよう確認する。
|
||||
- `requireCredential` は `true` / `false` を必ず明示する。
|
||||
- 新規エンドポイント追加後は **`pnpm build-misskey-js-with-types`** を実行する (`misskey-js` の自動生成ファイルを更新)。
|
||||
|
||||
### ルート登録
|
||||
|
||||
エンドポイントは **glob 自動収集されない**。新規ファイルを `endpoints/<category>/<name>.ts` に置いただけでは API ルーティングに乗らず、404 になる。`packages/backend/src/server/api/endpoint-list.ts` にアルファベット順で 1 行追加するのが必須:
|
||||
|
||||
```ts
|
||||
export * as '<category>/<name>' from './endpoints/<category>/<name>.js';
|
||||
```
|
||||
|
||||
`EndpointsModule.ts` がこのファイルの全エクスポートを `Object.entries()` で反復し、NestJS の provider (`provide: 'ep:<path>'`) を生成する。詳細は [.claude/skills/add-api-endpoint/SKILL.md](../skills/add-api-endpoint/SKILL.md) のステップ 4 を参照。
|
||||
|
||||
## モデル / Repository
|
||||
|
||||
- エンティティ: `packages/backend/src/models/<Name>.ts` (`@Entity` + `@Column`)。
|
||||
- DI 経由で注入される Repository を経由してアクセス。
|
||||
|
||||
## Migration
|
||||
|
||||
詳細手順 (手書き方式 = AGENTS.md §3 と整合):
|
||||
|
||||
> エンティティ差分からの自動生成や `CREATE INDEX CONCURRENTLY` 等のオプションを使いたい場合は [.claude/skills/create-migration/SKILL.md](../skills/create-migration/SKILL.md) の TypeORM CLI 手順を使う。手書き / CLI どちらでも `check-migrations` (pending DDL 検出) さえ通せば等価。
|
||||
|
||||
1. **タイムスタンプ取得**: `node -e "console.log(Date.now())"`
|
||||
2. **ファイル名**: `packages/backend/migration/{timestamp}-{PascalCaseName}.js` (拡張子は `.js`)
|
||||
3. **雛形**:
|
||||
|
||||
```js
|
||||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
export class PascalCaseName1234567890123 {
|
||||
name = 'PascalCaseName1234567890123'
|
||||
|
||||
async up(queryRunner) {
|
||||
// 前進マイグレーション
|
||||
}
|
||||
|
||||
async down(queryRunner) {
|
||||
// up を完全に巻き戻す
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
4. **検証**:
|
||||
- `pnpm --filter backend check-migrations` (TypeORM schema builder で pending DDL を検出する。エンティティと migration の不一致が残っているとここで非ゼロ終了する。実体は [scripts/check_migrations_clean.js](../../packages/backend/scripts/check_migrations_clean.js))
|
||||
- `pnpm migrate` (ローカル DB に適用)
|
||||
- `pnpm revert` (ロールバック確認)
|
||||
5. **エンティティとの整合性**: 関連する `src/models/*.ts` の `@Column` / `@Entity` も同時に更新する。
|
||||
|
||||
> マージ済み migration の編集は **絶対禁止** ([AGENTS.md §3](../../AGENTS.md#3-マージ済み-migration-を絶対に編集しない))。
|
||||
|
||||
## テスト
|
||||
|
||||
- Unit: `pnpm --filter backend test` (`vitest.config.unit.ts`)
|
||||
- E2E: `pnpm --filter backend test:e2e` (`vitest.config.e2e.ts`)
|
||||
- Federation: `pnpm --filter backend test:fed` (`vitest.config.fed.ts`)
|
||||
- 配置: `packages/backend/test/` 配下。
|
||||
@@ -1,76 +0,0 @@
|
||||
# Frontend (`packages/frontend`) 規約
|
||||
|
||||
Vue 3.5 + Vite + Storybook + Cypress E2E。
|
||||
|
||||
## コンポーネント命名
|
||||
|
||||
- 共有 / 再利用コンポーネントは **`Mk` プレフィックス** (例: `MkButton.vue`, `MkInput.vue`, `MkAbuseReport.vue`)。
|
||||
- ページ単位のものは `packages/frontend/src/pages/` 配下に置く。
|
||||
|
||||
## SFC スタイル
|
||||
|
||||
Composition API + `<script setup lang="ts">` を基本とする (Options API は新規導入しない)。型宣言や module スコープのユーティリティを置きたい時は、setup ブロックと**併用**する形で追加の `<script lang="ts">` ブロックを置いて構わない (例: [`MkInput.vue`](../../packages/frontend/src/components/MkInput.vue) は `SupportedTypes` 型を別ブロックで宣言してから setup を書いている)。SCSS は **CSS Modules** で書き、`<style lang="scss" module>` を使う:
|
||||
|
||||
```vue
|
||||
<!--
|
||||
SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div :class="$style.root">
|
||||
<!-- ... -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
// ...
|
||||
</script>
|
||||
|
||||
<style lang="scss" module>
|
||||
.root {
|
||||
/* ... */
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
## 国際化 (i18n)
|
||||
|
||||
- 文字列リテラルを直書きしない。
|
||||
- 引数なし: `i18n.ts.<path>` で参照する (例: `i18n.ts.deleted`)。
|
||||
- 引数あり: `i18n.tsx.<path>(...)` で関数呼び出しする (例: `i18n.tsx.takeOverConfirm({ name })`)。
|
||||
- 新規キーは **`locales/ja-JP.yml` のみ** に追加する (他言語は Crowdin で自動配信)。
|
||||
- `i18n` は `packages/frontend/src/i18n.ts` (または共有モジュール) から import する。
|
||||
|
||||
## モーダル / 通知
|
||||
|
||||
- `os.ts` (`packages/frontend/src/os.ts`) 経由で呼ぶ。
|
||||
- `os.alert(...)` / `os.confirm(...)` / `os.popup(...)` / `os.success(...)` など。
|
||||
- ブラウザ標準の `window.alert()` / `window.confirm()` を **直接呼ばない**。
|
||||
|
||||
## アクセシビリティ (PR レビューで指摘されやすい点)
|
||||
|
||||
- クリックハンドラを付けるなら `<button>` を使うか、`role="button"` + `tabindex` を付ける。
|
||||
- フォーム要素には `<label>` または `aria-label` を付ける。
|
||||
- キーボード操作可能であること。
|
||||
|
||||
## Storybook
|
||||
|
||||
新規共有コンポーネントには `<ComponentName>.stories.impl.ts` を併設するのが慣習 (`MkButton.stories.impl.ts` 等の例多数)。
|
||||
|
||||
```bash
|
||||
pnpm --filter frontend storybook-dev # localhost:6006
|
||||
```
|
||||
|
||||
## ビルド・開発
|
||||
|
||||
- 開発: `pnpm dev` (ルート) で backend + frontend が watch で立ち上がる。
|
||||
- ビルド: `pnpm --filter frontend build`
|
||||
- 型チェック: `pnpm --filter frontend typecheck` (vue-tsc)
|
||||
- ESLint: `pnpm --filter frontend eslint`
|
||||
|
||||
## テスト
|
||||
|
||||
- Unit (Vitest): `pnpm --filter frontend test`
|
||||
- Cypress E2E: `pnpm e2e` (ルートから; `start-server-and-test` で起動)
|
||||
@@ -1,28 +0,0 @@
|
||||
# 有効化済 Claude Code プラグイン
|
||||
|
||||
`.claude/settings.json` で 14 プラグインが有効化されている。それぞれの典型的な利用シーンを 1 行で示す。
|
||||
|
||||
| プラグイン | 用途 |
|
||||
| --- | --- |
|
||||
| `frontend-design` | UI コンポーネント / ページの設計・デザイン作業 (Vue 3 編集に有効) |
|
||||
| `superpowers` | TDD・debugging・brainstorming・planning 等のメタスキル群 |
|
||||
| `context7` | OSS ドキュメントの取得 (Vue 3, NestJS, TypeORM, Vitest 等) — 訓練データの古さを補う |
|
||||
| `code-review` | コードレビュー (`/code-review`) |
|
||||
| `code-simplifier` | コード整理 (`code-simplifier:code-simplifier` サブエージェント経由) |
|
||||
| `github` | GitHub PR / Issue 操作 (gh ベースだが補助コマンドあり) |
|
||||
| `skill-creator` | 新スキルの作成・改善・評価 |
|
||||
| `feature-dev` | 機能開発ガイド (`/feature-dev:feature-dev` / 内部に `code-architect` / `code-explorer` / `code-reviewer` サブエージェント) |
|
||||
| `claude-md-management` | CLAUDE.md の作成・改善 (`/claude-md-management:revise-claude-md` / `claude-md-improver` エージェント) |
|
||||
| `typescript-lsp` | TypeScript LSP 連携 (型情報を活用) |
|
||||
| `security-guidance` | セキュリティレビュー (`/security-review`) |
|
||||
| `pr-review-toolkit` | PR レビュー一式。サブエージェント: `code-reviewer` / `code-simplifier` / `comment-analyzer` / `pr-test-analyzer` / `silent-failure-hunter` / `type-design-analyzer` |
|
||||
| `claude-code-setup` | Claude Code 自動化セットアップ提案 |
|
||||
| `playwright` | ブラウザ自動操作 (フロントエンド動作確認時に有用) |
|
||||
|
||||
## 使い分けの指針
|
||||
|
||||
- **API 関連の調査**: `context7` で対象ライブラリのドキュメントを取得 → 編集。
|
||||
- **PR 作成前**: `pr-review-toolkit` の各エージェント (code-reviewer / silent-failure-hunter 等) を並列で走らせる。
|
||||
- **新機能の設計**: `feature-dev` → brainstorming → 実装の流れ。
|
||||
- **UI 確認**: `playwright` で `pnpm dev` の画面を直接操作。
|
||||
- **将来追加検討**: PostgreSQL MCP — TypeORM + 342 migration の調査効率化。read-only ロールで登録し、接続先 (`misskey` DB) と権限分離に注意する。
|
||||
@@ -1,69 +0,0 @@
|
||||
# テスト構成
|
||||
|
||||
## Backend 全般の前提: `.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))。**未作成だとテスト自体が起動しない。**
|
||||
|
||||
未作成なら以下を 1 回だけ手動コピーする (どちらでも可):
|
||||
|
||||
```bash
|
||||
ncp .github/misskey/test.yml .config/test.yml
|
||||
# または
|
||||
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`) の前提ではない (ポート競合の元になるため使わないこと)。
|
||||
|
||||
## Backend (Vitest 4, 3 設定)
|
||||
|
||||
| 種別 | 設定ファイル | 実行コマンド |
|
||||
| --- | --- | --- |
|
||||
| Unit | `packages/backend/vitest.config.unit.ts` | `pnpm --filter backend test` |
|
||||
| E2E (HTTP / DB) | `packages/backend/vitest.config.e2e.ts` | `pnpm --filter backend test:e2e` |
|
||||
| Federation | `packages/backend/vitest.config.fed.ts` | `pnpm --filter backend test:fed` |
|
||||
|
||||
- 配置: `packages/backend/test/`
|
||||
- 事前準備は [§Backend 全般の前提: `.config/test.yml`](#backend-全般の前提-configtestyml) を参照。
|
||||
- カバレッジ: `pnpm --filter backend test-and-coverage`
|
||||
|
||||
## Frontend (Vitest)
|
||||
|
||||
```bash
|
||||
pnpm --filter frontend test # 1 回実行
|
||||
pnpm --filter frontend test-and-coverage # カバレッジ付き
|
||||
```
|
||||
|
||||
- 主な配置: `packages/frontend/test/*.test.ts` (例: `i18n.test.ts`, `theme.test.ts`, `is-birthday.test.ts`)。
|
||||
- ビルドツール周りなど対象コードと隣接させた方が分かりやすいテストは、コードと同じディレクトリに `*.test.ts` として置く (例: [`packages/frontend/lib/rollup-plugin-unwind-css-module-class-name.test.ts`](../../packages/frontend/lib/rollup-plugin-unwind-css-module-class-name.test.ts))。
|
||||
- 共有コンポーネント (`MkX.vue`) のユニットテストは現状少なく、`*.spec.ts` / `__tests__/` 形式は採用していない (Storybook + Cypress でカバー)。
|
||||
|
||||
## E2E (Cypress)
|
||||
|
||||
ルートから実行する:
|
||||
|
||||
```bash
|
||||
pnpm e2e # start:test サーバーを立てて Cypress run
|
||||
pnpm cy:open # 対話的に開く
|
||||
```
|
||||
|
||||
- 設定: ルート `cypress.config.ts`。テスト本体は `cypress/` 配下。
|
||||
|
||||
## Storybook (frontend)
|
||||
|
||||
```bash
|
||||
pnpm --filter frontend storybook-dev # http://localhost:6006
|
||||
pnpm --filter frontend build-storybook # 静的ビルド
|
||||
```
|
||||
|
||||
- 各コンポーネント横に `*.stories.impl.ts` を併設する慣習 (例: `MkButton.stories.impl.ts`)。
|
||||
- Chromatic (`pnpm --filter frontend chromatic`) で視覚回帰チェック。
|
||||
|
||||
## ローカル DB / Redis (テスト・開発共通)
|
||||
|
||||
```bash
|
||||
docker compose -f compose.local-db.yml up -d
|
||||
```
|
||||
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"enabledPlugins": {
|
||||
"frontend-design@claude-plugins-official": true,
|
||||
"superpowers@claude-plugins-official": true,
|
||||
"context7@claude-plugins-official": true,
|
||||
"code-review@claude-plugins-official": true,
|
||||
"code-simplifier@claude-plugins-official": true,
|
||||
"github@claude-plugins-official": true,
|
||||
"skill-creator@claude-plugins-official": true,
|
||||
"feature-dev@claude-plugins-official": true,
|
||||
"claude-md-management@claude-plugins-official": true,
|
||||
"typescript-lsp@claude-plugins-official": true,
|
||||
"security-guidance@claude-plugins-official": true,
|
||||
"pr-review-toolkit@claude-plugins-official": true,
|
||||
"claude-code-setup@claude-plugins-official": true,
|
||||
"playwright@claude-plugins-official": true
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
# `.claude/skills/` — プロジェクト固有のカスタムスキル
|
||||
|
||||
Misskey 固有の繰り返しタスクを Claude にスムーズに実行させるための **カスタムスキル** を `.claude/skills/<name>/SKILL.md` 形式で配置する。
|
||||
|
||||
frontmatter (`name` + `description`) は、Claude が **自動でスキルを呼び出すか判断する** 唯一の手がかりになる。`description` には用途を具体的かつ網羅的に書く (動詞 + 対象 + トリガー条件)。
|
||||
|
||||
## 実装済スキル
|
||||
|
||||
### Misskey 固有 (本リポジトリ向け書き起こし)
|
||||
|
||||
| スキル名 | 役割 | 優先度 |
|
||||
| --- | --- | --- |
|
||||
| [create-migration](create-migration/SKILL.md) | TypeORM CLI (`migration:generate` / `migration:create`) でマイグレーションを生成し、SPDX / up-down / `check-migrations` まで誘導 | 高 (342 既存 / 規約厳しい) |
|
||||
| [add-api-endpoint](add-api-endpoint/SKILL.md) | NestJS DI + meta/paramDef 規約で API エンドポイント追加。`endpoint-list.ts` 登録と `misskey-js` 再生成を含む | 高 |
|
||||
| [add-i18n-key](add-i18n-key/SKILL.md) | `locales/ja-JP.yml` のみ編集する補助。型は `packages/i18n` が自動再生成 | 中 |
|
||||
| [add-mk-component](add-mk-component/SKILL.md) | `Mk*` 命名 + SPDX (HTML) + SCSS module + `*.stories.impl.ts` 併設の Vue コンポーネントを一括スキャフォールド | 中 |
|
||||
|
||||
### ECC (everything-claude-code) 由来 — MIT セレクトインポート
|
||||
|
||||
[.claude/THIRD_PARTY_LICENSES.md](../THIRD_PARTY_LICENSES.md) §1 に出典・改変メモ・MIT 全文を集約。
|
||||
|
||||
| スキル名 | 役割 | 優先度 |
|
||||
| --- | --- | --- |
|
||||
| [context-budget](context-budget/SKILL.md) | agents / skills / MCP / CLAUDE.md の token overhead を見える化し、肥大コンポーネントを検出 | 中 |
|
||||
|
||||
設計方針: `create-migration` は手動の `Date.now()` 命名ではなく TypeORM 公式 CLI (`migration:generate` / `migration:create`) を採用。Storybook ファイル名は `*.stories.impl.ts` 規約に準拠する。
|
||||
|
||||
## 新規スキルを追加する場合
|
||||
|
||||
- `.claude/skills/<name>/SKILL.md` に YAML frontmatter (`name` + `description`) と本文 Markdown を書く。
|
||||
- `disable-model-invocation: true` は付けない (auto-invoke させたいため)。
|
||||
- 主要参照ファイルへのリンクは、リポジトリルートからの相対パス (例: `../../packages/backend/...`) で貼る。絶対パスは contributor のホームディレクトリ依存になるので使わない。
|
||||
- 完成したらこの README の表にも 1 行追加する。
|
||||
@@ -1,253 +0,0 @@
|
||||
---
|
||||
name: add-api-endpoint
|
||||
description: Misskey の REST API エンドポイント (/api/<category>/<name>) を NestJS DI + meta/paramDef 規約で追加する。バックエンドに新しい API ルートを足す時に必ず使う。endpoint-list.ts への手動登録、e2e テスト、misskey-js 再生成、CHANGELOG までの一連の手順を含む。
|
||||
---
|
||||
|
||||
# Misskey API エンドポイント追加スキル
|
||||
|
||||
`packages/backend/src/server/api/endpoints/<category>/<name>.ts` に新規エンドポイントを追加するためのワークフロー。**手順 4 (endpoint-list.ts 登録) を忘れると 404 になる** 点に最大の注意を払う。
|
||||
|
||||
## 最重要事実 (見落とすと壊れる)
|
||||
|
||||
1. エンドポイントは **glob 自動収集されない**。[packages/backend/src/server/api/endpoint-list.ts](../../../packages/backend/src/server/api/endpoint-list.ts) への 1 行追加が必須。
|
||||
2. `meta` / `paramDef` を変えたら **misskey-js の再生成が必須**。`pnpm build-misskey-js-with-types` を忘れると CI の `check-misskey-js-autogen` で必ず落ちる。
|
||||
3. `meta.errors` の各 `id` は **UUID**。重複させない (既存全 UUID と衝突確認)。
|
||||
|
||||
## ステップ 1: ファイル配置と SPDX
|
||||
|
||||
`packages/backend/src/server/api/endpoints/<category>/<name>.ts` に新規作成する。`<category>` は機能領域 (例: `notes`, `users`, `admin/announcements`)。
|
||||
|
||||
冒頭に SPDX ヘッダーを必ず付ける:
|
||||
|
||||
```ts
|
||||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
```
|
||||
|
||||
## ステップ 2: 最小テンプレート (シンプル read 系)
|
||||
|
||||
[endpoints/ping.ts](../../../packages/backend/src/server/api/endpoints/ping.ts) をベースに書く。認証不要・パラメータなし・小さなレスポンスの例:
|
||||
|
||||
```ts
|
||||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['<tag>'],
|
||||
requireCredential: false,
|
||||
|
||||
res: {
|
||||
type: 'object',
|
||||
optional: false, nullable: false,
|
||||
properties: {
|
||||
// ...
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {},
|
||||
required: [],
|
||||
} as const;
|
||||
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
constructor(
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
// 実装
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## ステップ 3: 認証付き / DI / errors を含むテンプレート
|
||||
|
||||
[endpoints/notes/create.ts](../../../packages/backend/src/server/api/endpoints/notes/create.ts) を参照する。要点:
|
||||
|
||||
```ts
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import { ApiError } from '@/server/api/error.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
// import ms from 'ms'; // limit.duration に ms('1hour') 等を渡すとき (default import)
|
||||
|
||||
export const meta = {
|
||||
tags: ['notes'],
|
||||
requireCredential: true, // 認証必須なら true
|
||||
prohibitMoved: false, // moved user を拒否するか
|
||||
kind: 'write:notes', // OAuth scope (requireCredential 時に必須)
|
||||
limit: {
|
||||
duration: 3600000, // ms('1hour')
|
||||
max: 300,
|
||||
},
|
||||
errors: {
|
||||
noSuchNote: {
|
||||
message: 'No such note.',
|
||||
code: 'NO_SUCH_NOTE',
|
||||
id: 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx', // ★ UUID v4 を必ず生成 (`x`=hex, `y`=8/9/a/b)。下の「UUID 生成」を参照
|
||||
},
|
||||
},
|
||||
res: {
|
||||
type: 'object',
|
||||
optional: false, nullable: false,
|
||||
ref: 'Note', // packed entity に揃える場合
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
noteId: { type: 'string', format: 'misskey:id' },
|
||||
},
|
||||
required: ['noteId'],
|
||||
} as const;
|
||||
|
||||
@Injectable()
|
||||
export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
|
||||
constructor(
|
||||
@Inject(DI.notesRepository)
|
||||
private notesRepository: NotesRepository,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, me) => {
|
||||
const note = await this.notesRepository.findOneBy({ id: ps.noteId });
|
||||
if (note == null) throw new ApiError(meta.errors.noSuchNote);
|
||||
// 実装
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### meta フィールド早見表
|
||||
|
||||
| フィールド | 用途 |
|
||||
|---|---|
|
||||
| `tags` | OpenAPI タグ (機能領域) |
|
||||
| `requireCredential` | 認証必須か |
|
||||
| `requireModerator` / `requireAdmin` | 権限制限 |
|
||||
| `prohibitMoved` | アカウント移行済ユーザーを拒否 |
|
||||
| `kind` | OAuth scope (`read:notes` / `write:notes` 等)。`requireCredential: true` 時必須 |
|
||||
| `limit` | レート制限 (`{ duration, max, key?, minInterval? }`) |
|
||||
| `errors` | エラー定義。各要素に `message` / `code` / `id` (UUID v4) 必須 |
|
||||
| `res` | JSON Schema or `ref: '<EntityName>'` (packed entity 参照) |
|
||||
| `requireFile` | ファイルアップロード必須 |
|
||||
| `secure` | secure cookie 必要 |
|
||||
| `allowGet` | GET メソッド許可 |
|
||||
| `cacheSec` | レスポンスキャッシュ秒数 |
|
||||
| `description` | OpenAPI 説明 |
|
||||
|
||||
詳細は [endpoints.ts](../../../packages/backend/src/server/api/endpoints.ts) の型定義 (lines 11-125) を参照。
|
||||
|
||||
### paramDef の特殊フォーマット
|
||||
|
||||
JSON Schema (AJV) ベースだが、Misskey 拡張を使える:
|
||||
|
||||
- `format: 'misskey:id'` — ID 文字列バリデーション
|
||||
- `allOf` / `anyOf` / `oneOf` — 複合条件
|
||||
- `default` — デフォルト値
|
||||
|
||||
詳細は [endpoint-base.ts](../../../packages/backend/src/server/api/endpoint-base.ts) を参照。
|
||||
|
||||
### エラー throw
|
||||
|
||||
**「公開 API エラーとして API クライアントに返したいもの」は必ず `throw new ApiError(meta.errors.<key>)` を使う**。`meta.errors` に列挙した上で `ApiError` でラップしないと、misskey-js 側の型情報に出ず、レスポンスも 500 になる。第 2 引数で追加情報を渡せる:
|
||||
|
||||
```ts
|
||||
throw new ApiError(meta.errors.invalidParam, { reason: 'too short' });
|
||||
```
|
||||
|
||||
一方で、**想定外の例外 (DB 不整合 / 下層サービスの bug など) を握り潰すために `try/catch` で `ApiError` に変換するのは避ける**。既存 endpoint も「期待される業務エラーは `ApiError` に変換し、それ以外は `throw err;` で再 throw する」という二段構えになっている。`packages/backend/src/server/api/endpoints/notes/create.ts` の `catch` 節 (末尾の `throw err;`) を参照。生の `throw` を全面禁止すると未知例外も 200 で潰れて debug が困難になるので、このバランスを保つ。
|
||||
|
||||
詳細は [error.ts](../../../packages/backend/src/server/api/error.ts) の `ApiError` クラスを参照。
|
||||
|
||||
### UUID 生成
|
||||
|
||||
```bash
|
||||
node -e "console.log(crypto.randomUUID())"
|
||||
```
|
||||
|
||||
その UUID が他のエンドポイントの `id` と衝突していないか必ず確認:
|
||||
|
||||
```bash
|
||||
grep -r "id: '<生成した UUID>'" packages/backend/src/server/api/endpoints/
|
||||
```
|
||||
|
||||
## ステップ 4: ★必須 — endpoint-list.ts に登録
|
||||
|
||||
[packages/backend/src/server/api/endpoint-list.ts](../../../packages/backend/src/server/api/endpoint-list.ts) の同カテゴリ末尾に 1 行追加する(既存の並びを崩さない):
|
||||
|
||||
```ts
|
||||
export * as '<category>/<name>' from './endpoints/<category>/<name>.js';
|
||||
```
|
||||
|
||||
ファイル冒頭のコメント (`When you add new endpoint, you should add it to this file.`) の通り、このリストが API ルーティングの単一の真実。**忘れると 404**。
|
||||
|
||||
`EndpointsModule.ts` がこのファイルの全エクスポートを `Object.entries()` で反復し、NestJS provider (`provide: 'ep:<path>'`) を生成する。
|
||||
|
||||
## ステップ 5: e2e テスト追加
|
||||
|
||||
[packages/backend/test/e2e/endpoints.ts](../../../packages/backend/test/e2e/endpoints.ts) に対応する `describe` / `test` を追加する。`api()` ヘルパーで叩く:
|
||||
|
||||
```ts
|
||||
describe('<category>/<name>', () => {
|
||||
test('正常系', async () => {
|
||||
const res = await api('<category>/<name>', { /* params */ }, alice);
|
||||
assert.strictEqual(res.status, 200);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
実行: `pnpm --filter backend test:e2e`
|
||||
|
||||
## ステップ 6: misskey-js 再生成 (★必須)
|
||||
|
||||
`meta` / `paramDef` / `res` を変えたら必ず実行する:
|
||||
|
||||
```bash
|
||||
pnpm build-misskey-js-with-types
|
||||
```
|
||||
|
||||
これで以下が更新される:
|
||||
|
||||
- `packages/backend/built/api.json` (OpenAPI spec)
|
||||
- `packages/misskey-js/generator/api.json`
|
||||
- `packages/misskey-js/src/autogen/*.ts` (TypeScript 型)
|
||||
|
||||
PR に `packages/misskey-js/src/autogen/` 配下の差分が含まれていないと、CI の `check-misskey-js-autogen` で落ちる。
|
||||
|
||||
## ステップ 7: Lint と typecheck
|
||||
|
||||
```bash
|
||||
pnpm --filter backend lint
|
||||
```
|
||||
|
||||
(typecheck = `tsgo --noEmit` / ESLint = `eslint`)
|
||||
|
||||
## ステップ 8: CHANGELOG
|
||||
|
||||
ユーザー影響がある (新機能 / 既存挙動変更) なら、`CHANGELOG.md` の `## Unreleased` → `### Server` に 1 行追加する ([AGENTS.md §CHANGELOG](../../../AGENTS.md#changelog) 参照):
|
||||
|
||||
```
|
||||
- Feat: /api/<category>/<name> を追加
|
||||
```
|
||||
|
||||
純粋なリファクタや内部用なら不要。
|
||||
|
||||
## 参照ファイル
|
||||
|
||||
- [endpoints.ts (meta/paramDef 型定義)](../../../packages/backend/src/server/api/endpoints.ts)
|
||||
- [endpoint-base.ts (Endpoint 基底クラス)](../../../packages/backend/src/server/api/endpoint-base.ts)
|
||||
- [endpoint-list.ts (★ ここに登録)](../../../packages/backend/src/server/api/endpoint-list.ts)
|
||||
- [error.ts (ApiError)](../../../packages/backend/src/server/api/error.ts)
|
||||
- [endpoints/ping.ts (最小例)](../../../packages/backend/src/server/api/endpoints/ping.ts)
|
||||
- [endpoints/notes/create.ts (DI + errors の典型)](../../../packages/backend/src/server/api/endpoints/notes/create.ts)
|
||||
- [test/e2e/endpoints.ts (テスト例)](../../../packages/backend/test/e2e/endpoints.ts)
|
||||
- [scripts/generate_api_json.js (misskey-js 生成元)](../../../packages/backend/scripts/generate_api_json.js)
|
||||
@@ -1,115 +0,0 @@
|
||||
---
|
||||
name: add-i18n-key
|
||||
description: Misskey の i18n キーを追加・修正する。locales/ja-JP.yml のみ編集可能で、他言語ファイル (en-US.yml 等 39 言語) は Crowdin の自動配信先のため絶対に触らない。型は packages/i18n が ja-JP.yml から自動再生成する。frontend からは i18n.ts.<key> または i18n.tsx.<key>(...) で参照する。
|
||||
---
|
||||
|
||||
# Misskey i18n キー追加スキル
|
||||
|
||||
UI 文言の追加・変更を行う際の規約。**手動編集して良いのは `locales/ja-JP.yml` のみ。**
|
||||
|
||||
## 大前提 (絶対 NG)
|
||||
|
||||
- **`locales/<lang>.yml` (ja-JP.yml 以外) の編集は禁止**。これらは Crowdin の自動配信先で、手動編集すると次の同期で上書き喪失する ([locales/README.md](../../../locales/README.md), [crowdin.yml](../../../crowdin.yml))。
|
||||
- 文字列リテラルを SFC に直書きしない (`<span>こんにちは</span>` 等)。必ず `i18n.ts.<key>` を経由する。
|
||||
- 既存キーの破壊的リネームは Crowdin 翻訳資産も道連れになるので慎重に。追加・改名併用 (新キー追加 → 移行 → 旧キー削除) を検討する。
|
||||
|
||||
## ステップ 1: ja-JP.yml にキーを追加
|
||||
|
||||
[locales/ja-JP.yml](../../../locales/ja-JP.yml) を編集する。YAML の階層構造を維持し、関連するセクションに配置する:
|
||||
|
||||
```yaml
|
||||
# トップレベル単純キー
|
||||
save: "保存"
|
||||
|
||||
# ネストしたカテゴリ (アンダースコア接頭辞は内部カテゴリ)
|
||||
_settings:
|
||||
general: "全般"
|
||||
appearance: "外観"
|
||||
|
||||
# パラメータ付き (ICU MessageFormat 互換)
|
||||
greeting: "こんにちは、{name}さん"
|
||||
```
|
||||
|
||||
### 命名のお作法
|
||||
|
||||
- 単純キー: lowerCamelCase (例: `saveChanges`, `confirmDelete`)。
|
||||
- カテゴリ: アンダースコア接頭辞 (例: `_settings`, `_abuseUserReport`)。
|
||||
- 既存セクション内に置く場合はアルファベット順を維持する (新セクション全体を末尾に追加するのは可)。
|
||||
|
||||
## ステップ 2: 型定義の自動再生成
|
||||
|
||||
`packages/i18n/build.ts` が `ja-JP.yml` を解析し、TypeScript インターフェースを [packages/i18n/src/autogen/locale.ts](../../../packages/i18n/src/autogen/locale.ts) に出力する。
|
||||
|
||||
### 自動 (推奨)
|
||||
|
||||
`pnpm dev` 実行中なら、`packages/i18n` の watch スクリプトが yml の変更を検知して自動再生成する。
|
||||
|
||||
### 手動
|
||||
|
||||
```bash
|
||||
pnpm --filter i18n generate
|
||||
```
|
||||
|
||||
実体は `tsx scripts/generateLocaleInterface.ts`。
|
||||
|
||||
### 失敗パターン
|
||||
|
||||
これを実行せずに frontend 側で `i18n.ts.<newKey>` を参照すると、`Locale` インターフェースに追加されていないため、typecheck で「Property '<newKey>' does not exist on type 'Locale'」というエラーになる。`pnpm --filter frontend lint` で発覚する。
|
||||
|
||||
## ステップ 3: frontend での参照
|
||||
|
||||
```ts
|
||||
import { i18n } from '@/i18n.js';
|
||||
```
|
||||
|
||||
| 用途 | 書き方 |
|
||||
|---|---|
|
||||
| 単純文字列 | `i18n.ts.save` |
|
||||
| ネスト | `i18n.ts._settings.general` |
|
||||
| パラメータ付き | `i18n.tsx.greeting({ name: userName })` |
|
||||
| Vue テンプレート内 | `{{ i18n.ts.save }}` / `{{ i18n.tsx.greeting({ name }) }}` |
|
||||
|
||||
`i18n.ts` は型付き文字列、`i18n.tsx` は MessageFormat 関数。
|
||||
|
||||
## ステップ 4: 検証
|
||||
|
||||
```bash
|
||||
# i18n パッケージの型再生成 + typecheck
|
||||
pnpm --filter i18n lint
|
||||
|
||||
# frontend で新キー参照箇所の型チェック
|
||||
pnpm --filter frontend lint
|
||||
```
|
||||
|
||||
## 例: 「ノートを削除しますか?」確認ダイアログを追加する
|
||||
|
||||
1. `locales/ja-JP.yml`:
|
||||
```yaml
|
||||
_notes:
|
||||
deleteConfirm: "このノートを削除しますか?"
|
||||
```
|
||||
2. `pnpm --filter i18n generate` (または `pnpm dev` で watch 中)
|
||||
3. SFC:
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import { i18n } from '@/i18n.js';
|
||||
import * as os from '@/os.js';
|
||||
|
||||
async function onDelete() {
|
||||
const { canceled } = await os.confirm({
|
||||
type: 'warning',
|
||||
text: i18n.ts._notes.deleteConfirm,
|
||||
});
|
||||
if (canceled) return;
|
||||
// 削除処理
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
## 参照ファイル
|
||||
|
||||
- [locales/README.md (★ 編集ポリシー根拠)](../../../locales/README.md)
|
||||
- [locales/ja-JP.yml](../../../locales/ja-JP.yml)
|
||||
- [packages/i18n/build.ts](../../../packages/i18n/build.ts)
|
||||
- [packages/i18n/src/autogen/locale.ts (生成物)](../../../packages/i18n/src/autogen/locale.ts)
|
||||
- [packages/frontend/src/i18n.ts](../../../packages/frontend/src/i18n.ts)
|
||||
@@ -1,174 +0,0 @@
|
||||
---
|
||||
name: add-mk-component
|
||||
description: Misskey フロントエンドの新規 Vue 3 コンポーネントを追加する。Mk* 命名 / SPDX (HTML コメント) / <script setup lang="ts"> / <style lang="scss" module> / *.stories.impl.ts 併設の規約をまとめて適用する。新しい共有 UI コンポーネントを packages/frontend/src/components/ に作る時に使う。
|
||||
---
|
||||
|
||||
# Misskey Vue コンポーネント追加スキル
|
||||
|
||||
`packages/frontend/src/components/` に新しい共有コンポーネントを追加するための規約。
|
||||
|
||||
## 大前提
|
||||
|
||||
- 共有 / 再利用コンポーネントは **必ず `Mk` プレフィックス** (例: `MkButton`, `MkInput`)。ページ固有部品など `Mk` プレフィックスでないものは原則 `pages/` 側に置く。
|
||||
- 新規では `<style lang="scss" module>` (CSS Modules) を既定とする。古い `scoped` 形式が混在しているが、新規では使わない。
|
||||
- 文字列リテラルの直書きは禁止。文言は必ず `i18n.ts.<key>` 経由で参照する (新キーは `add-i18n-key` スキルを参照)。
|
||||
- `alert()` / `confirm()` / `window.prompt()` は使わない。`os.alert` / `os.confirm` / `os.popup` などを使う。
|
||||
|
||||
## ステップ 1: ファイル配置
|
||||
|
||||
`packages/frontend/src/components/Mk<Name>.vue` に新規作成する。
|
||||
|
||||
ストーリーが必要 (= ほぼ常に必要) なら、同階層に `Mk<Name>.stories.impl.ts` も作る。Storybook の規約は `*.stories.impl.ts` であって、`*.stories.ts` ではない。
|
||||
|
||||
## ステップ 2: SPDX ヘッダー (HTML コメント形式)
|
||||
|
||||
`.vue` ファイル冒頭に必須:
|
||||
|
||||
```html
|
||||
<!--
|
||||
SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
```
|
||||
|
||||
`/* ... */` (TS / JS 形式) ではなく **HTML コメント** で書くこと。既存の `.vue` ファイルがすべて HTML コメント形式を使っており、SFC の先頭として自然な形式に統一するため (CI の `spdx` ジョブはコメント形式ではなく SPDX 文字列の有無のみを検査する)。
|
||||
|
||||
## ステップ 3: 最小テンプレート
|
||||
|
||||
[MkInfo.vue](../../../packages/frontend/src/components/MkInfo.vue) をベースにする (シンプルな表示コンポーネント):
|
||||
|
||||
```vue
|
||||
<!--
|
||||
SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div :class="$style.root">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
const props = defineProps<{
|
||||
variant?: 'primary' | 'secondary';
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(ev: 'click'): void;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<style lang="scss" module>
|
||||
.root {
|
||||
padding: 12px 14px;
|
||||
border-radius: var(--MI-radius);
|
||||
background: var(--MI_THEME-panel);
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
### 規約ポイント
|
||||
|
||||
| 項目 | 規約 |
|
||||
|---|---|
|
||||
| `<script>` | `<script lang="ts" setup>`。型パラメータが必要なら `generic="T extends ..."` を付ける ([MkInput.vue 参照](../../../packages/frontend/src/components/MkInput.vue)) |
|
||||
| `defineProps` / `defineEmits` | **type-only** (`<{ ... }>`) 形式。runtime の object 形式は使わない |
|
||||
| `<style>` | `lang="scss" module` を既定。クラス参照は `:class="$style.foo"` |
|
||||
| CSS 変数 | `var(--MI_THEME-...)` (テーマ) / `var(--MI-radius)` (UI 共通) — ハードコードしない |
|
||||
| アイコン | Tabler icons のクラス (`<i class="ti ti-info-circle">`) を使う |
|
||||
|
||||
## ステップ 4: i18n と os の利用
|
||||
|
||||
```vue
|
||||
<script lang="ts" setup>
|
||||
import { i18n } from '@/i18n.js';
|
||||
import * as os from '@/os.js';
|
||||
|
||||
async function onClick() {
|
||||
const { canceled } = await os.confirm({
|
||||
type: 'warning',
|
||||
text: i18n.ts._notes.deleteConfirm,
|
||||
});
|
||||
if (canceled) return;
|
||||
os.toast(i18n.ts.deleted);
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
### `os` の主なヘルパー (詳細は [os.ts](../../../packages/frontend/src/os.ts))
|
||||
|
||||
| 関数 | 用途 |
|
||||
|---|---|
|
||||
| `os.alert({ type, title?, text })` | 単方向アラート |
|
||||
| `os.confirm({ type, title, text })` | yes/no 確認 (`{ canceled }` を返す) |
|
||||
| `os.toast(message)` | 一時通知 |
|
||||
| `os.popup(component, props, handlers)` | 任意コンポーネントの非同期ポップアップ |
|
||||
| `os.popupMenu(items, anchor?)` | コンテキストメニュー |
|
||||
| `os.form(title, fields)` | フォームダイアログ |
|
||||
| `os.apiWithDialog(endpoint, data)` | API 呼出し + エラー時ダイアログ表示 |
|
||||
|
||||
## ステップ 5: Storybook ストーリー併設
|
||||
|
||||
[MkButton.stories.impl.ts](../../../packages/frontend/src/components/MkButton.stories.impl.ts) を雛形として参考にする。`.stories.impl.ts` も `packages/frontend/src/` 配下の `.ts` ファイルなので [AGENTS.md §1 SPDX ヘッダー必須](../../../AGENTS.md#1-spdx-ヘッダー必須) の対象であり、冒頭に SPDX ヘッダーを必ず付ける (HTML コメント形式ではなく `/* */` 形式)。形式 (以下の `MkXxx` は実際のコンポーネント名に置換する):
|
||||
|
||||
```ts
|
||||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
||||
/* eslint-disable import/no-default-export */
|
||||
import type { StoryObj } from '@storybook/vue3';
|
||||
import MkXxx from './MkXxx.vue';
|
||||
|
||||
export const Default = {
|
||||
render(args) {
|
||||
return {
|
||||
components: { MkXxx },
|
||||
setup() {
|
||||
return { args };
|
||||
},
|
||||
template: '<MkXxx v-bind="args">slot content</MkXxx>',
|
||||
};
|
||||
},
|
||||
args: {
|
||||
variant: 'primary',
|
||||
},
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
},
|
||||
} satisfies StoryObj<typeof MkXxx>;
|
||||
```
|
||||
|
||||
`Vue` SFC は default export なので、`import MkXxx from './MkXxx.vue';` のように名前付き import ではなく default import で書く。実行確認は `pnpm --filter frontend storybook-dev`。
|
||||
|
||||
## ステップ 6: Lint と typecheck
|
||||
|
||||
```bash
|
||||
pnpm --filter frontend lint
|
||||
```
|
||||
|
||||
(typecheck = vue-tsc 等、ESLint = `@misskey-dev/eslint-plugin` 含む)
|
||||
|
||||
ESLint --fix をピンポイントで:
|
||||
|
||||
```bash
|
||||
pnpm exec eslint --fix packages/frontend/src/components/Mk<Name>.vue
|
||||
```
|
||||
|
||||
## ステップ 7: 既存コンポーネントとの整合性確認
|
||||
|
||||
- 似た用途の既存 `Mk*` コンポーネントを参考に、スタイルやプロップ命名を揃える。
|
||||
- `_button` / `_panel` / `_selectable` などの **共通 utility class** (グローバルスタイルにある) を活用できるか確認する。
|
||||
- 大きな機能なら、Storybook stories で各バリエーションを網羅する。
|
||||
|
||||
## 参照ファイル
|
||||
|
||||
- [MkInfo.vue (シンプル例)](../../../packages/frontend/src/components/MkInfo.vue)
|
||||
- [MkButton.vue (汎用ボタン例)](../../../packages/frontend/src/components/MkButton.vue)
|
||||
- [MkInput.vue (generics + 多機能例)](../../../packages/frontend/src/components/MkInput.vue)
|
||||
- [MkButton.stories.impl.ts (Storybook 雛形)](../../../packages/frontend/src/components/MkButton.stories.impl.ts)
|
||||
- [packages/frontend/src/os.ts](../../../packages/frontend/src/os.ts)
|
||||
- [packages/frontend/src/i18n.ts](../../../packages/frontend/src/i18n.ts)
|
||||
@@ -1,148 +0,0 @@
|
||||
---
|
||||
name: context-budget
|
||||
description: Claude Code セッションのコンテキスト窓消費を agents/skills/MCP/rules/CLAUDE.md ごとに見える化し、肥大化と冗長コンポーネントを検出して節約候補を提示する。"コンテキスト消費を見せて"、"context budget"、"context audit"、"トークン内訳"、"これ以上 MCP 入る?" 等の発話で起動する。
|
||||
---
|
||||
|
||||
<!--
|
||||
SPDX-License-Identifier: MIT
|
||||
SPDX-FileCopyrightText: 2026 Affaan Mustafa and everything-claude-code contributors
|
||||
|
||||
出典 (upstream): https://github.com/affaan-m/everything-claude-code (v2.0.0-rc.1)
|
||||
upstream path: skills/context-budget/SKILL.md
|
||||
upstream origin frontmatter: ECC
|
||||
upstream license: MIT — https://github.com/affaan-m/everything-claude-code/blob/main/LICENSE
|
||||
project-level notice: see .claude/THIRD_PARTY_LICENSES.md (Misskey 内サードパーティ一覧 + MIT 全文)
|
||||
|
||||
Imported into Misskey .claude/ on 2026-05-10 as a standalone copy (no dependency on the ECC plugin runtime). description was rewritten in Japanese and a "Misskey 固有メモ" section was appended; body content remains MIT-licensed.
|
||||
|
||||
note: Misskey の skills/agents 数は少ないので、MCP / CLAUDE.md / プラグイン由来の overhead が支配的になりやすい点に留意。
|
||||
-->
|
||||
|
||||
# Context Budget
|
||||
|
||||
セッション内に読み込まれるコンポーネント (agents / skills / rules / MCP servers / CLAUDE.md) の token overhead を分析し、空き context を回復する具体策を提示する。
|
||||
|
||||
## 使う場面
|
||||
|
||||
- セッションが重い・出力品質が落ちてきた感覚がある
|
||||
- 直近で skills / agents / MCP server を多数追加した
|
||||
- 残りの context headroom を知りたい
|
||||
- 追加コンポーネントを入れる前に空きを確認したい
|
||||
- 「context-budget」「token 内訳」等のキーワードでユーザーが明示的に要請した時 (Misskey リポジトリにはこの名前のスラッシュコマンドは登録していない — 本 skill は名前 / description マッチで auto-invoke される想定。実装済の slash command 一覧は [.claude/commands/](../../commands/) を参照)
|
||||
|
||||
## 仕組み
|
||||
|
||||
### Phase 1: Inventory
|
||||
|
||||
各コンポーネントを走査して token を推定する。
|
||||
|
||||
**Agents** (`.claude/agents/*.md`)
|
||||
- 行数とトークン数 (`words × 1.3`) を計算
|
||||
- frontmatter `description` の長さを抽出
|
||||
- フラグ: 200 行超 (重い)、description 30 word 超 (frontmatter 肥大)
|
||||
|
||||
**Skills** (`.claude/skills/*/SKILL.md`)
|
||||
- SKILL.md ごとに token を計算
|
||||
- フラグ: 400 行超
|
||||
- `.agents/skills/` 等の重複コピーは除外
|
||||
|
||||
**Rules** (リポジトリルートの `AGENTS.md` + `.claude/` から `@-import` されるファイル)
|
||||
- ファイル単位で token 計算
|
||||
- フラグ: 100 行超
|
||||
- 同一言語モジュール内の内容重複を検出
|
||||
|
||||
**MCP Servers** (`.mcp.json` または有効 MCP 設定)
|
||||
- server 数と総 tool 数
|
||||
- schema overhead をツールあたり ~500 token で見積もる
|
||||
- フラグ: 20 tool 超のサーバー、`gh` / `git` / `npm` 等の CLI を単純ラップしただけのサーバー
|
||||
|
||||
**CLAUDE.md** (project + user-level)
|
||||
- ファイルごとに token を計算
|
||||
- フラグ: 合計 300 行超
|
||||
|
||||
### Phase 2: Classify
|
||||
|
||||
| バケット | 判定基準 | 行動 |
|
||||
|--------------------|-------------------------------------------------------------|-----------------------------------|
|
||||
| **Always needed** | CLAUDE.md から参照されている / 有効コマンドの裏 / 現プロジェクトと一致 | 維持 |
|
||||
| **Sometimes needed** | ドメイン依存 (例: 言語パターン)、CLAUDE.md 参照なし | オンデマンド有効化を検討 |
|
||||
| **Rarely needed** | コマンド参照なし、内容重複、明確な用途なし | 削除または lazy-load |
|
||||
|
||||
### Phase 3: Detect Issues
|
||||
|
||||
- **Bloated agent description** — frontmatter description が 30 word 超だと、Task ツール起動のたびに毎回ロードされる
|
||||
- **Heavy agents** — 200 行超は Task ツールの context を毎回膨らませる
|
||||
- **Redundant components** — agent ロジックを重複する skill、CLAUDE.md と重複する rule
|
||||
- **MCP over-subscription** — 10 server 超、または CLI 代用可能なサーバー
|
||||
- **CLAUDE.md bloat** — 冗長説明、古いセクション、rule に移すべき指示
|
||||
|
||||
### Phase 4: Report
|
||||
|
||||
```
|
||||
Context Budget Report
|
||||
═══════════════════════════════════════
|
||||
|
||||
Total estimated overhead: ~XX,XXX tokens
|
||||
Context model: <現在モデル名> (<window>K window) ← 例: Claude Opus 4.7 (1M), Claude Sonnet (200K)
|
||||
Effective available context: ~XXX,XXX tokens (XX%)
|
||||
|
||||
Component Breakdown:
|
||||
┌─────────────────┬────────┬───────────┐
|
||||
│ Component │ Count │ Tokens │
|
||||
├─────────────────┼────────┼───────────┤
|
||||
│ Agents │ N │ ~X,XXX │
|
||||
│ Skills │ N │ ~X,XXX │
|
||||
│ Rules │ N │ ~X,XXX │
|
||||
│ MCP tools │ N │ ~XX,XXX │
|
||||
│ CLAUDE.md │ N │ ~X,XXX │
|
||||
└─────────────────┴────────┴───────────┘
|
||||
|
||||
WARNING: Issues Found (N):
|
||||
[token 節約量の降順]
|
||||
|
||||
Top 3 Optimizations:
|
||||
1. [action] → save ~X,XXX tokens
|
||||
2. [action] → save ~X,XXX tokens
|
||||
3. [action] → save ~X,XXX tokens
|
||||
|
||||
Potential savings: ~XX,XXX tokens (XX% of current overhead)
|
||||
```
|
||||
|
||||
verbose mode ではさらにファイルごとの token 内訳、最重ファイルの行単位ブレークダウン、重複行の対比、MCP tool 一覧 + tool ごとの schema サイズ推定を出す。
|
||||
|
||||
## 例
|
||||
|
||||
**基本監査**
|
||||
```
|
||||
User: コンテキスト消費を見せて
|
||||
Skill: 16 agents (12,400 tokens), 28 skills (6,200), 87 MCP tools (43,500), 2 CLAUDE.md (1,200)
|
||||
Flags: 重い agent 3 個、CLI 代用可能な MCP 3 個
|
||||
Top saving: MCP 3 個削除 → -27,500 tokens (overhead の 47% 削減)
|
||||
```
|
||||
|
||||
**Verbose**
|
||||
```
|
||||
User: トークン内訳をファイル単位で
|
||||
Skill: 上記レポートに加えて、planner.md (213 lines, 1,840 tokens) のような
|
||||
per-file 行内訳、MCP tool ごとのサイズ、rule の重複行を side-by-side で表示
|
||||
```
|
||||
|
||||
**追加前チェック**
|
||||
```
|
||||
User: MCP server を 5 個追加したいが、空きある?
|
||||
Skill: 現状 33% → 5 server (≈ 50 tools) 追加で +25,000 tokens → 45% に到達
|
||||
推奨: CLI 代用可能な server 2 個を先に外して 40% 以下を維持
|
||||
```
|
||||
|
||||
## ベストプラクティス
|
||||
|
||||
- **トークン推定**: prose は `words × 1.3`、code 主体は `chars / 4`
|
||||
- **MCP は最大のレバー**: tool あたり ~500 token、30-tool server ひとつで全 skill より大きい
|
||||
- **agent description は常時ロード**: 呼ばれない agent でも description は毎 Task 投入
|
||||
- **verbose は debug 用**: 普段は使わない
|
||||
- **変更後は監査**: agent/skill/MCP 追加直後に走らせて creep を早期発見
|
||||
|
||||
## Misskey 固有メモ
|
||||
|
||||
- Misskey は MCP server をプロジェクトで明示登録していないため (`.mcp.json` 不在)、現状 overhead の支配項は CLAUDE.md と公式プラグイン群の skills / agents description である。
|
||||
- ECC プラグインがユーザースコープで `installed_plugins.json` に存在するため、プロジェクトで `enabledPlugins` に追加していなくても system reminder に 200+ skill が現れる。これらは description が短いので個別 overhead は小さいが、合計値の確認に本 skill を使う。
|
||||
@@ -1,156 +0,0 @@
|
||||
---
|
||||
name: create-migration
|
||||
description: Misskey の TypeORM マイグレーションを公式 CLI (migration:generate / migration:create) で正しく生成し、SPDX ヘッダー付与・up/down 整合・check-migrations 確認まで誘導する。エンティティのスキーマ変更を含むあらゆる DB 変更、または手書き SQL によるデータ移行が必要な時に使用する。
|
||||
---
|
||||
|
||||
# Misskey マイグレーション作成スキル
|
||||
|
||||
`packages/backend/migration/` に新規 TypeORM マイグレーションを追加するためのワークフロー。
|
||||
|
||||
## 大前提 (絶対 NG)
|
||||
|
||||
- **既にマージ済み (develop / master) のマイグレーションファイルを編集しない** ([AGENTS.md §3](../../../AGENTS.md#3-マージ済み-migration-を絶対に編集しない))。本番履歴の改変は深刻なデータ不整合を引き起こす。スキーマ変更は **常に新しいタイムスタンプで新規ファイル** を作る。
|
||||
- ファイル名のタイムスタンプ部分を後から書き換えない (順序が壊れる)。
|
||||
|
||||
> 作り方は AGENTS.md §3 の「`Date.now()` で UNIX ms を取得 → `{ms}-{PascalName}.js` を手書き」が最低ライン。エンティティ差分から自動生成したい (= TypeORM の `migration:generate` を使う) 場合は本 skill の手順に従う。**どちらでも構わない**が、エンティティ変更を伴う時は CLI 経由のほうが取り漏れが減るので推奨。
|
||||
|
||||
## ステップ 1: どちらの方式を使うか決める
|
||||
|
||||
| 状況 | 方式 |
|
||||
|---|---|
|
||||
| エンティティ (`packages/backend/src/models/*.ts`) を `@Column` / `@Index` / `@Entity` 等で先に変更し、差分から自動生成したい | `typeorm migration:generate` (本 skill の手順) |
|
||||
| 手書き SQL / データ移行 / `CREATE INDEX CONCURRENTLY` など、エンティティ差分では表現できない変更 | `typeorm migration:create` で空雛形を作るか、`migrate-new` command で手書き雛形を作る |
|
||||
| 列追加 1 本のような小規模変更で、既存ファイルをコピーした方が速い | AGENTS.md §3 の手順 (`Date.now()` + 手書き) でよい |
|
||||
|
||||
迷ったら **まずエンティティを変更 → `migration:generate`** が原則。既存 342 ファイルのほぼすべてが `queryRunner.query(\`SQL...\`)` の raw SQL なので、CLI 出力でも手書きでもスタイルは揃う。
|
||||
|
||||
## ステップ 2: CLI 実行
|
||||
|
||||
ルートディレクトリから以下を実行する。`<PascalName>` は変更内容を表す PascalCase (例: `AddBirthdayIndex`, `AddCategoryToAvatarDecorations`)。
|
||||
|
||||
### 2-A. エンティティ差分から生成
|
||||
|
||||
[CONTRIBUTING.md §Migration作成方法](../../../CONTRIBUTING.md#migration作成方法) に記載の基本形:
|
||||
|
||||
```bash
|
||||
# packages/backend ディレクトリで実行する場合 (CONTRIBUTING.md 記載形式)
|
||||
pnpm dlx typeorm migration:generate -d ormconfig.js -o --esm <PascalName>
|
||||
```
|
||||
|
||||
**リポジトリルートから実行する場合** (AI が使う推奨形式。`pnpm --filter backend exec` を使うと backend の TypeORM バージョンと一致するため確実):
|
||||
|
||||
```bash
|
||||
pnpm --filter backend exec typeorm migration:generate -d ormconfig.js -o --esm migration/<PascalName>
|
||||
```
|
||||
|
||||
> **`--esm` について**: `-o` / `--outputJs` は「TS ではなく JS を出力する」オプション、`--esm` は「ESM 形式 (`export class ...`) で出力する」オプション。Misskey の既存 migration はすべて ESM JS であるため **両方が必須**。`--esm` を省略すると CommonJS 形式の JS が生成されスタイルが揃わない。
|
||||
|
||||
事前準備:
|
||||
|
||||
- `pnpm build-pre` を実行して `built/meta.json` を生成する (`loadConfig()` が `built/meta.json` を必須とするため。`pnpm build` 済みであれば不要)。
|
||||
- `.config/default.yml` が存在すること (なければ `.config/example.yml` を参考に作成する)。
|
||||
- `pnpm --filter backend compile-config` を実行して `built/.config.json` を生成する (`ormconfig.js` が `loadConfig()` 経由で必須とする。未実行だと "Compiled configuration file not found." エラーになる)。
|
||||
- `pnpm --filter backend build` でエンティティを最新ビルド (CLI は `built/` を読む)。
|
||||
- ローカル DB を起動する (`docker compose -f compose.local-db.yml up -d`)。
|
||||
|
||||
### 2-B. 空の手書きマイグレーション
|
||||
|
||||
```bash
|
||||
pnpm --filter backend exec typeorm migration:create -o --esm migration/<PascalName>
|
||||
```
|
||||
|
||||
ローカル DB の起動とビルドは不要。空の `up` / `down` だけが生成される。
|
||||
|
||||
> `-o --esm` を **必ず付ける**。これが無いと `<UnixMs>-<PascalName>.ts` (CommonJS / TS 出力) が生成されるが、Misskey の `ormconfig.js` は `migration/*.js` だけを読み、既存の他 migration も全て `export class ... { async up(queryRunner) {...} }` の ESM JS 形式なので、後で手作業で `.ts → .js` リネーム + `import { MigrationInterface }` 削除 + `class ... implements MigrationInterface` 削除をしないと走らない。`-o --esm` を付ければそのまま `.js` ESM で出るので、後処理は SPDX ヘッダー付与 (ステップ 3) だけで済む。
|
||||
|
||||
## ステップ 3: SPDX ヘッダー付与
|
||||
|
||||
CLI 出力には SPDX ヘッダーが含まれない。**必ず冒頭に追加する** (CI の `spdx` ジョブが失敗するため)。
|
||||
|
||||
```js
|
||||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
```
|
||||
|
||||
## ステップ 4: up / down の整合確認
|
||||
|
||||
- `up()` の各ステートメントに対し、`down()` で完全に巻き戻せること。
|
||||
- 列追加 (`ADD COLUMN`) ↔ 列削除 (`DROP COLUMN`)、テーブル作成 ↔ テーブル削除、
|
||||
FK 追加 ↔ FK 削除、インデックス作成 ↔ インデックス削除 を必ずペアで書く。
|
||||
- `down()` を空のまま残さない。本番ロールバック時に詰む。
|
||||
|
||||
### インデックス追加時の注意 (CREATE INDEX CONCURRENTLY)
|
||||
|
||||
大規模テーブルへの `CREATE INDEX` は本番で長時間ロックする恐れがある。`CONCURRENTLY` で発行するときは **migration 側にも対応が必要**: PostgreSQL は `CREATE INDEX CONCURRENTLY` を transaction 内で実行できないため、migration class に以下を仕込んで TypeORM に「この migration は transaction を張らない」と指示する。
|
||||
|
||||
参照実装: [packages/backend/migration/1745378064470-composite-note-index.js](../../../packages/backend/migration/1745378064470-composite-note-index.js)。
|
||||
|
||||
```js
|
||||
const isConcurrentIndexMigrationEnabled = process.env.MISSKEY_MIGRATION_CREATE_INDEX_CONCURRENTLY === '1';
|
||||
|
||||
export class CompositeNoteIndex1745378064470 {
|
||||
name = 'CompositeNoteIndex1745378064470';
|
||||
transaction = isConcurrentIndexMigrationEnabled ? false : undefined;
|
||||
|
||||
async up(queryRunner) {
|
||||
const concurrently = isConcurrentIndexMigrationEnabled;
|
||||
if (concurrently) {
|
||||
// CREATE INDEX CONCURRENTLY ...
|
||||
} else {
|
||||
// CREATE INDEX ...
|
||||
}
|
||||
}
|
||||
|
||||
async down(queryRunner) {
|
||||
// 同様に環境変数で分岐
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
要点:
|
||||
|
||||
- **`transaction = isConcurrentIndexMigrationEnabled ? false : undefined;`** が必須。これがないと `CREATE INDEX CONCURRENTLY` が transaction 内で実行されて `ERROR: CREATE INDEX CONCURRENTLY cannot run inside a transaction block` で失敗する。
|
||||
- 環境変数 `MISSKEY_MIGRATION_CREATE_INDEX_CONCURRENTLY=1` がデフォルト OFF。OFF のときは普通の `CREATE INDEX` (transaction 内) で動く必要がある。`up`/`down` 双方を環境変数で分岐させる。
|
||||
- `ormconfig.js` の `migrationsTransactionMode` は **環境変数で切り替わる**: `MISSKEY_MIGRATION_CREATE_INDEX_CONCURRENTLY=1` のときだけ `'each'` (各 migration が個別 transaction)、未設定時は `'all'` (全 migration を 1 つの transaction でラップ) ([ormconfig.js:19](../../../packages/backend/ormconfig.js#L19))。普段は `'all'` 前提なので、CONCURRENTLY を使う migration を書く時だけこのフラグの存在を意識すれば良い。
|
||||
|
||||
### 関連エンティティとの一致
|
||||
|
||||
`migration:generate` を使った場合、エンティティ側の `@Column` / `@Entity` 修正と DB スキーマが食い違うとビルド全体がズレる。生成後に該当エンティティと SQL の対応を目視確認すること。
|
||||
|
||||
## ステップ 5: 検証
|
||||
|
||||
ルートから実行:
|
||||
|
||||
```bash
|
||||
# 未反映の差分が無いか (新規 migration が生成すべき DDL を取り逃していないか)
|
||||
pnpm --filter backend check-migrations
|
||||
|
||||
# ローカル DB に適用
|
||||
pnpm migrate
|
||||
|
||||
# ロールバック (down が壊れていないか)
|
||||
pnpm revert
|
||||
|
||||
# 再適用 (順方向にもう一度通す)
|
||||
pnpm migrate
|
||||
```
|
||||
|
||||
`check-migrations` の実体は [scripts/check_migrations_clean.js](../../../packages/backend/scripts/check_migrations_clean.js)。TypeORM の `dataSource.driver.createSchemaBuilder().log()` で pending DDL を取得し、`upQueries` / `downQueries` のいずれかが残っていれば非ゼロ終了する。**順序検査ではなく**「エンティティと migration が同期しているか」の検査。
|
||||
|
||||
## ステップ 6: 既存ファイル参照テンプレ
|
||||
|
||||
新規ファイルを書くときは、変更パターンが近い既存ファイルを **必ずひとつ開いて並べて書く**。スタイルが激しくズレた PR は差し戻されやすい。
|
||||
|
||||
| パターン | 参照ファイル |
|
||||
|---|---|
|
||||
| インデックス追加 + 関数定義 | [packages/backend/migration/1767169026317-birthday-index.js](../../../packages/backend/migration/1767169026317-birthday-index.js) |
|
||||
| 列追加のみ | [packages/backend/migration/1766652173085-add-category-to-avatar-decorations.js](../../../packages/backend/migration/1766652173085-add-category-to-avatar-decorations.js) |
|
||||
| テーブル新規作成 + FK | [packages/backend/migration/1761569941833-add-channel-muting.js](../../../packages/backend/migration/1761569941833-add-channel-muting.js) |
|
||||
|
||||
クラス命名規則は **PascalCase 名 + 13 桁タイムスタンプ** (例: `class BirthdayIndex1767169026317`)。`name` プロパティもクラス名と同一文字列にする。
|
||||
|
||||
## ステップ 7: CHANGELOG (ユーザー影響がある場合)
|
||||
|
||||
スキーマ変更がユーザーに見える挙動を生む場合のみ、`CHANGELOG.md` の `## Unreleased` → `### Server` または `### General` に 1 行追加する ([AGENTS.md §CHANGELOG](../../../AGENTS.md#changelog) 参照)。内部リファクタや純粋なインデックス追加は不要。
|
||||
@@ -1,226 +0,0 @@
|
||||
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
# Misskey configuration
|
||||
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
# ┌────────────────────────┐
|
||||
#───┘ Initial Setup Password └─────────────────────────────────────────────────────
|
||||
|
||||
# Password to initiate setting up admin account.
|
||||
# It will not be used after the initial setup is complete.
|
||||
#
|
||||
# Be sure to change this when you set up Misskey via the Internet.
|
||||
#
|
||||
# The provider of the service who sets up Misskey on behalf of the customer should
|
||||
# set this value to something unique when generating the Misskey config file,
|
||||
# and provide it to the customer.
|
||||
setupPassword: example_password_please_change_this_or_you_will_get_hacked
|
||||
|
||||
# ┌─────┐
|
||||
#───┘ URL └─────────────────────────────────────────────────────
|
||||
|
||||
# Final accessible URL seen by a user.
|
||||
url: 'http://misskey.local'
|
||||
|
||||
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
||||
# URL SETTINGS AFTER THAT!
|
||||
|
||||
# ┌───────────────────────┐
|
||||
#───┘ Port and TLS settings └───────────────────────────────────
|
||||
|
||||
#
|
||||
# Misskey requires a reverse proxy to support HTTPS connections.
|
||||
#
|
||||
# +----- https://example.tld/ ------------+
|
||||
# +------+ |+-------------+ +----------------+|
|
||||
# | User | ---> || Proxy (443) | ---> | Misskey (3000) ||
|
||||
# +------+ |+-------------+ +----------------+|
|
||||
# +---------------------------------------+
|
||||
#
|
||||
# You need to set up a reverse proxy. (e.g. nginx)
|
||||
# An encrypted connection with HTTPS is highly recommended
|
||||
# because tokens may be transferred in GET requests.
|
||||
|
||||
# The port that your Misskey server should listen on.
|
||||
port: 61812
|
||||
|
||||
# ┌──────────────────────────┐
|
||||
#───┘ PostgreSQL configuration └────────────────────────────────
|
||||
|
||||
db:
|
||||
host: db
|
||||
port: 5432
|
||||
|
||||
# Database name
|
||||
db: misskey
|
||||
|
||||
# Auth
|
||||
user: postgres
|
||||
pass: postgres
|
||||
|
||||
# Whether disable Caching queries
|
||||
#disableCache: true
|
||||
|
||||
# Extra Connection options
|
||||
#extra:
|
||||
# ssl: true
|
||||
|
||||
dbReplications: false
|
||||
|
||||
# You can configure any number of replicas here
|
||||
#dbSlaves:
|
||||
# -
|
||||
# host:
|
||||
# port:
|
||||
# db:
|
||||
# user:
|
||||
# pass:
|
||||
# -
|
||||
# host:
|
||||
# port:
|
||||
# db:
|
||||
# user:
|
||||
# pass:
|
||||
|
||||
# ┌─────────────────────┐
|
||||
#───┘ Redis configuration └─────────────────────────────────────
|
||||
|
||||
redis:
|
||||
host: redis
|
||||
port: 6379
|
||||
#family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
||||
#pass: example-pass
|
||||
#prefix: example-prefix
|
||||
#db: 1
|
||||
|
||||
#redisForPubsub:
|
||||
# host: redis
|
||||
# port: 6379
|
||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
||||
# #pass: example-pass
|
||||
# #prefix: example-prefix
|
||||
# #db: 1
|
||||
|
||||
#redisForJobQueue:
|
||||
# host: redis
|
||||
# port: 6379
|
||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
||||
# #pass: example-pass
|
||||
# #prefix: example-prefix
|
||||
# #db: 1
|
||||
|
||||
#redisForTimelines:
|
||||
# host: redis
|
||||
# port: 6379
|
||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
||||
# #pass: example-pass
|
||||
# #prefix: example-prefix
|
||||
# #db: 1
|
||||
|
||||
#redisForReactions:
|
||||
# host: redis
|
||||
# port: 6379
|
||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
||||
# #pass: example-pass
|
||||
# #prefix: example-prefix
|
||||
# #db: 1
|
||||
|
||||
# ┌───────────────────────────┐
|
||||
#───┘ MeiliSearch configuration └─────────────────────────────
|
||||
|
||||
#meilisearch:
|
||||
# host: meilisearch
|
||||
# port: 7700
|
||||
# apiKey: ''
|
||||
# ssl: true
|
||||
# index: ''
|
||||
|
||||
# ┌───────────────┐
|
||||
#───┘ ID generation └───────────────────────────────────────────
|
||||
|
||||
# You can select the ID generation method.
|
||||
# You don't usually need to change this setting, but you can
|
||||
# change it according to your preferences.
|
||||
|
||||
# Available methods:
|
||||
# aid ... Short, Millisecond accuracy
|
||||
# aidx ... Millisecond accuracy
|
||||
# meid ... Similar to ObjectID, Millisecond accuracy
|
||||
# ulid ... Millisecond accuracy
|
||||
# objectid ... This is left for backward compatibility
|
||||
|
||||
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
||||
# ID SETTINGS AFTER THAT!
|
||||
|
||||
id: 'aidx'
|
||||
|
||||
# ┌────────────────┐
|
||||
#───┘ Error tracking └──────────────────────────────────────────
|
||||
|
||||
# Sentry is available for error tracking.
|
||||
# See the Sentry documentation for more details on options.
|
||||
|
||||
#sentryForBackend:
|
||||
# enableNodeProfiling: true
|
||||
# options:
|
||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
||||
|
||||
#sentryForFrontend:
|
||||
# vueIntegration:
|
||||
# tracingOptions:
|
||||
# trackComponents: true
|
||||
# browserTracingIntegration:
|
||||
# replayIntegration:
|
||||
# options:
|
||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
||||
|
||||
# ┌─────────────────────┐
|
||||
#───┘ Other configuration └─────────────────────────────────────
|
||||
|
||||
# Whether disable HSTS
|
||||
#disableHsts: true
|
||||
|
||||
# Number of worker processes
|
||||
#clusterLimit: 1
|
||||
|
||||
# Number of threads of extra thread pool for CPU-intensive tasks (per worker)
|
||||
#threadPoolSize: 1
|
||||
|
||||
# Job concurrency per worker
|
||||
# deliverJobConcurrency: 128
|
||||
# inboxJobConcurrency: 16
|
||||
|
||||
# Job rate limiter
|
||||
# deliverJobPerSec: 128
|
||||
# inboxJobPerSec: 32
|
||||
|
||||
# Job attempts
|
||||
# deliverJobMaxAttempts: 12
|
||||
# inboxJobMaxAttempts: 8
|
||||
|
||||
# IP address family used for outgoing request (ipv4, ipv6 or dual)
|
||||
#outgoingAddressFamily: ipv4
|
||||
|
||||
# Proxy for HTTP/HTTPS
|
||||
#proxy: http://127.0.0.1:3128
|
||||
|
||||
proxyBypassHosts:
|
||||
- api.deepl.com
|
||||
- api-free.deepl.com
|
||||
- www.recaptcha.net
|
||||
- hcaptcha.com
|
||||
- challenges.cloudflare.com
|
||||
|
||||
# Proxy for SMTP/SMTPS
|
||||
#proxySmtp: http://127.0.0.1:3128 # use HTTP/1.1 CONNECT
|
||||
#proxySmtp: socks4://127.0.0.1:1080 # use SOCKS4
|
||||
#proxySmtp: socks5://127.0.0.1:1080 # use SOCKS5
|
||||
|
||||
# Media Proxy
|
||||
#mediaProxy: https://example.com/proxy
|
||||
|
||||
allowedPrivateNetworks: [
|
||||
'127.0.0.1/32'
|
||||
]
|
||||
|
||||
# Upload or download file size limits (bytes)
|
||||
#maxFileSize: 262144000
|
||||
@@ -1,11 +1,4 @@
|
||||
# misskey settings
|
||||
# MISSKEY_URL=https://example.tld/
|
||||
|
||||
# db settings
|
||||
POSTGRES_PASSWORD=example-misskey-pass
|
||||
# DATABASE_PASSWORD=${POSTGRES_PASSWORD}
|
||||
POSTGRES_USER=example-misskey-user
|
||||
# DATABASE_USER=${POSTGRES_USER}
|
||||
POSTGRES_DB=misskey
|
||||
# DATABASE_DB=${POSTGRES_DB}
|
||||
DATABASE_URL="postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}"
|
||||
|
||||
@@ -1,251 +0,0 @@
|
||||
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
# Misskey configuration
|
||||
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
# ┌─────┐
|
||||
#───┘ URL └─────────────────────────────────────────────────────
|
||||
|
||||
# Final accessible URL seen by a user.
|
||||
# You can set url from an environment variable instead.
|
||||
url: https://example.tld/
|
||||
|
||||
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
||||
# URL SETTINGS AFTER THAT!
|
||||
|
||||
# ┌───────────────────────┐
|
||||
#───┘ Port and TLS settings └───────────────────────────────────
|
||||
|
||||
#
|
||||
# Misskey requires a reverse proxy to support HTTPS connections.
|
||||
#
|
||||
# +----- https://example.tld/ ------------+
|
||||
# +------+ |+-------------+ +----------------+|
|
||||
# | User | ---> || Proxy (443) | ---> | Misskey (3000) ||
|
||||
# +------+ |+-------------+ +----------------+|
|
||||
# +---------------------------------------+
|
||||
#
|
||||
# You need to set up a reverse proxy. (e.g. nginx)
|
||||
# An encrypted connection with HTTPS is highly recommended
|
||||
# because tokens may be transferred in GET requests.
|
||||
|
||||
# The port that your Misskey server should listen on.
|
||||
port: 3000
|
||||
|
||||
# ┌──────────────────────────┐
|
||||
#───┘ PostgreSQL configuration └────────────────────────────────
|
||||
|
||||
db:
|
||||
host: db
|
||||
port: 5432
|
||||
|
||||
# Database name
|
||||
# You can set db from an environment variable instead.
|
||||
db: misskey
|
||||
|
||||
# Auth
|
||||
# You can set user and pass from environment variables instead.
|
||||
user: example-misskey-user
|
||||
pass: example-misskey-pass
|
||||
|
||||
# Whether disable Caching queries
|
||||
#disableCache: true
|
||||
|
||||
# Extra Connection options
|
||||
#extra:
|
||||
# ssl: true
|
||||
|
||||
dbReplications: false
|
||||
|
||||
# You can configure any number of replicas here
|
||||
#dbSlaves:
|
||||
# -
|
||||
# host:
|
||||
# port:
|
||||
# db:
|
||||
# user:
|
||||
# pass:
|
||||
# -
|
||||
# host:
|
||||
# port:
|
||||
# db:
|
||||
# user:
|
||||
# pass:
|
||||
|
||||
# ┌─────────────────────┐
|
||||
#───┘ Redis configuration └─────────────────────────────────────
|
||||
|
||||
redis:
|
||||
host: redis
|
||||
port: 6379
|
||||
#family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
||||
#pass: example-pass
|
||||
#prefix: example-prefix
|
||||
#db: 1
|
||||
|
||||
#redisForPubsub:
|
||||
# host: redis
|
||||
# port: 6379
|
||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
||||
# #pass: example-pass
|
||||
# #prefix: example-prefix
|
||||
# #db: 1
|
||||
|
||||
#redisForJobQueue:
|
||||
# host: redis
|
||||
# port: 6379
|
||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
||||
# #pass: example-pass
|
||||
# #prefix: example-prefix
|
||||
# #db: 1
|
||||
|
||||
#redisForTimelines:
|
||||
# host: redis
|
||||
# port: 6379
|
||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
||||
# #pass: example-pass
|
||||
# #prefix: example-prefix
|
||||
# #db: 1
|
||||
|
||||
#redisForReactions:
|
||||
# host: redis
|
||||
# port: 6379
|
||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
||||
# #pass: example-pass
|
||||
# #prefix: example-prefix
|
||||
# #db: 1
|
||||
|
||||
# ┌───────────────────────────────┐
|
||||
#───┘ Fulltext search configuration └─────────────────────────────
|
||||
|
||||
# These are the setting items for the full-text search provider.
|
||||
fulltextSearch:
|
||||
# You can select the ID generation method.
|
||||
# - sqlLike (default)
|
||||
# Use SQL-like search.
|
||||
# This is a standard feature of PostgreSQL, so no special extensions are required.
|
||||
# - sqlPgroonga
|
||||
# Use pgroonga.
|
||||
# You need to install pgroonga and configure it as a PostgreSQL extension.
|
||||
# In addition to the above, you need to create a pgroonga index on the text column of the note table.
|
||||
# see: https://pgroonga.github.io/tutorial/
|
||||
# - meilisearch
|
||||
# Use Meilisearch.
|
||||
# You need to install Meilisearch and configure.
|
||||
provider: sqlLike
|
||||
|
||||
# For Meilisearch settings.
|
||||
# If you select "meilisearch" for "fulltextSearch.provider", it must be set.
|
||||
# You can set scope to local (default value) or global
|
||||
# (include notes from remote).
|
||||
|
||||
#meilisearch:
|
||||
# host: meilisearch
|
||||
# port: 7700
|
||||
# apiKey: ''
|
||||
# ssl: true
|
||||
# index: ''
|
||||
# scope: local
|
||||
|
||||
# ┌───────────────┐
|
||||
#───┘ ID generation └───────────────────────────────────────────
|
||||
|
||||
# You can select the ID generation method.
|
||||
# You don't usually need to change this setting, but you can
|
||||
# change it according to your preferences.
|
||||
|
||||
# Available methods:
|
||||
# aid ... Short, Millisecond accuracy
|
||||
# aidx ... Millisecond accuracy
|
||||
# meid ... Similar to ObjectID, Millisecond accuracy
|
||||
# ulid ... Millisecond accuracy
|
||||
# objectid ... This is left for backward compatibility
|
||||
|
||||
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
||||
# ID SETTINGS AFTER THAT!
|
||||
|
||||
id: 'aidx'
|
||||
|
||||
# ┌────────────────┐
|
||||
#───┘ Error tracking └──────────────────────────────────────────
|
||||
|
||||
# Sentry is available for error tracking.
|
||||
# See the Sentry documentation for more details on options.
|
||||
|
||||
#sentryForBackend:
|
||||
# enableNodeProfiling: true
|
||||
# options:
|
||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
||||
|
||||
#sentryForFrontend:
|
||||
# vueIntegration:
|
||||
# tracingOptions:
|
||||
# trackComponents: true
|
||||
# browserTracingIntegration:
|
||||
# replayIntegration:
|
||||
# options:
|
||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
||||
|
||||
# ┌─────────────────────┐
|
||||
#───┘ Other configuration └─────────────────────────────────────
|
||||
|
||||
# Whether disable HSTS
|
||||
#disableHsts: true
|
||||
|
||||
# Number of worker processes
|
||||
#clusterLimit: 1
|
||||
|
||||
# Number of threads of extra thread pool for CPU-intensive tasks (per worker)
|
||||
#threadPoolSize: 1
|
||||
|
||||
# Job concurrency per worker
|
||||
# deliverJobConcurrency: 128
|
||||
# inboxJobConcurrency: 16
|
||||
|
||||
# Job rate limiter
|
||||
# deliverJobPerSec: 128
|
||||
# inboxJobPerSec: 32
|
||||
|
||||
# Job attempts
|
||||
# deliverJobMaxAttempts: 12
|
||||
# inboxJobMaxAttempts: 8
|
||||
|
||||
# IP address family used for outgoing request (ipv4, ipv6 or dual)
|
||||
#outgoingAddressFamily: ipv4
|
||||
|
||||
# Proxy for HTTP/HTTPS
|
||||
#proxy: http://127.0.0.1:3128
|
||||
|
||||
proxyBypassHosts:
|
||||
- api.deepl.com
|
||||
- api-free.deepl.com
|
||||
- www.recaptcha.net
|
||||
- hcaptcha.com
|
||||
- challenges.cloudflare.com
|
||||
|
||||
# Proxy for SMTP/SMTPS
|
||||
#proxySmtp: http://127.0.0.1:3128 # use HTTP/1.1 CONNECT
|
||||
#proxySmtp: socks4://127.0.0.1:1080 # use SOCKS4
|
||||
#proxySmtp: socks5://127.0.0.1:1080 # use SOCKS5
|
||||
|
||||
# Media Proxy
|
||||
#mediaProxy: https://example.com/proxy
|
||||
|
||||
# For security reasons, uploading attachments from the intranet is prohibited,
|
||||
# but exceptions can be made from the following settings. Default value is "undefined".
|
||||
# Read changelog to learn more (Improvements of 12.90.0 (2021/09/04)).
|
||||
#allowedPrivateNetworks: [
|
||||
# '127.0.0.1/32'
|
||||
#]
|
||||
|
||||
# Upload or download file size limits (bytes)
|
||||
#maxFileSize: 262144000
|
||||
|
||||
# Log settings
|
||||
# logging:
|
||||
# sql:
|
||||
# # Outputs query parameters during SQL execution to the log.
|
||||
# # default: false
|
||||
# enableQueryParamLogging: false
|
||||
# # Disable query truncation. If set to true, the full text of the query will be output to the log.
|
||||
# # default: false
|
||||
# disableQueryTruncation: false
|
||||
@@ -2,77 +2,6 @@
|
||||
# Misskey configuration
|
||||
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
# ┌──────────────────────────────┐
|
||||
#───┘ a boring but important thing └────────────────────────────
|
||||
|
||||
#
|
||||
# First of all, let me tell you a story that may possibly be
|
||||
# boring to you and possibly important to you.
|
||||
#
|
||||
# Misskey is licensed under the AGPLv3 license. This license is
|
||||
# known to be often misunderstood. Please read the following
|
||||
# instructions carefully and select the appropriate option so
|
||||
# that you do not negligently cause a license violation.
|
||||
#
|
||||
|
||||
# --------
|
||||
# Option 1: If you host Misskey AS-IS (without any changes to
|
||||
# the source code. forks are not included).
|
||||
#
|
||||
# Step 1: Congratulations! You don't need to do anything.
|
||||
|
||||
# --------
|
||||
# Option 2: If you have made changes to the source code (forks
|
||||
# are included) and publish a Git repository of source
|
||||
# code. There should be no access restrictions on
|
||||
# this repository. Strictly speaking, it doesn't have
|
||||
# to be a Git repository, but you'll probably use Git!
|
||||
#
|
||||
# Step 1: Build and run the Misskey server first.
|
||||
# Step 2: Open <https://your.misskey.example/admin/settings> in
|
||||
# your browser with the administrator account.
|
||||
# Step 3: Enter the URL of your Git repository in the
|
||||
# "Repository URL" field.
|
||||
|
||||
# --------
|
||||
# Option 3: If neither of the above applies to you.
|
||||
# (In this case, the source code should be published
|
||||
# on the Misskey interface. IT IS NOT ENOUGH TO
|
||||
# DISCLOSE THE SOURCE CODE WHEN A USER REQUESTS IT BY
|
||||
# E-MAIL OR OTHER MEANS. If you are not satisfied
|
||||
# with this, it is recommended that you read the
|
||||
# license again carefully. Anyway, enabling this
|
||||
# option will automatically generate and publish a
|
||||
# tarball at build time, protecting you from
|
||||
# inadvertent license violations. (There is no legal
|
||||
# guarantee, of course.) The tarball will generated
|
||||
# from the root directory of your codebase. So it is
|
||||
# also recommended to check <built/tarball> directory
|
||||
# once after building and before activating the server
|
||||
# to avoid ACCIDENTAL LEAKING OF SENSITIVE INFORMATION.
|
||||
# To prevent certain files from being included in the
|
||||
# tarball, add a glob pattern after line 15 in
|
||||
# <scripts/tarball.mjs>. DO NOT FORGET TO BUILD AFTER
|
||||
# ENABLING THIS OPTION!)
|
||||
#
|
||||
# Step 1: Uncomment the following line.
|
||||
#
|
||||
# publishTarballInsteadOfProvideRepositoryUrl: true
|
||||
|
||||
# ┌────────────────────────┐
|
||||
#───┘ Initial Setup Password └─────────────────────────────────────────────────────
|
||||
|
||||
# Password to initiate setting up admin account.
|
||||
# It will not be used after the initial setup is complete.
|
||||
#
|
||||
# Be sure to change this when you set up Misskey via the Internet.
|
||||
#
|
||||
# The provider of the service who sets up Misskey on behalf of the customer should
|
||||
# set this value to something unique when generating the Misskey config file,
|
||||
# and provide it to the customer.
|
||||
#
|
||||
# setupPassword: example_password_please_change_this_or_you_will_get_hacked
|
||||
|
||||
# ┌─────┐
|
||||
#───┘ URL └─────────────────────────────────────────────────────
|
||||
|
||||
@@ -101,58 +30,6 @@ url: https://example.tld/
|
||||
# The port that your Misskey server should listen on.
|
||||
port: 3000
|
||||
|
||||
# You can also use UNIX domain socket.
|
||||
# socket: /path/to/misskey.sock
|
||||
# chmodSocket: '777'
|
||||
|
||||
# Proxy trust settings
|
||||
#
|
||||
# Specifies the IP addresses that Misskey will use as trusted
|
||||
# reverse proxies (e.g., nginx, Cloudflare). This affects how
|
||||
# Misskey determines the source IP for each request and is used
|
||||
# for important rate limiting and security features. If the value
|
||||
# is not set correctly, Misskey may use the IP address of the
|
||||
# reverse proxy instead of the actual source IP, which may lead to
|
||||
# unintended rate limiting or security vulnerabilities.
|
||||
# By default, the loopback network and private network address
|
||||
# ranges shown below are trusted.
|
||||
# If you are using a single reverse proxy and it is on the same
|
||||
# machine or the same private network as Misskey, it is unlikely you
|
||||
# need to change this setting, and the default setting is fine.
|
||||
# Also, if you are using multiple reverse proxy servers and they are
|
||||
# all on the same private network as Misskey, the default setting
|
||||
# is fine.
|
||||
# However, if you are using a reverse proxy server that accesses
|
||||
# Misskey web servers and streaming servers via public IP addresses
|
||||
# (for example, Cloudflare), you must set this variable.
|
||||
# When changing this setting, you can use one of the following values:
|
||||
#
|
||||
# - true: Trust all proxies
|
||||
# - false: Do not trust any proxies
|
||||
# - IP address, IP address range, or array of them: Trust hops that
|
||||
# match the specified criteria.
|
||||
# - Integer: Trust the nth hop from the front-facing proxy server as
|
||||
# the client.
|
||||
# For more information on how to configure this setting, please refer
|
||||
# to the Fastify documentation:
|
||||
# https://fastify.dev/docs/latest/Reference/Server/#trustproxy
|
||||
#
|
||||
# Note that if this variable is set, it overrides the default range,
|
||||
# so if you have both an external reverse proxy and a proxy on the
|
||||
# local host, you must include both IPs (or IP ranges).
|
||||
#
|
||||
#trustProxy:
|
||||
# - '10.0.0.0/8'
|
||||
# - '172.16.0.0/12'
|
||||
# - '192.168.0.0/16'
|
||||
# - '127.0.0.1/32'
|
||||
# - '::1/128'
|
||||
# - 'fc00::/7'
|
||||
# # Example: If you are using some external reverse proxies like CDNs,
|
||||
# # you may need to add the CDN IP ranges here.
|
||||
# # If you're using Cloudflare, you can find IP Ranges at:
|
||||
# # https://www.cloudflare.com/ips/
|
||||
|
||||
# ┌──────────────────────────┐
|
||||
#───┘ PostgreSQL configuration └────────────────────────────────
|
||||
|
||||
@@ -174,23 +51,6 @@ db:
|
||||
#extra:
|
||||
# ssl: true
|
||||
|
||||
dbReplications: false
|
||||
|
||||
# You can configure any number of replicas here
|
||||
#dbSlaves:
|
||||
# -
|
||||
# host:
|
||||
# port:
|
||||
# db:
|
||||
# user:
|
||||
# pass:
|
||||
# -
|
||||
# host:
|
||||
# port:
|
||||
# db:
|
||||
# user:
|
||||
# pass:
|
||||
|
||||
# ┌─────────────────────┐
|
||||
#───┘ Redis configuration └─────────────────────────────────────
|
||||
|
||||
@@ -201,80 +61,16 @@ redis:
|
||||
#pass: example-pass
|
||||
#prefix: example-prefix
|
||||
#db: 1
|
||||
# You can specify more ioredis options...
|
||||
#username: example-username
|
||||
|
||||
#redisForPubsub:
|
||||
# ┌─────────────────────────────┐
|
||||
#───┘ Elasticsearch configuration └─────────────────────────────
|
||||
|
||||
#elasticsearch:
|
||||
# host: localhost
|
||||
# port: 6379
|
||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
||||
# #pass: example-pass
|
||||
# #prefix: example-prefix
|
||||
# #db: 1
|
||||
# # You can specify more ioredis options...
|
||||
# #username: example-username
|
||||
|
||||
#redisForJobQueue:
|
||||
# host: localhost
|
||||
# port: 6379
|
||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
||||
# #pass: example-pass
|
||||
# #prefix: example-prefix
|
||||
# #db: 1
|
||||
# # You can specify more ioredis options...
|
||||
# #username: example-username
|
||||
|
||||
#redisForTimelines:
|
||||
# host: localhost
|
||||
# port: 6379
|
||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
||||
# #pass: example-pass
|
||||
# #prefix: example-prefix
|
||||
# #db: 1
|
||||
# # You can specify more ioredis options...
|
||||
# #username: example-username
|
||||
|
||||
#redisForReactions:
|
||||
# host: localhost
|
||||
# port: 6379
|
||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
||||
# #pass: example-pass
|
||||
# #prefix: example-prefix
|
||||
# #db: 1
|
||||
# # You can specify more ioredis options...
|
||||
# #username: example-username
|
||||
|
||||
# ┌───────────────────────────────┐
|
||||
#───┘ Fulltext search configuration └─────────────────────────────
|
||||
|
||||
# These are the setting items for the full-text search provider.
|
||||
fulltextSearch:
|
||||
# You can select the ID generation method.
|
||||
# - sqlLike (default)
|
||||
# Use SQL-like search.
|
||||
# This is a standard feature of PostgreSQL, so no special extensions are required.
|
||||
# - sqlPgroonga
|
||||
# Use pgroonga.
|
||||
# You need to install pgroonga and configure it as a PostgreSQL extension.
|
||||
# In addition to the above, you need to create a pgroonga index on the text column of the note table.
|
||||
# see: https://pgroonga.github.io/tutorial/
|
||||
# - meilisearch
|
||||
# Use Meilisearch.
|
||||
# You need to install Meilisearch and configure.
|
||||
provider: sqlLike
|
||||
|
||||
# For Meilisearch settings.
|
||||
# If you select "meilisearch" for "fulltextSearch.provider", it must be set.
|
||||
# You can set scope to local (default value) or global
|
||||
# (include notes from remote).
|
||||
|
||||
#meilisearch:
|
||||
# host: localhost
|
||||
# port: 7700
|
||||
# apiKey: ''
|
||||
# ssl: true
|
||||
# index: ''
|
||||
# scope: local
|
||||
# port: 9200
|
||||
# ssl: false
|
||||
# user:
|
||||
# pass:
|
||||
|
||||
# ┌───────────────┐
|
||||
#───┘ ID generation └───────────────────────────────────────────
|
||||
@@ -285,7 +81,6 @@ fulltextSearch:
|
||||
|
||||
# Available methods:
|
||||
# aid ... Short, Millisecond accuracy
|
||||
# aidx ... Millisecond accuracy
|
||||
# meid ... Similar to ObjectID, Millisecond accuracy
|
||||
# ulid ... Millisecond accuracy
|
||||
# objectid ... This is left for backward compatibility
|
||||
@@ -293,27 +88,7 @@ fulltextSearch:
|
||||
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
||||
# ID SETTINGS AFTER THAT!
|
||||
|
||||
id: 'aidx'
|
||||
|
||||
# ┌────────────────┐
|
||||
#───┘ Error tracking └──────────────────────────────────────────
|
||||
|
||||
# Sentry is available for error tracking.
|
||||
# See the Sentry documentation for more details on options.
|
||||
|
||||
#sentryForBackend:
|
||||
# enableNodeProfiling: true
|
||||
# options:
|
||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
||||
|
||||
#sentryForFrontend:
|
||||
# vueIntegration:
|
||||
# tracingOptions:
|
||||
# trackComponents: true
|
||||
# browserTracingIntegration:
|
||||
# replayIntegration:
|
||||
# options:
|
||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
||||
id: 'aid'
|
||||
|
||||
# ┌─────────────────────┐
|
||||
#───┘ Other configuration └─────────────────────────────────────
|
||||
@@ -321,47 +96,36 @@ id: 'aidx'
|
||||
# Whether disable HSTS
|
||||
#disableHsts: true
|
||||
|
||||
# Enable internal IP-based rate limiting (default: true)
|
||||
# To configure them in reverse proxy instead, set this to false.
|
||||
#enableIpRateLimit: true
|
||||
|
||||
# Number of worker processes
|
||||
#clusterLimit: 1
|
||||
|
||||
# Number of threads of extra thread pool for CPU-intensive tasks (per worker)
|
||||
#threadPoolSize: 1
|
||||
|
||||
# Job concurrency per worker
|
||||
#deliverJobConcurrency: 128
|
||||
#inboxJobConcurrency: 16
|
||||
#relationshipJobConcurrency: 16
|
||||
# What's relationshipJob?:
|
||||
# Follow, unfollow, block and unblock(ings) while following-imports, etc. or account migrations.
|
||||
# deliverJobConcurrency: 128
|
||||
# inboxJobConcurrency: 16
|
||||
|
||||
# Job rate limiter
|
||||
#deliverJobPerSec: 128
|
||||
#inboxJobPerSec: 32
|
||||
#relationshipJobPerSec: 64
|
||||
# deliverJobPerSec: 128
|
||||
# inboxJobPerSec: 16
|
||||
|
||||
# Job attempts
|
||||
#deliverJobMaxAttempts: 12
|
||||
#inboxJobMaxAttempts: 8
|
||||
|
||||
# Local address used for outgoing requests
|
||||
#outgoingAddress: 127.0.0.1
|
||||
# deliverJobMaxAttempts: 12
|
||||
# inboxJobMaxAttempts: 8
|
||||
|
||||
# IP address family used for outgoing request (ipv4, ipv6 or dual)
|
||||
#outgoingAddressFamily: ipv4
|
||||
|
||||
# Syslog option
|
||||
#syslog:
|
||||
# host: localhost
|
||||
# port: 514
|
||||
|
||||
# Proxy for HTTP/HTTPS
|
||||
#proxy: http://127.0.0.1:3128
|
||||
|
||||
proxyBypassHosts:
|
||||
- api.deepl.com
|
||||
- api-free.deepl.com
|
||||
- www.recaptcha.net
|
||||
- hcaptcha.com
|
||||
- challenges.cloudflare.com
|
||||
#proxyBypassHosts: [
|
||||
# 'example.com',
|
||||
# '192.0.2.8'
|
||||
#]
|
||||
|
||||
# Proxy for SMTP/SMTPS
|
||||
#proxySmtp: http://127.0.0.1:3128 # use HTTP/1.1 CONNECT
|
||||
@@ -369,36 +133,17 @@ proxyBypassHosts:
|
||||
#proxySmtp: socks5://127.0.0.1:1080 # use SOCKS5
|
||||
|
||||
# Media Proxy
|
||||
# Reference Implementation: https://github.com/misskey-dev/media-proxy
|
||||
# * Deliver a common cache between instances
|
||||
# * Perform image compression (on a different server resource than the main process)
|
||||
#mediaProxy: https://example.com/proxy
|
||||
|
||||
# Movie Thumbnail Generation URL
|
||||
# There is no reference implementation.
|
||||
# For example, Misskey will point to the following URL:
|
||||
# https://example.com/thumbnail.webp?thumbnail=1&url=https%3A%2F%2Fstorage.example.com%2Fpath%2Fto%2Fvideo.mp4
|
||||
#videoThumbnailGenerator: https://example.com
|
||||
# Proxy remote files (default: false)
|
||||
#proxyRemoteFiles: true
|
||||
|
||||
# Sign to ActivityPub GET request (default: false)
|
||||
#signToActivityPubGet: true
|
||||
|
||||
# For security reasons, uploading attachments from the intranet is prohibited,
|
||||
# but exceptions can be made from the following settings. Default value is "undefined".
|
||||
# Read changelog to learn more (Improvements of 12.90.0 (2021/09/04)).
|
||||
#allowedPrivateNetworks: [
|
||||
# '127.0.0.1/32'
|
||||
#]
|
||||
|
||||
# Upload or download file size limits (bytes)
|
||||
#maxFileSize: 262144000
|
||||
|
||||
# PID File of master process
|
||||
#pidFile: /tmp/misskey.pid
|
||||
|
||||
# Log settings
|
||||
# logging:
|
||||
# sql:
|
||||
# # Outputs query parameters during SQL execution to the log.
|
||||
# # default: false
|
||||
# enableQueryParamLogging: false
|
||||
# # Disable query truncation. If set to true, the full text of the query will be output to the log.
|
||||
# # default: false
|
||||
# disableQueryTruncation: false
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
FROM mcr.microsoft.com/devcontainers/javascript-node:4.0.3-24-trixie
|
||||
@@ -1,53 +0,0 @@
|
||||
services:
|
||||
app:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
|
||||
volumes:
|
||||
- ../:/workspace:cached
|
||||
- node_modules:/workspace/node_modules
|
||||
|
||||
command: sleep infinity
|
||||
|
||||
networks:
|
||||
- internal_network
|
||||
- external_network
|
||||
|
||||
redis:
|
||||
restart: unless-stopped
|
||||
image: redis:7-alpine
|
||||
networks:
|
||||
- internal_network
|
||||
volumes:
|
||||
- redis-data:/data
|
||||
healthcheck:
|
||||
test: "redis-cli ping"
|
||||
interval: 5s
|
||||
retries: 20
|
||||
|
||||
db:
|
||||
restart: unless-stopped
|
||||
image: postgres:18-alpine
|
||||
networks:
|
||||
- internal_network
|
||||
environment:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_DB: misskey
|
||||
volumes:
|
||||
- postgres-data:/var/lib/postgresql
|
||||
healthcheck:
|
||||
test: "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"
|
||||
interval: 5s
|
||||
retries: 20
|
||||
|
||||
volumes:
|
||||
postgres-data:
|
||||
redis-data:
|
||||
node_modules:
|
||||
|
||||
networks:
|
||||
internal_network:
|
||||
internal: true
|
||||
external_network:
|
||||
@@ -1,27 +0,0 @@
|
||||
{
|
||||
"name": "Misskey",
|
||||
"dockerComposeFile": "compose.yml",
|
||||
"service": "app",
|
||||
"workspaceFolder": "/workspace",
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/node:1": {
|
||||
"version": "22.15.0"
|
||||
},
|
||||
"ghcr.io/devcontainers-extra/features/pnpm:2": {
|
||||
"version": "10.10.0"
|
||||
}
|
||||
},
|
||||
"forwardPorts": [3000],
|
||||
"postCreateCommand": "/bin/bash .devcontainer/init.sh",
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"editorconfig.editorconfig",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"Vue.volar",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"mrmlnc.vscode-json5"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,213 +0,0 @@
|
||||
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
# Misskey configuration
|
||||
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
# ┌─────┐
|
||||
#───┘ URL └─────────────────────────────────────────────────────
|
||||
|
||||
# Final accessible URL seen by a user.
|
||||
url: http://127.0.0.1:3000/
|
||||
|
||||
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
||||
# URL SETTINGS AFTER THAT!
|
||||
|
||||
# ┌───────────────────────┐
|
||||
#───┘ Port and TLS settings └───────────────────────────────────
|
||||
|
||||
#
|
||||
# Misskey requires a reverse proxy to support HTTPS connections.
|
||||
#
|
||||
# +----- https://example.tld/ ------------+
|
||||
# +------+ |+-------------+ +----------------+|
|
||||
# | User | ---> || Proxy (443) | ---> | Misskey (3000) ||
|
||||
# +------+ |+-------------+ +----------------+|
|
||||
# +---------------------------------------+
|
||||
#
|
||||
# You need to set up a reverse proxy. (e.g. nginx)
|
||||
# An encrypted connection with HTTPS is highly recommended
|
||||
# because tokens may be transferred in GET requests.
|
||||
|
||||
# The port that your Misskey server should listen on.
|
||||
port: 3000
|
||||
|
||||
# ┌──────────────────────────┐
|
||||
#───┘ PostgreSQL configuration └────────────────────────────────
|
||||
|
||||
db:
|
||||
host: db
|
||||
port: 5432
|
||||
|
||||
# Database name
|
||||
db: misskey
|
||||
|
||||
# Auth
|
||||
user: postgres
|
||||
pass: postgres
|
||||
|
||||
# Whether disable Caching queries
|
||||
#disableCache: true
|
||||
|
||||
# Extra Connection options
|
||||
#extra:
|
||||
# ssl: true
|
||||
|
||||
dbReplications: false
|
||||
|
||||
# You can configure any number of replicas here
|
||||
#dbSlaves:
|
||||
# -
|
||||
# host:
|
||||
# port:
|
||||
# db:
|
||||
# user:
|
||||
# pass:
|
||||
# -
|
||||
# host:
|
||||
# port:
|
||||
# db:
|
||||
# user:
|
||||
# pass:
|
||||
|
||||
# ┌─────────────────────┐
|
||||
#───┘ Redis configuration └─────────────────────────────────────
|
||||
|
||||
redis:
|
||||
host: redis
|
||||
port: 6379
|
||||
#family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
||||
#pass: example-pass
|
||||
#prefix: example-prefix
|
||||
#db: 1
|
||||
|
||||
#redisForPubsub:
|
||||
# host: redis
|
||||
# port: 6379
|
||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
||||
# #pass: example-pass
|
||||
# #prefix: example-prefix
|
||||
# #db: 1
|
||||
|
||||
#redisForJobQueue:
|
||||
# host: redis
|
||||
# port: 6379
|
||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
||||
# #pass: example-pass
|
||||
# #prefix: example-prefix
|
||||
# #db: 1
|
||||
|
||||
#redisForTimelines:
|
||||
# host: redis
|
||||
# port: 6379
|
||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
||||
# #pass: example-pass
|
||||
# #prefix: example-prefix
|
||||
# #db: 1
|
||||
|
||||
#redisForReactions:
|
||||
# host: redis
|
||||
# port: 6379
|
||||
# #family: 0 # 0=Both, 4=IPv4, 6=IPv6
|
||||
# #pass: example-pass
|
||||
# #prefix: example-prefix
|
||||
# #db: 1
|
||||
|
||||
# ┌───────────────────────────┐
|
||||
#───┘ MeiliSearch configuration └─────────────────────────────
|
||||
|
||||
#meilisearch:
|
||||
# host: meilisearch
|
||||
# port: 7700
|
||||
# apiKey: ''
|
||||
# ssl: true
|
||||
# index: ''
|
||||
|
||||
# ┌───────────────┐
|
||||
#───┘ ID generation └───────────────────────────────────────────
|
||||
|
||||
# You can select the ID generation method.
|
||||
# You don't usually need to change this setting, but you can
|
||||
# change it according to your preferences.
|
||||
|
||||
# Available methods:
|
||||
# aid ... Short, Millisecond accuracy
|
||||
# aidx ... Millisecond accuracy
|
||||
# meid ... Similar to ObjectID, Millisecond accuracy
|
||||
# ulid ... Millisecond accuracy
|
||||
# objectid ... This is left for backward compatibility
|
||||
|
||||
# ONCE YOU HAVE STARTED THE INSTANCE, DO NOT CHANGE THE
|
||||
# ID SETTINGS AFTER THAT!
|
||||
|
||||
id: 'aidx'
|
||||
|
||||
# ┌────────────────┐
|
||||
#───┘ Error tracking └──────────────────────────────────────────
|
||||
|
||||
# Sentry is available for error tracking.
|
||||
# See the Sentry documentation for more details on options.
|
||||
|
||||
#sentryForBackend:
|
||||
# enableNodeProfiling: true
|
||||
# options:
|
||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
||||
|
||||
#sentryForFrontend:
|
||||
# vueIntegration:
|
||||
# tracingOptions:
|
||||
# trackComponents: true
|
||||
# browserTracingIntegration:
|
||||
# replayIntegration:
|
||||
# options:
|
||||
# dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0'
|
||||
|
||||
# ┌─────────────────────┐
|
||||
#───┘ Other configuration └─────────────────────────────────────
|
||||
|
||||
# Whether disable HSTS
|
||||
#disableHsts: true
|
||||
|
||||
# Number of worker processes
|
||||
#clusterLimit: 1
|
||||
|
||||
# Number of threads of extra thread pool for CPU-intensive tasks (per worker)
|
||||
#threadPoolSize: 1
|
||||
|
||||
# Job concurrency per worker
|
||||
# deliverJobConcurrency: 128
|
||||
# inboxJobConcurrency: 16
|
||||
|
||||
# Job rate limiter
|
||||
# deliverJobPerSec: 128
|
||||
# inboxJobPerSec: 32
|
||||
|
||||
# Job attempts
|
||||
# deliverJobMaxAttempts: 12
|
||||
# inboxJobMaxAttempts: 8
|
||||
|
||||
# IP address family used for outgoing request (ipv4, ipv6 or dual)
|
||||
#outgoingAddressFamily: ipv4
|
||||
|
||||
# Proxy for HTTP/HTTPS
|
||||
#proxy: http://127.0.0.1:3128
|
||||
|
||||
proxyBypassHosts:
|
||||
- api.deepl.com
|
||||
- api-free.deepl.com
|
||||
- www.recaptcha.net
|
||||
- hcaptcha.com
|
||||
- challenges.cloudflare.com
|
||||
|
||||
# Proxy for SMTP/SMTPS
|
||||
#proxySmtp: http://127.0.0.1:3128 # use HTTP/1.1 CONNECT
|
||||
#proxySmtp: socks4://127.0.0.1:1080 # use SOCKS4
|
||||
#proxySmtp: socks5://127.0.0.1:1080 # use SOCKS5
|
||||
|
||||
# Media Proxy
|
||||
#mediaProxy: https://example.com/proxy
|
||||
|
||||
allowedPrivateNetworks: [
|
||||
'127.0.0.1/32'
|
||||
]
|
||||
|
||||
# Upload or download file size limits (bytes)
|
||||
#maxFileSize: 262144000
|
||||
@@ -1,15 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -xe
|
||||
|
||||
sudo chown node node_modules
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install libgtk2.0-0 libgtk-3-0 libgbm-dev libnotify-dev libnss3 libxss1 libasound2 libxtst6 xauth xvfb
|
||||
git config --global --add safe.directory /workspace
|
||||
git submodule update --init
|
||||
pnpm config set store-dir /home/node/.local/share/pnpm/store
|
||||
pnpm install --frozen-lockfile
|
||||
cp .devcontainer/devcontainer.yml .config/default.yml
|
||||
pnpm build
|
||||
pnpm migrate
|
||||
pnpm exec cypress install
|
||||
@@ -6,26 +6,10 @@
|
||||
Dockerfile
|
||||
build/
|
||||
built/
|
||||
src-js/
|
||||
db/
|
||||
.devcontainer/compose.yml
|
||||
docker-compose.yml
|
||||
elasticsearch/
|
||||
node_modules/
|
||||
packages/*/node_modules
|
||||
redis/
|
||||
files/
|
||||
fluent-emojis/
|
||||
.pnp.*
|
||||
|
||||
# .yarn関連
|
||||
.yarn/*
|
||||
!.yarn/patches
|
||||
!.yarn/plugins
|
||||
!.yarn/releases
|
||||
!.yarn/sdks
|
||||
!.yarn/versions
|
||||
|
||||
.pnpm-store
|
||||
|
||||
.idea/
|
||||
packages/*/.vscode/
|
||||
packages/backend/test/compose.yml
|
||||
misskey-assets/
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
DKL-DI-0005
|
||||
DKL-DI-0006
|
||||
DKL-LI-0003
|
||||
@@ -5,15 +5,6 @@ indent_style = tab
|
||||
indent_size = 2
|
||||
charset = utf-8
|
||||
insert_final_newline = true
|
||||
end_of_line = lf
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.{yml,yaml}]
|
||||
[*.yml]
|
||||
indent_style = space
|
||||
|
||||
[packages/backend/migration/*.js]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -5,4 +5,3 @@
|
||||
*.glb -diff -text
|
||||
*.blend -diff -text
|
||||
*.afdesign -diff -text
|
||||
* text=auto eol=lf
|
||||
|
||||
3
.github/FUNDING.yml
vendored
Normal file
3
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
patreon: syuilo
|
||||
42
.github/ISSUE_TEMPLATE/01_bug-report.md
vendored
Normal file
42
.github/ISSUE_TEMPLATE/01_bug-report.md
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
---
|
||||
name: 🐛 Bug Report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ⚠️bug?
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!--
|
||||
Thanks for reporting!
|
||||
First, in order to avoid duplicate Issues, please search to see if the problem you found has already been reported.
|
||||
-->
|
||||
|
||||
## 💡 Summary
|
||||
|
||||
<!-- Tell us what the bug is -->
|
||||
|
||||
## 🥰 Expected Behavior
|
||||
|
||||
<!--- Tell us what should happen -->
|
||||
|
||||
## 🤬 Actual Behavior
|
||||
|
||||
<!--
|
||||
Tell us what happens instead of the expected behavior.
|
||||
Please include errors from the developer console and/or server log files if you have access to them.
|
||||
-->
|
||||
|
||||
## 📝 Steps to Reproduce
|
||||
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
|
||||
## 📌 Environment
|
||||
|
||||
<!-- Tell us where on the platform it happens -->
|
||||
|
||||
Misskey version:
|
||||
Your OS:
|
||||
Your browser:
|
||||
97
.github/ISSUE_TEMPLATE/01_bug-report.yml
vendored
97
.github/ISSUE_TEMPLATE/01_bug-report.yml
vendored
@@ -1,97 +0,0 @@
|
||||
name: 🐛 Bug Report
|
||||
description: Create a report to help us improve
|
||||
labels: ["⚠️bug?"]
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for reporting!
|
||||
First, in order to avoid duplicate Issues, please search to see if the problem you found has already been reported.
|
||||
Also, If you are NOT owner/admin of server, PLEASE DONT REPORT SERVER SPECIFIC ISSUES TO HERE! (e.g. feature XXX is not working in misskey.example) Please try with another misskey servers, and if your issue is only reproducible with specific server, contact your server's owner/admin first.
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 💡 Summary
|
||||
description: Tell us what the bug is
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 🥰 Expected Behavior
|
||||
description: Tell us what should happen
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 🤬 Actual Behavior
|
||||
description: |
|
||||
Tell us what happens instead of the expected behavior.
|
||||
Please include errors from the developer console and/or server log files if you have access to them.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 📝 Steps to Reproduce
|
||||
placeholder: |
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 💻 Frontend Environment
|
||||
description: |
|
||||
Tell us where on the platform it happens
|
||||
DO NOT WRITE "latest". Please provide the specific version.
|
||||
|
||||
Examples:
|
||||
* Model and OS of the device(s): MacBook Pro (14inch, 2021), macOS Ventura 13.4
|
||||
* Browser: Chrome 113.0.5672.126
|
||||
* Server URL: misskey.example.com
|
||||
* Misskey: 2026.x.x
|
||||
value: |
|
||||
* Model and OS of the device(s):
|
||||
* Browser:
|
||||
* Server URL:
|
||||
* Misskey:
|
||||
render: markdown
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 🛰 Backend Environment (for server admin)
|
||||
description: |
|
||||
Tell us where on the platform it happens
|
||||
DO NOT WRITE "latest". Please provide the specific version.
|
||||
If you are using a managed service, put that after the version.
|
||||
|
||||
Examples:
|
||||
* Installation Method or Hosting Service: docker compose, k8s/docker, systemd, "Misskey install shell script", development environment
|
||||
* Misskey: 2026.x.x
|
||||
* Node: 20.x.x
|
||||
* PostgreSQL: 18.x.x
|
||||
* Redis: 7.x.x
|
||||
* OS and Architecture: Ubuntu 24.04.2 LTS aarch64
|
||||
value: |
|
||||
* Installation Method or Hosting Service:
|
||||
* Misskey:
|
||||
* Node:
|
||||
* PostgreSQL:
|
||||
* Redis:
|
||||
* OS and Architecture:
|
||||
render: markdown
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Do you want to address this bug yourself?
|
||||
options:
|
||||
- label: Yes, I will patch the bug myself and send a pull request
|
||||
12
.github/ISSUE_TEMPLATE/02_feature-request.md
vendored
Normal file
12
.github/ISSUE_TEMPLATE/02_feature-request.md
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
name: ✨ Feature Request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: ✨Feature
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
<!-- Tell us what the suggestion is -->
|
||||
22
.github/ISSUE_TEMPLATE/02_feature-request.yml
vendored
22
.github/ISSUE_TEMPLATE/02_feature-request.yml
vendored
@@ -1,22 +0,0 @@
|
||||
name: ✨ Feature Request
|
||||
description: Suggest an idea for this project
|
||||
labels: ["✨Feature"]
|
||||
|
||||
body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Summary
|
||||
description: Tell us what the suggestion is
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Purpose
|
||||
description: Describe the specific problem or need you think this feature will solve, and who it will help.
|
||||
validations:
|
||||
required: true
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Do you want to implement this feature yourself?
|
||||
options:
|
||||
- label: Yes, I will implement this by myself and send a pull request
|
||||
7
.github/ISSUE_TEMPLATE/config.yml
vendored
7
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,8 +1,7 @@
|
||||
contact_links:
|
||||
- name: 👪 Misskey Forum
|
||||
url: https://forum.misskey.io/
|
||||
about: Ask questions and share knowledge
|
||||
- name: 💬 Misskey official Discord
|
||||
url: https://discord.gg/Wp8gVStHW3
|
||||
about: Chat freely about Misskey
|
||||
# 仮
|
||||
- name: 💬 Start discussion
|
||||
url: https://github.com/misskey-dev/misskey/discussions
|
||||
about: The official forum to join conversation and ask question
|
||||
|
||||
17
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
17
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<!-- ℹ お読みください / README
|
||||
PRありがとうございます! PRを作成する前に、コントリビューションガイドをご確認ください:
|
||||
Thank you for your PR! Before creating a PR, please check the contribution guide:
|
||||
https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md
|
||||
-->
|
||||
|
||||
# What
|
||||
<!-- このPRで何をしたのか? どう変わるのか? -->
|
||||
<!-- What did you do with this PR? How will it change things? -->
|
||||
|
||||
# Why
|
||||
<!-- なぜそうするのか? どういう意図なのか? 何が困っているのか? -->
|
||||
<!-- Why do you do it? What are your intentions? What is the problem? -->
|
||||
|
||||
# Additional info (optional)
|
||||
<!-- テスト観点など -->
|
||||
<!-- Test perspective, etc -->
|
||||
23
.github/PULL_REQUEST_TEMPLATE/01_bug.md
vendored
23
.github/PULL_REQUEST_TEMPLATE/01_bug.md
vendored
@@ -1,23 +0,0 @@
|
||||
<!-- ℹ お読みください / README
|
||||
PRありがとうございます! PRを作成する前に、コントリビューションガイドをご確認ください:
|
||||
Thank you for your PR! Before creating a PR, please check the contribution guide:
|
||||
https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md
|
||||
-->
|
||||
|
||||
## What
|
||||
<!-- このPRで何をしたのか? どう変わるのか? -->
|
||||
<!-- What did you do with this PR? How will it change things? -->
|
||||
|
||||
## Why
|
||||
<!-- なぜそうするのか? どういう意図なのか? 何が困っているのか? -->
|
||||
<!-- Why do you do it? What are your intentions? What is the problem? -->
|
||||
|
||||
## Additional info (optional)
|
||||
<!-- テスト観点など -->
|
||||
<!-- Test perspective, etc -->
|
||||
|
||||
## Checklist
|
||||
- [ ] Read the [contribution guide](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md)
|
||||
- [ ] Test working in a local environment
|
||||
- [ ] (If needed) Update CHANGELOG.md
|
||||
- [ ] (If possible) Add tests
|
||||
23
.github/PULL_REQUEST_TEMPLATE/02_enhance.md
vendored
23
.github/PULL_REQUEST_TEMPLATE/02_enhance.md
vendored
@@ -1,23 +0,0 @@
|
||||
<!-- ℹ お読みください / README
|
||||
PRありがとうございます! PRを作成する前に、コントリビューションガイドをご確認ください:
|
||||
Thank you for your PR! Before creating a PR, please check the contribution guide:
|
||||
https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md
|
||||
-->
|
||||
|
||||
## What
|
||||
<!-- このPRで何をしたのか? どう変わるのか? -->
|
||||
<!-- What did you do with this PR? How will it change things? -->
|
||||
|
||||
## Why
|
||||
<!-- なぜそうするのか? どういう意図なのか? 何が困っているのか? -->
|
||||
<!-- Why do you do it? What are your intentions? What is the problem? -->
|
||||
|
||||
## Additional info (optional)
|
||||
<!-- テスト観点など -->
|
||||
<!-- Test perspective, etc -->
|
||||
|
||||
## Checklist
|
||||
- [ ] Read the [contribution guide](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md)
|
||||
- [ ] Test working in a local environment
|
||||
- [ ] (If needed) Update CHANGELOG.md
|
||||
- [ ] (If possible) Add tests
|
||||
20
.github/PULL_REQUEST_TEMPLATE/03_release.md
vendored
20
.github/PULL_REQUEST_TEMPLATE/03_release.md
vendored
@@ -1,20 +0,0 @@
|
||||
## Summary
|
||||
This is a release PR.
|
||||
|
||||
For more information on the release instructions, please see:
|
||||
https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md#release
|
||||
|
||||
## For reviewers
|
||||
- CHANGELOGに抜け漏れは無いか
|
||||
- バージョンの上げ方は適切か
|
||||
- 他にこのリリースに含めなければならない変更は無いか
|
||||
- 全体的な変更内容を俯瞰し問題は無いか
|
||||
- レビューされていないコミットがある場合は、それが問題ないか
|
||||
- 最終的な動作確認を行い問題は無いか
|
||||
|
||||
などを確認し、リリースする準備が整っていると思われる場合は approve してください。
|
||||
|
||||
## Checklist
|
||||
- [ ] package.jsonのバージョンが正しく更新されている
|
||||
- [ ] CHANGELOGが過不足無く更新されている
|
||||
- [ ] CIが全て通っている
|
||||
54
.github/copilot-instructions.md
vendored
54
.github/copilot-instructions.md
vendored
@@ -1,54 +0,0 @@
|
||||
# Copilot Instructions for Misskey
|
||||
|
||||
このファイルは GitHub Copilot の repository-wide instructions として使われる。Copilot code review では `AGENTS.md` が読まれない環境があるため、レビューや軽微な実装判断に必要な規約はこのファイル単体で満たすこと。
|
||||
|
||||
このリポジトリは Misskey の pnpm workspace モノレポ。主要な実装は `packages/backend` (NestJS / TypeORM) と `packages/frontend` (Vue 3) にある。より詳しいガイドはリポジトリルートの `AGENTS.md` を参照してよいが、このファイルの要件を省略してそちらへの参照だけで済ませないこと。
|
||||
|
||||
## Always follow
|
||||
|
||||
- AGPL-3.0-only 管轄かつ SPDX CI 対象ディレクトリに新規 `.ts` / `.js` / `.cjs` / `.mjs` / `.scss` ファイルを追加する場合は、必ず次の SPDX ヘッダーを付ける。詳細な対象判定は `AGENTS.md` と `.github/workflows/check-spdx-license-id.yml` を参照すること。
|
||||
|
||||
```text
|
||||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
```
|
||||
|
||||
- AGPL-3.0-only 管轄かつ SPDX CI 対象ディレクトリに新規 `.vue` / `.html` ファイルを追加する場合は、必ず次の SPDX ヘッダーを付ける。
|
||||
|
||||
```text
|
||||
<!--
|
||||
SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
```
|
||||
|
||||
`packages/misskey-js` は MIT ライセンスのサブパッケージなので、この AGPL ヘッダーを一律に付けない。サブパッケージ固有の `package.json` / `LICENSE` / 既存ファイルのヘッダーに従う。
|
||||
|
||||
- `locales/` 配下の YAML は `ja-JP.yml` のみ手動編集してよい。他言語は Crowdin の自動配信先なので手動編集しないこと。
|
||||
- `packages/backend/migration/{timestamp}-*.js` のうち、既にマージ済みの migration は絶対に編集しない。スキーマ変更が必要な場合は新しい timestamp で migration を追加し、`up()` と `down()` の両方を実装すること。
|
||||
- ユーザー影響のある変更は `CHANGELOG.md` の `## Unreleased` 配下の `### General` / `### Client` / `### Server` のいずれかに 1 行追加する。内部リファクタのみなら不要。
|
||||
- API 変更時は `pnpm build-misskey-js-with-types` の実行が必要になる。
|
||||
|
||||
## Validation
|
||||
|
||||
- 全体ビルド: `pnpm build`
|
||||
- 全体 lint / typecheck: `pnpm lint`
|
||||
- Backend unit test: `pnpm --filter backend test`
|
||||
- Backend e2e test: `pnpm --filter backend test:e2e`
|
||||
- Backend federation test: `pnpm --filter backend test:fed`
|
||||
- Frontend test: `pnpm --filter frontend test`
|
||||
- Migration 差分検査: `pnpm --filter backend check-migrations`
|
||||
|
||||
> **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 は不要。
|
||||
|
||||
変更範囲に応じて最も近いコマンドから優先して検証し、必要なら全体コマンドに広げること。
|
||||
|
||||
## Editing hints
|
||||
|
||||
- Backend の API / migration / TypeORM 変更は `packages/backend` を見る。
|
||||
- Frontend の Vue コンポーネントやページ変更は `packages/frontend` を見る。
|
||||
- `AGENTS.md` 内の相対リンクはリポジトリルート起点で解決する想定。
|
||||
|
||||
> `AGENTS.md` はより詳細な正典だが、Copilot code review ではこのファイルが主な入口になる。両方が読まれる環境では `AGENTS.md` を補助情報として使ってよい。
|
||||
40
.github/dependabot.yml
vendored
40
.github/dependabot.yml
vendored
@@ -5,38 +5,18 @@
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: github-actions
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: daily
|
||||
open-pull-requests-limit: 0
|
||||
|
||||
# Add only the root, not each workspace item
|
||||
# https://github.com/dependabot/dependabot-core/issues/4993#issuecomment-1289133027
|
||||
- package-ecosystem: npm
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: daily
|
||||
open-pull-requests-limit: 0
|
||||
# List dependencies required to be updated together, sharing the same version numbers.
|
||||
# Those who simply have the common owner (e.g. @fastify) don't need to be listed.
|
||||
groups:
|
||||
aws-sdk:
|
||||
patterns:
|
||||
- "@aws-sdk/*"
|
||||
nestjs:
|
||||
patterns:
|
||||
- "@nestjs/*"
|
||||
slacc:
|
||||
patterns:
|
||||
- "slacc-*"
|
||||
storybook:
|
||||
patterns:
|
||||
- "storybook*"
|
||||
- "@storybook/*"
|
||||
typescript-eslint:
|
||||
patterns:
|
||||
- "@typescript-eslint/*"
|
||||
tensorflow:
|
||||
patterns:
|
||||
- "@tensorflow/*"
|
||||
- package-ecosystem: npm
|
||||
directory: "/packages/backend"
|
||||
schedule:
|
||||
interval: daily
|
||||
open-pull-requests-limit: 0
|
||||
- package-ecosystem: npm
|
||||
directory: "/packages/client"
|
||||
schedule:
|
||||
interval: daily
|
||||
open-pull-requests-limit: 0
|
||||
|
||||
40
.github/labeler.yml
vendored
40
.github/labeler.yml
vendored
@@ -1,34 +1,12 @@
|
||||
'packages/backend':
|
||||
- any:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: ['packages/backend/**/*']
|
||||
'⚙️Server':
|
||||
- packages/backend/**/*
|
||||
|
||||
'packages/backend:test':
|
||||
- any:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: ['packages/backend/test/**/*', 'packages/backend/test-federation/**/*']
|
||||
'🖥️Client':
|
||||
- packages/client/**/*
|
||||
|
||||
'packages/frontend':
|
||||
- any:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: ['packages/frontend/**/*']
|
||||
'🧪Test':
|
||||
- cypress/**/*
|
||||
- packages/backend/test/**/*
|
||||
|
||||
'packages/frontend:test':
|
||||
- any:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: ['cypress/**/*']
|
||||
|
||||
'packages/sw':
|
||||
- any:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: ['packages/sw/**/*']
|
||||
|
||||
'packages/misskey-js':
|
||||
- any:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: ['packages/misskey-js/**/*']
|
||||
|
||||
'packages/misskey-js:test':
|
||||
- any:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: ['packages/misskey-js/test/**/*', 'packages/misskey-js/test-d/**/*']
|
||||
'‼️ wrong locales':
|
||||
- any: ['locales/*.yml', '!locales/ja-JP.yml']
|
||||
|
||||
1
.github/min.node-version
vendored
1
.github/min.node-version
vendored
@@ -1 +0,0 @@
|
||||
22.15.0
|
||||
10
.github/misskey/test.yml
vendored
10
.github/misskey/test.yml
vendored
@@ -1,19 +1,15 @@
|
||||
url: 'http://misskey.local'
|
||||
|
||||
setupPassword: example_password_please_change_this_or_you_will_get_hacked
|
||||
|
||||
# ローカルでテストするときにポートを被らないようにするためデフォルトのものとは変える(以下同じ)
|
||||
port: 61812
|
||||
|
||||
db:
|
||||
host: 127.0.0.1
|
||||
host: localhost
|
||||
port: 54312
|
||||
db: test-misskey
|
||||
user: postgres
|
||||
pass: ''
|
||||
redis:
|
||||
host: 127.0.0.1
|
||||
host: localhost
|
||||
port: 56312
|
||||
id: aidx
|
||||
|
||||
proxyRemoteFiles: true
|
||||
id: aid
|
||||
|
||||
24
.github/pull_request_template.md
vendored
24
.github/pull_request_template.md
vendored
@@ -1,24 +0,0 @@
|
||||
<!-- ℹ お読みください / README
|
||||
PRありがとうございます! PRを作成する前に、コントリビューションガイドをご確認ください:
|
||||
Thank you for your PR! Before creating a PR, please check the contribution guide:
|
||||
https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md
|
||||
-->
|
||||
|
||||
## What
|
||||
<!-- このPRで何をしたのか? どう変わるのか? -->
|
||||
<!-- What did you do with this PR? How will it change things? -->
|
||||
|
||||
## Why
|
||||
<!-- なぜそうするのか? どういう意図なのか? 何が困っているのか? -->
|
||||
<!-- Why do you do it? What are your intentions? What is the problem? -->
|
||||
|
||||
## Additional info (optional)
|
||||
<!-- テスト観点など -->
|
||||
<!-- Test perspective, etc -->
|
||||
|
||||
## Checklist
|
||||
- [ ] Read the [contribution guide](https://github.com/misskey-dev/misskey/blob/develop/CONTRIBUTING.md)
|
||||
- [ ] Test working in a local environment
|
||||
- [ ] (If needed) Add story of storybook
|
||||
- [ ] (If needed) Update CHANGELOG.md
|
||||
- [ ] (If possible) Add tests
|
||||
44
.github/workflows/api-misskey-js.yml
vendored
44
.github/workflows/api-misskey-js.yml
vendored
@@ -1,44 +0,0 @@
|
||||
name: API report (misskey.js)
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- packages/misskey-js/**
|
||||
- .github/workflows/api-misskey-js.yml
|
||||
pull_request:
|
||||
paths:
|
||||
- packages/misskey-js/**
|
||||
- .github/workflows/api-misskey-js.yml
|
||||
jobs:
|
||||
report:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6.0.2
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v6.0.3
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6.4.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm i --frozen-lockfile
|
||||
|
||||
- name: Build
|
||||
run: pnpm --filter misskey-js build
|
||||
|
||||
- name: Check files
|
||||
run: ls packages/misskey-js/built
|
||||
|
||||
- name: API report
|
||||
run: pnpm --filter misskey-js api-prod
|
||||
|
||||
- name: Show report
|
||||
if: always()
|
||||
run: cat packages/misskey-js/temp/misskey-js.api.md
|
||||
43
.github/workflows/changelog-check.yml
vendored
43
.github/workflows/changelog-check.yml
vendored
@@ -1,43 +0,0 @@
|
||||
name: Check the description in CHANGELOG.md
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
|
||||
jobs:
|
||||
check-changelog:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout head
|
||||
uses: actions/checkout@v6.0.2
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6.4.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
|
||||
- name: Checkout base
|
||||
run: |
|
||||
mkdir _base
|
||||
cp -r .git _base/.git
|
||||
cd _base
|
||||
git fetch --depth 1 origin ${{ github.base_ref }}
|
||||
git checkout origin/${{ github.base_ref }} CHANGELOG.md
|
||||
|
||||
- name: Copy to Checker directory for CHANGELOG-base.md
|
||||
run: cp _base/CHANGELOG.md scripts/changelog-checker/CHANGELOG-base.md
|
||||
- name: Copy to Checker directory for CHANGELOG-head.md
|
||||
run: cp CHANGELOG.md scripts/changelog-checker/CHANGELOG-head.md
|
||||
- name: diff
|
||||
continue-on-error: true
|
||||
run: diff -u CHANGELOG-base.md CHANGELOG-head.md
|
||||
working-directory: scripts/changelog-checker
|
||||
|
||||
- name: Setup Checker
|
||||
run: npm install
|
||||
working-directory: scripts/changelog-checker
|
||||
- name: Run Checker
|
||||
run: npm run run
|
||||
working-directory: scripts/changelog-checker
|
||||
139
.github/workflows/check-misskey-js-autogen.yml
vendored
139
.github/workflows/check-misskey-js-autogen.yml
vendored
@@ -1,139 +0,0 @@
|
||||
name: Check Misskey JS autogen
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
- improve-misskey-js-autogen-check
|
||||
paths:
|
||||
- packages/backend/**
|
||||
|
||||
jobs:
|
||||
# pull_request_target safety: permissions: read-all, and there are no secrets used in this job
|
||||
generate-misskey-js:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
if: ${{ github.event.pull_request.mergeable == null || github.event.pull_request.mergeable == true }}
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v6.0.2
|
||||
with:
|
||||
submodules: true
|
||||
persist-credentials: false
|
||||
ref: refs/pull/${{ github.event.pull_request.number }}/merge
|
||||
|
||||
- name: setup pnpm
|
||||
uses: pnpm/action-setup@v6
|
||||
|
||||
- name: setup node
|
||||
id: setup-node
|
||||
uses: actions/setup-node@v6.4.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: pnpm
|
||||
|
||||
- name: install dependencies
|
||||
run: pnpm i --frozen-lockfile
|
||||
|
||||
# generate api.json
|
||||
- name: Copy Config
|
||||
run: cp .config/example.yml .config/default.yml
|
||||
- name: Build
|
||||
run: pnpm build
|
||||
- name: Generate API JSON
|
||||
run: pnpm --filter backend generate-api-json
|
||||
|
||||
# build misskey js
|
||||
- name: Build misskey-js
|
||||
run: |-
|
||||
cp packages/backend/built/api.json packages/misskey-js/generator/api.json
|
||||
pnpm run --filter misskey-js-type-generator generate
|
||||
|
||||
# packages/misskey-js/generator/built/autogen
|
||||
- name: Upload Generated
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: generated-misskey-js
|
||||
path: packages/misskey-js/generator/built/autogen
|
||||
|
||||
# pull_request_target safety: permissions: read-all, and no user codes are executed
|
||||
get-actual-misskey-js:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
if: ${{ github.event.pull_request.mergeable == null || github.event.pull_request.mergeable == true }}
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v6.0.2
|
||||
with:
|
||||
submodules: true
|
||||
persist-credentials: false
|
||||
ref: refs/pull/${{ github.event.pull_request.number }}/merge
|
||||
|
||||
- name: Upload From Merged
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: actual-misskey-js
|
||||
path: packages/misskey-js/src/autogen
|
||||
|
||||
# pull_request_target safety: nothing is cloned from repository
|
||||
comment-misskey-js-autogen:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [generate-misskey-js, get-actual-misskey-js]
|
||||
permissions:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: download generated-misskey-js
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: generated-misskey-js
|
||||
path: misskey-js-generated
|
||||
|
||||
- name: download actual-misskey-js
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: actual-misskey-js
|
||||
path: misskey-js-actual
|
||||
|
||||
- name: check misskey-js changes
|
||||
id: check-changes
|
||||
run: |
|
||||
diff -r -u --label=generated --label=on-tree ./misskey-js-generated ./misskey-js-actual > misskey-js.diff || true
|
||||
|
||||
if [ -s misskey-js.diff ]; then
|
||||
echo "changes=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "changes=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Print full diff
|
||||
run: cat ./misskey-js.diff
|
||||
|
||||
- name: send message
|
||||
if: steps.check-changes.outputs.changes == 'true'
|
||||
uses: thollander/actions-comment-pull-request@v3
|
||||
with:
|
||||
comment-tag: check-misskey-js-autogen
|
||||
message: |-
|
||||
Thank you for sending us a great Pull Request! 👍
|
||||
Please regenerate misskey-js type definitions! 🙏
|
||||
|
||||
example:
|
||||
```sh
|
||||
pnpm run build-misskey-js-with-types
|
||||
```
|
||||
|
||||
- name: send message
|
||||
if: steps.check-changes.outputs.changes == 'false'
|
||||
uses: thollander/actions-comment-pull-request@v3
|
||||
with:
|
||||
comment-tag: check-misskey-js-autogen
|
||||
mode: delete
|
||||
message: "Thank you!"
|
||||
create_if_not_exists: false
|
||||
|
||||
- name: Make failure if changes are detected
|
||||
if: steps.check-changes.outputs.changes == 'true'
|
||||
run: exit 1
|
||||
29
.github/workflows/check-misskey-js-version.yml
vendored
29
.github/workflows/check-misskey-js-version.yml
vendored
@@ -1,29 +0,0 @@
|
||||
name: Check Misskey JS version
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ develop ]
|
||||
paths:
|
||||
- packages/misskey-js/package.json
|
||||
- package.json
|
||||
- .github/workflows/check-misskey-js-version.yml
|
||||
pull_request:
|
||||
branches: [ develop ]
|
||||
paths:
|
||||
- packages/misskey-js/package.json
|
||||
- package.json
|
||||
- .github/workflows/check-misskey-js-version.yml
|
||||
jobs:
|
||||
check-version:
|
||||
# ルートの package.json と packages/misskey-js/package.json のバージョンが一致しているかを確認する
|
||||
name: Check version
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6.0.2
|
||||
- name: Check version
|
||||
run: |
|
||||
if [ "$(jq -r '.version' package.json)" != "$(jq -r '.version' packages/misskey-js/package.json)" ]; then
|
||||
echo "Version mismatch!"
|
||||
exit 1
|
||||
fi
|
||||
81
.github/workflows/check-spdx-license-id.yml
vendored
81
.github/workflows/check-spdx-license-id.yml
vendored
@@ -1,81 +0,0 @@
|
||||
name: Check SPDX-License-Identifier
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
check-spdx-license-id:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6.0.2
|
||||
- name: Check
|
||||
run: |
|
||||
counter=0
|
||||
|
||||
search() {
|
||||
local directory="$1"
|
||||
find "$directory" -type f \
|
||||
'(' \
|
||||
-name "*.cjs" -and -not -name '*.config.cjs' -o \
|
||||
-name "*.html" -o \
|
||||
-name "*.js" -and -not -name '*.config.js' -o \
|
||||
-name "*.mjs" -and -not -name '*.config.mjs' -o \
|
||||
-name "*.scss" -o \
|
||||
-name "*.ts" -and -not -name '*.config.ts' -o \
|
||||
-name "*.vue" \
|
||||
')' -and \
|
||||
-not -name '*eslint*'
|
||||
}
|
||||
|
||||
check() {
|
||||
local file="$1"
|
||||
if ! (
|
||||
grep -q "SPDX-FileCopyrightText: syuilo and misskey-project" "$file" ||
|
||||
grep -q "SPDX-License-Identifier: AGPL-3.0-only" "$file"
|
||||
); then
|
||||
echo "Missing: $file"
|
||||
((counter++))
|
||||
fi
|
||||
}
|
||||
|
||||
directories=(
|
||||
"cypress/e2e"
|
||||
"packages/backend/migration"
|
||||
"packages/backend/src"
|
||||
"packages/backend/test"
|
||||
"packages/frontend-shared/@types"
|
||||
"packages/frontend-shared/js"
|
||||
"packages/frontend-builder"
|
||||
"packages/frontend/.storybook"
|
||||
"packages/frontend/@types"
|
||||
"packages/frontend/lib"
|
||||
"packages/frontend/public"
|
||||
"packages/frontend/src"
|
||||
"packages/frontend/test"
|
||||
"packages/frontend-embed/@types"
|
||||
"packages/frontend-embed/src"
|
||||
"packages/icons-subsetter/src"
|
||||
"packages/misskey-bubble-game/src"
|
||||
"packages/misskey-reversi/src"
|
||||
"packages/sw/src"
|
||||
"scripts"
|
||||
)
|
||||
|
||||
for directory in "${directories[@]}"; do
|
||||
for file in $(search $directory); do
|
||||
check "$file"
|
||||
done
|
||||
done
|
||||
|
||||
if [ $counter -gt 0 ]; then
|
||||
echo "SPDX-License-Identifier is missing in $counter files."
|
||||
exit 1
|
||||
else
|
||||
echo "SPDX-License-Identifier is certainly described in all target files!"
|
||||
exit 0
|
||||
fi
|
||||
18
.github/workflows/check_copyright_year.yml
vendored
18
.github/workflows/check_copyright_year.yml
vendored
@@ -1,18 +0,0 @@
|
||||
name: Check copyright year
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
|
||||
jobs:
|
||||
check_copyright_year:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6.0.2
|
||||
- run: |
|
||||
if [ "$(grep Copyright COPYING | sed -e 's/.*2014-\([0-9]*\) .*/\1/g')" -ne "$(date +%Y)" ]; then
|
||||
echo "Please change copyright year!"
|
||||
exit 1
|
||||
fi
|
||||
84
.github/workflows/deploy-test-environment.yml
vendored
84
.github/workflows/deploy-test-environment.yml
vendored
@@ -1,84 +0,0 @@
|
||||
name: deploy-test-environment
|
||||
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
repository:
|
||||
description: 'Repository to deploy (optional, use the repository where this workflow is stored by default)'
|
||||
required: false
|
||||
default: ''
|
||||
branch_or_hash:
|
||||
description: 'Branch or Commit hash to deploy (optional, use the branch where this workflow is stored by default)'
|
||||
required: false
|
||||
default: ''
|
||||
wait_time:
|
||||
description: 'Time to wait in seconds (optional, 1800 seconds by default)'
|
||||
required: false
|
||||
default: ''
|
||||
|
||||
jobs:
|
||||
get-pr-ref:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'issue_comment' && github.event.issue.pull_request && startsWith(github.event.comment.body, '/preview')
|
||||
outputs:
|
||||
is-allowed-user: ${{ steps.check-allowed-users.outputs.is-allowed-user }}
|
||||
pr-ref: ${{ steps.get-ref.outputs.pr-ref }}
|
||||
wait_time: ${{ steps.get-wait-time.outputs.wait_time }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6.0.2
|
||||
|
||||
- name: Check allowed users
|
||||
id: check-allowed-users
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
ORG_ID: ${{ github.repository_owner_id }}
|
||||
COMMENT_AUTHOR: ${{ github.event.comment.user.login }}
|
||||
run: |
|
||||
MEMBERSHIP_STATUS=$(curl -s -H "Authorization: Bearer $GITHUB_TOKEN" \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
-H "X-GitHub-Api-Version: 2022-11-28" \
|
||||
"https://api.github.com/organizations/$ORG_ID/public_members/$COMMENT_AUTHOR" \
|
||||
-o /dev/null -w '%{http_code}\n' -s)
|
||||
if [ "$MEMBERSHIP_STATUS" -eq 204 ]; then
|
||||
echo "is-allowed-user=true" > $GITHUB_OUTPUT
|
||||
else
|
||||
echo "is-allowed-user=false" > $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Get PR ref
|
||||
id: get-ref
|
||||
run: |
|
||||
PR_REF="refs/pull/${{ github.event.issue.number }}/head"
|
||||
echo "pr-ref=$PR_REF" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Extract wait time
|
||||
id: get-wait-time
|
||||
env:
|
||||
COMMENT_BODY: ${{ github.event.comment.body }}
|
||||
run: |
|
||||
WAIT_TIME=$(echo "$COMMENT_BODY" | grep -oP '(?<=/preview\s)\d+' || echo "1800")
|
||||
echo "wait_time=$WAIT_TIME" > $GITHUB_OUTPUT
|
||||
|
||||
deploy-test-environment-pr-comment:
|
||||
needs: get-pr-ref
|
||||
if: needs.get-pr-ref.outputs.is-allowed-user == 'true'
|
||||
uses: joinmisskey/misskey-tga/.github/workflows/deploy-test-environment.yml@main
|
||||
with:
|
||||
repository: ${{ github.repository }}
|
||||
branch_or_hash: ${{ needs.get-pr-ref.outputs.pr-ref }}
|
||||
wait_time: ${{ needs.get-pr-ref.outputs.wait_time }}
|
||||
secrets:
|
||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||
|
||||
deploy-test-environment-wd:
|
||||
if: github.event_name == 'workflow_dispatch'
|
||||
uses: joinmisskey/misskey-tga/.github/workflows/deploy-test-environment.yml@main
|
||||
with:
|
||||
repository: ${{ inputs.repository || github.repository }}
|
||||
branch_or_hash: ${{ inputs.branch_or_hash || github.ref_name }}
|
||||
wait_time: ${{ inputs.wait_time || '1800' }}
|
||||
secrets:
|
||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||
81
.github/workflows/docker-develop.yml
vendored
81
.github/workflows/docker-develop.yml
vendored
@@ -6,83 +6,28 @@ on:
|
||||
- develop
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
REGISTRY_IMAGE: misskey/misskey
|
||||
|
||||
jobs:
|
||||
# see https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-build-across-multiple-runners
|
||||
build:
|
||||
name: Build
|
||||
push_to_registry:
|
||||
name: Push Docker image to Docker Hub
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform:
|
||||
- linux/amd64
|
||||
- linux/arm64
|
||||
if: github.repository == 'misskey-dev/misskey'
|
||||
|
||||
steps:
|
||||
- name: Prepare
|
||||
run: |
|
||||
platform=${{ matrix.platform }}
|
||||
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
|
||||
- name: Check out the repo
|
||||
uses: actions/checkout@v6.0.2
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v4
|
||||
uses: actions/checkout@v2
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v3
|
||||
with:
|
||||
images: misskey/misskey
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@v4
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
- name: Build and push by digest
|
||||
id: build
|
||||
uses: docker/build-push-action@v7
|
||||
- name: Build and Push to Docker Hub
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
platforms: ${{ matrix.platform }}
|
||||
provenance: false
|
||||
tags: misskey/misskey:develop
|
||||
labels: develop
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true
|
||||
- name: Export digest
|
||||
run: |
|
||||
mkdir -p /tmp/digests
|
||||
digest="${{ steps.build.outputs.digest }}"
|
||||
touch "/tmp/digests/${digest#sha256:}"
|
||||
- name: Upload digest
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: digests-${{ env.PLATFORM_PAIR }}
|
||||
path: /tmp/digests/*
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
|
||||
merge:
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- build
|
||||
steps:
|
||||
- name: Download digests
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
path: /tmp/digests
|
||||
pattern: digests-*
|
||||
merge-multiple: true
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v4
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
- name: Create manifest list and push
|
||||
working-directory: /tmp/digests
|
||||
run: |
|
||||
docker buildx imagetools create --tag ${{ env.REGISTRY_IMAGE }}:develop \
|
||||
$(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *)
|
||||
- name: Inspect image
|
||||
run: |
|
||||
docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:develop
|
||||
|
||||
91
.github/workflows/docker.yml
vendored
91
.github/workflows/docker.yml
vendored
@@ -5,101 +5,28 @@ on:
|
||||
types: [published]
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
REGISTRY_IMAGE: misskey/misskey
|
||||
TAGS: |
|
||||
type=edge
|
||||
type=ref,event=pr
|
||||
type=ref,event=branch
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=semver,pattern={{major}}
|
||||
|
||||
jobs:
|
||||
# see https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-build-across-multiple-runners
|
||||
build:
|
||||
name: Build
|
||||
push_to_registry:
|
||||
name: Push Docker image to Docker Hub
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform:
|
||||
- linux/amd64
|
||||
- linux/arm64
|
||||
|
||||
steps:
|
||||
- name: Prepare
|
||||
run: |
|
||||
platform=${{ matrix.platform }}
|
||||
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
|
||||
- name: Check out the repo
|
||||
uses: actions/checkout@v6.0.2
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v4
|
||||
uses: actions/checkout@v2
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v6
|
||||
uses: docker/metadata-action@v3
|
||||
with:
|
||||
images: ${{ env.REGISTRY_IMAGE }}
|
||||
tags: ${{ env.TAGS }}
|
||||
images: misskey/misskey
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@v4
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
- name: Build and Push to Docker Hub
|
||||
id: build
|
||||
uses: docker/build-push-action@v7
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
platforms: ${{ matrix.platform }}
|
||||
provenance: false
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true
|
||||
- name: Export digest
|
||||
run: |
|
||||
mkdir -p /tmp/digests
|
||||
digest="${{ steps.build.outputs.digest }}"
|
||||
touch "/tmp/digests/${digest#sha256:}"
|
||||
- name: Upload digest
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: digests-${{ env.PLATFORM_PAIR }}
|
||||
path: /tmp/digests/*
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
|
||||
merge:
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- build
|
||||
steps:
|
||||
- name: Download digests
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
path: /tmp/digests
|
||||
pattern: digests-*
|
||||
merge-multiple: true
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v4
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v6
|
||||
with:
|
||||
images: ${{ env.REGISTRY_IMAGE }}
|
||||
tags: ${{ env.TAGS }}
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
- name: Create manifest list and push
|
||||
working-directory: /tmp/digests
|
||||
run: |
|
||||
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
|
||||
$(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *)
|
||||
- name: Inspect image
|
||||
run: |
|
||||
docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.meta.outputs.version }}
|
||||
|
||||
53
.github/workflows/dockle.yml
vendored
53
.github/workflows/dockle.yml
vendored
@@ -1,53 +0,0 @@
|
||||
---
|
||||
name: Dockle
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
dockle:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
env:
|
||||
DOCKER_CONTENT_TRUST: 1
|
||||
DOCKLE_VERSION: 0.4.15
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6.0.2
|
||||
|
||||
- name: Download and install dockle v${{ env.DOCKLE_VERSION }}
|
||||
run: |
|
||||
set -eux
|
||||
curl -L -o dockle.deb "https://github.com/goodwithtech/dockle/releases/download/v${DOCKLE_VERSION}/dockle_${DOCKLE_VERSION}_Linux-64bit.deb"
|
||||
sudo dpkg -i dockle.deb
|
||||
|
||||
- name: Build web image (docker build)
|
||||
run: |
|
||||
set -eux
|
||||
docker build -t "misskey-web:ci" .
|
||||
docker image ls
|
||||
|
||||
- name: Mount tmpfs for Dockle tar
|
||||
env:
|
||||
TMPFS_SIZE: 8G
|
||||
run: |
|
||||
set -eux
|
||||
sudo mkdir -p /mnt/dockle-tmp
|
||||
sudo mount -t tmpfs -o size=${{ env.TMPFS_SIZE }} tmpfs /mnt/dockle-tmp
|
||||
free -h
|
||||
df -h
|
||||
|
||||
- name: Save image tar into tmpfs
|
||||
run: |
|
||||
set -eux
|
||||
docker save misskey-web:ci -o /mnt/dockle-tmp/misskey-web.tar
|
||||
ls -lh /mnt/dockle-tmp/misskey-web.tar
|
||||
|
||||
- name: Run Dockle Scan (tar input)
|
||||
run: |
|
||||
set -eux
|
||||
dockle --exit-code 1 --input /mnt/dockle-tmp/misskey-web.tar
|
||||
67
.github/workflows/get-api-diff.yml
vendored
67
.github/workflows/get-api-diff.yml
vendored
@@ -1,67 +0,0 @@
|
||||
# this name is used in report-api-diff.yml so be careful when change name
|
||||
name: Get api.json from Misskey
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
paths:
|
||||
- packages/backend/**
|
||||
- .github/workflows/get-api-diff.yml
|
||||
jobs:
|
||||
get-from-misskey:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
api-json-name: [api-base.json, api-head.json]
|
||||
include:
|
||||
- api-json-name: api-base.json
|
||||
ref: ${{ github.base_ref }}
|
||||
- api-json-name: api-head.json
|
||||
ref: refs/pull/${{ github.event.number }}/merge
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6.0.2
|
||||
with:
|
||||
ref: ${{ matrix.ref }}
|
||||
submodules: true
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v6.0.3
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v6.4.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
- run: pnpm i --frozen-lockfile
|
||||
- name: Check pnpm-lock.yaml
|
||||
run: git diff --exit-code pnpm-lock.yaml
|
||||
- name: Copy Configure
|
||||
run: cp .config/example.yml .config/default.yml
|
||||
- name: Build
|
||||
run: pnpm build
|
||||
- name: Generate API JSON
|
||||
run: pnpm --filter backend generate-api-json
|
||||
- name: Copy API.json
|
||||
run: cp packages/backend/built/api.json ${{ matrix.api-json-name }}
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: api-artifact-${{ matrix.api-json-name }}
|
||||
path: ${{ matrix.api-json-name }}
|
||||
|
||||
save-pr-number:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Save PR number
|
||||
env:
|
||||
PR_NUMBER: ${{ github.event.number }}
|
||||
run: |
|
||||
echo "$PR_NUMBER" > ./pr_number
|
||||
- uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: api-artifact-pr-number
|
||||
path: pr_number
|
||||
87
.github/workflows/get-backend-memory.yml
vendored
87
.github/workflows/get-backend-memory.yml
vendored
@@ -1,87 +0,0 @@
|
||||
# this name is used in report-backend-memory.yml so be careful when change name
|
||||
name: Get backend memory usage
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
paths:
|
||||
- packages/backend/**
|
||||
- packages/misskey-js/**
|
||||
- .github/workflows/get-backend-memory.yml
|
||||
|
||||
jobs:
|
||||
get-memory-usage:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
memory-json-name: [memory-base.json, memory-head.json]
|
||||
include:
|
||||
- memory-json-name: memory-base.json
|
||||
ref: ${{ github.base_ref }}
|
||||
- memory-json-name: memory-head.json
|
||||
ref: refs/pull/${{ github.event.number }}/merge
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:18
|
||||
ports:
|
||||
- 54312:5432
|
||||
env:
|
||||
POSTGRES_DB: test-misskey
|
||||
POSTGRES_HOST_AUTH_METHOD: trust
|
||||
redis:
|
||||
image: redis:8
|
||||
ports:
|
||||
- 56312:6379
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6.0.2
|
||||
with:
|
||||
ref: ${{ matrix.ref }}
|
||||
submodules: true
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v6.0.3
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v6.4.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
- run: pnpm i --frozen-lockfile
|
||||
- name: Check pnpm-lock.yaml
|
||||
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
|
||||
run: pnpm --filter backend migrate
|
||||
- name: Measure memory usage
|
||||
run: |
|
||||
# Start the server and measure memory usage
|
||||
node packages/backend/scripts/measure-memory.mjs > ${{ matrix.memory-json-name }}
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: memory-artifact-${{ matrix.memory-json-name }}
|
||||
path: ${{ matrix.memory-json-name }}
|
||||
|
||||
save-pr-number:
|
||||
runs-on: ubuntu-latest
|
||||
permissions: {}
|
||||
steps:
|
||||
- name: Save PR number
|
||||
env:
|
||||
PR_NUMBER: ${{ github.event.number }}
|
||||
run: |
|
||||
echo "$PR_NUMBER" > ./pr_number
|
||||
- uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: memory-artifact-pr-number
|
||||
path: pr_number
|
||||
2
.github/workflows/labeler.yml
vendored
2
.github/workflows/labeler.yml
vendored
@@ -11,6 +11,6 @@ jobs:
|
||||
pull-requests: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/labeler@v6
|
||||
- uses: actions/labeler@v4
|
||||
with:
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
|
||||
154
.github/workflows/lint.yml
vendored
154
.github/workflows/lint.yml
vendored
@@ -1,115 +1,39 @@
|
||||
name: Lint
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
paths:
|
||||
- packages/backend/**
|
||||
- packages/frontend/**
|
||||
- packages/frontend-shared/**
|
||||
- packages/frontend-builder/**
|
||||
- packages/frontend-embed/**
|
||||
- packages/icons-subsetter/**
|
||||
- packages/sw/**
|
||||
- packages/misskey-js/**
|
||||
- packages/misskey-bubble-game/**
|
||||
- packages/misskey-reversi/**
|
||||
- packages/shared/eslint.config.js
|
||||
- .github/workflows/lint.yml
|
||||
pull_request:
|
||||
paths:
|
||||
- packages/backend/**
|
||||
- packages/frontend/**
|
||||
- packages/frontend-shared/**
|
||||
- packages/frontend-builder/**
|
||||
- packages/frontend-embed/**
|
||||
- packages/icons-subsetter/**
|
||||
- packages/sw/**
|
||||
- packages/misskey-js/**
|
||||
- packages/misskey-bubble-game/**
|
||||
- packages/misskey-reversi/**
|
||||
- packages/shared/eslint.config.js
|
||||
- .github/workflows/lint.yml
|
||||
jobs:
|
||||
pnpm_install:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6.0.2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v6.0.3
|
||||
- uses: actions/setup-node@v6.4.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
- run: pnpm i --frozen-lockfile
|
||||
|
||||
lint:
|
||||
needs: [pnpm_install]
|
||||
runs-on: ubuntu-latest
|
||||
continue-on-error: true
|
||||
strategy:
|
||||
matrix:
|
||||
workspace:
|
||||
- backend
|
||||
- frontend
|
||||
- frontend-shared
|
||||
- frontend-builder
|
||||
- frontend-embed
|
||||
- icons-subsetter
|
||||
- sw
|
||||
- misskey-js
|
||||
- misskey-bubble-game
|
||||
- misskey-reversi
|
||||
env:
|
||||
eslint-cache-version: v1
|
||||
eslint-cache-path: ${{ github.workspace }}/node_modules/.cache/eslint-${{ matrix.workspace }}
|
||||
steps:
|
||||
- uses: actions/checkout@v6.0.2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v6.0.3
|
||||
- uses: actions/setup-node@v6.4.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
- run: pnpm i --frozen-lockfile
|
||||
- name: Restore eslint cache
|
||||
uses: actions/cache@v5.0.5
|
||||
with:
|
||||
path: ${{ env.eslint-cache-path }}
|
||||
key: eslint-${{ env.eslint-cache-version }}-${{ matrix.workspace }}-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ github.ref_name }}-${{ github.sha }}
|
||||
restore-keys: eslint-${{ env.eslint-cache-version }}-${{ matrix.workspace }}-${{ hashFiles('**/pnpm-lock.yaml') }}-
|
||||
- run: pnpm --filter ${{ matrix.workspace }} run eslint --cache --cache-location ${{ env.eslint-cache-path }} --cache-strategy content
|
||||
|
||||
typecheck:
|
||||
needs: [pnpm_install]
|
||||
runs-on: ubuntu-latest
|
||||
continue-on-error: true
|
||||
strategy:
|
||||
matrix:
|
||||
workspace:
|
||||
- backend
|
||||
- frontend
|
||||
- sw
|
||||
- misskey-js
|
||||
steps:
|
||||
- uses: actions/checkout@v6.0.2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v6.0.3
|
||||
- uses: actions/setup-node@v6.4.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
- run: pnpm i --frozen-lockfile
|
||||
- run: pnpm --filter "${{ matrix.workspace }}^..." run build
|
||||
- run: pnpm --filter ${{ matrix.workspace }} run typecheck
|
||||
name: Lint
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
backend:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18.x
|
||||
cache: 'yarn'
|
||||
cache-dependency-path: |
|
||||
packages/backend/yarn.lock
|
||||
- run: yarn install
|
||||
- run: yarn --cwd ./packages/backend lint
|
||||
|
||||
client:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18.x
|
||||
cache: 'yarn'
|
||||
cache-dependency-path: |
|
||||
packages/client/yarn.lock
|
||||
- run: yarn install
|
||||
- run: yarn --cwd ./packages/client lint
|
||||
|
||||
33
.github/workflows/locale.yml
vendored
33
.github/workflows/locale.yml
vendored
@@ -1,33 +0,0 @@
|
||||
name: Lint
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- packages/i18n/**
|
||||
- locales/**
|
||||
- .github/workflows/locale.yml
|
||||
pull_request:
|
||||
paths:
|
||||
- packages/i18n/**
|
||||
- locales/**
|
||||
- .github/workflows/locale.yml
|
||||
jobs:
|
||||
locale_verify:
|
||||
runs-on: ubuntu-latest
|
||||
continue-on-error: true
|
||||
steps:
|
||||
- uses: actions/checkout@v6.0.2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v6.0.3
|
||||
- uses: actions/setup-node@v6.4.0
|
||||
with:
|
||||
node-version-file: ".node-version"
|
||||
cache: "pnpm"
|
||||
- run: pnpm i --frozen-lockfile
|
||||
- run: pnpm --filter i18n build
|
||||
- name: Verify Locales
|
||||
working-directory: ./packages/i18n
|
||||
run: pnpm run verify
|
||||
36
.github/workflows/ok-to-test.yml
vendored
Normal file
36
.github/workflows/ok-to-test.yml
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
# If someone with write access comments "/ok-to-test" on a pull request, emit a repository_dispatch event
|
||||
name: Ok To Test
|
||||
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
|
||||
jobs:
|
||||
ok-to-test:
|
||||
runs-on: ubuntu-latest
|
||||
# Only run for PRs, not issue comments
|
||||
if: ${{ github.event.issue.pull_request }}
|
||||
steps:
|
||||
# Generate a GitHub App installation access token from an App ID and private key
|
||||
# To create a new GitHub App:
|
||||
# https://developer.github.com/apps/building-github-apps/creating-a-github-app/
|
||||
# See app.yml for an example app manifest
|
||||
- name: Generate token
|
||||
id: generate_token
|
||||
uses: tibdex/github-app-token@v1
|
||||
with:
|
||||
app_id: ${{ secrets.DEPLOYBOT_APP_ID }}
|
||||
private_key: ${{ secrets.DEPLOYBOT_PRIVATE_KEY }}
|
||||
|
||||
- name: Slash Command Dispatch
|
||||
uses: peter-evans/slash-command-dispatch@v1
|
||||
env:
|
||||
TOKEN: ${{ steps.generate_token.outputs.token }}
|
||||
with:
|
||||
token: ${{ env.TOKEN }} # GitHub App installation access token
|
||||
# token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} # PAT or OAuth token will also work
|
||||
reaction-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-type: pull-request
|
||||
commands: deploy
|
||||
named-args: true
|
||||
permission: write
|
||||
41
.github/workflows/on-release-created.yml
vendored
41
.github/workflows/on-release-created.yml
vendored
@@ -1,41 +0,0 @@
|
||||
name: On Release Created (Publish misskey-js)
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [created]
|
||||
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
publish-misskey-js:
|
||||
name: Publish misskey-js
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6.0.2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v6.0.3
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v6.4.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
# see https://docs.github.com/actions/use-cases-and-examples/publishing-packages/publishing-nodejs-packages#publishing-packages-to-the-npm-registry
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
# Ensure npm 11.5.1 or later is installed
|
||||
- name: Update npm
|
||||
run: npm install -g npm@latest
|
||||
- name: Publish package
|
||||
run: |
|
||||
pnpm i --frozen-lockfile
|
||||
pnpm build
|
||||
pnpm --filter misskey-js publish --access public --no-git-checks --provenance
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }}
|
||||
NPM_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }}
|
||||
95
.github/workflows/pr-preview-deploy.yml
vendored
Normal file
95
.github/workflows/pr-preview-deploy.yml
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
# Run secret-dependent integration tests only after /deploy approval
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, reopened, synchronize]
|
||||
repository_dispatch:
|
||||
types: [deploy-command]
|
||||
|
||||
name: Deploy preview environment
|
||||
|
||||
jobs:
|
||||
# Repo owner has commented /deploy on a (fork-based) pull request
|
||||
deploy-preview-environment:
|
||||
runs-on: ubuntu-latest
|
||||
if:
|
||||
github.event_name == 'repository_dispatch' &&
|
||||
github.event.client_payload.slash_command.sha != '' &&
|
||||
contains(github.event.client_payload.pull_request.head.sha, github.event.client_payload.slash_command.sha)
|
||||
steps:
|
||||
- uses: actions/github-script@v5
|
||||
id: check-id
|
||||
env:
|
||||
number: ${{ github.event.client_payload.pull_request.number }}
|
||||
job: ${{ github.job }}
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
result-encoding: string
|
||||
script: |
|
||||
const { data: pull } = await github.rest.pulls.get({
|
||||
...context.repo,
|
||||
pull_number: process.env.number
|
||||
});
|
||||
const ref = pull.head.sha;
|
||||
|
||||
const { data: checks } = await github.rest.checks.listForRef({
|
||||
...context.repo,
|
||||
ref
|
||||
});
|
||||
|
||||
const check = checks.check_runs.filter(c => c.name === process.env.job);
|
||||
|
||||
return check[0].id;
|
||||
|
||||
- uses: actions/github-script@v5
|
||||
env:
|
||||
check_id: ${{ steps.check-id.outputs.result }}
|
||||
details_url: ${{ github.server_url }}/${{ github.repository }}/runs/${{ github.run_id }}
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
await github.rest.checks.update({
|
||||
...context.repo,
|
||||
check_run_id: process.env.check_id,
|
||||
status: 'in_progress',
|
||||
details_url: process.env.details_url
|
||||
});
|
||||
|
||||
# Check out merge commit
|
||||
- name: Fork based /deploy checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
ref: 'refs/pull/${{ github.event.client_payload.pull_request.number }}/merge'
|
||||
|
||||
# <insert integration tests needing secrets>
|
||||
- name: Context
|
||||
uses: okteto/context@latest
|
||||
with:
|
||||
token: ${{ secrets.OKTETO_TOKEN }}
|
||||
|
||||
- name: Deploy preview environment
|
||||
uses: ikuradon/deploy-preview@latest
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
name: pr-${{ github.event.client_payload.pull_request.number }}-syuilo
|
||||
timeout: 15m
|
||||
|
||||
# Update check run called "integration-fork"
|
||||
- uses: actions/github-script@v5
|
||||
id: update-check-run
|
||||
if: ${{ always() }}
|
||||
env:
|
||||
# Conveniently, job.status maps to https://developer.github.com/v3/checks/runs/#update-a-check-run
|
||||
conclusion: ${{ job.status }}
|
||||
check_id: ${{ steps.check-id.outputs.result }}
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
const { data: result } = await github.rest.checks.update({
|
||||
...context.repo,
|
||||
check_run_id: process.env.check_id,
|
||||
status: 'completed',
|
||||
conclusion: process.env.conclusion
|
||||
});
|
||||
|
||||
return result;
|
||||
21
.github/workflows/pr-preview-destroy.yml
vendored
Normal file
21
.github/workflows/pr-preview-destroy.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# file: .github/workflows/preview-closed.yaml
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- closed
|
||||
|
||||
name: Destroy preview environment
|
||||
|
||||
jobs:
|
||||
destroy-preview-environment:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Context
|
||||
uses: okteto/context@latest
|
||||
with:
|
||||
token: ${{ secrets.OKTETO_TOKEN }}
|
||||
|
||||
- name: Destroy preview environment
|
||||
uses: okteto/destroy-preview@latest
|
||||
with:
|
||||
name: pr-${{ github.event.number }}-syuilo
|
||||
48
.github/workflows/release-edit-with-push.yml
vendored
48
.github/workflows/release-edit-with-push.yml
vendored
@@ -1,48 +0,0 @@
|
||||
name: "Release Manager: sync changelog with PR"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- develop
|
||||
paths:
|
||||
- 'CHANGELOG.md'
|
||||
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
edit:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
# headが$GITHUB_REF_NAME, baseが$STABLE_BRANCHかつopenのPRを1つ取得
|
||||
- name: Get PR
|
||||
run: |
|
||||
echo "pr_number=$(gh pr list --limit 1 --search "head:$GITHUB_REF_NAME base:$STABLE_BRANCH is:open" --json number --jq '.[] | .number')" >> $GITHUB_OUTPUT
|
||||
id: get_pr
|
||||
env:
|
||||
STABLE_BRANCH: ${{ vars.STABLE_BRANCH }}
|
||||
- name: Get target version
|
||||
if: steps.get_pr.outputs.pr_number != ''
|
||||
uses: misskey-dev/release-manager-actions/.github/actions/get-target-version@v2
|
||||
id: v
|
||||
# CHANGELOG.mdの内容を取得
|
||||
- name: Get changelog
|
||||
if: steps.get_pr.outputs.pr_number != ''
|
||||
uses: misskey-dev/release-manager-actions/.github/actions/get-changelog@v2
|
||||
with:
|
||||
version: ${{ steps.v.outputs.target_version }}
|
||||
id: changelog
|
||||
# PRのnotesを更新
|
||||
- name: Update PR
|
||||
if: steps.get_pr.outputs.pr_number != ''
|
||||
run: |
|
||||
gh pr edit "$PR_NUMBER" --body "$CHANGELOG"
|
||||
env:
|
||||
PR_NUMBER: ${{ steps.get_pr.outputs.pr_number }}
|
||||
CHANGELOG: ${{ steps.changelog.outputs.changelog }}
|
||||
136
.github/workflows/release-with-dispatch.yml
vendored
136
.github/workflows/release-with-dispatch.yml
vendored
@@ -1,136 +0,0 @@
|
||||
name: "Release Manager [Dispatch]"
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
## Specify the type of the next release.
|
||||
#version_increment_type:
|
||||
# type: choice
|
||||
# description: 'VERSION INCREMENT TYPE'
|
||||
# default: 'patch'
|
||||
# required: false
|
||||
# options:
|
||||
# - 'major'
|
||||
# - 'minor'
|
||||
# - 'patch'
|
||||
merge:
|
||||
type: boolean
|
||||
description: 'MERGE RELEASE BRANCH TO MAIN'
|
||||
default: false
|
||||
start-rc:
|
||||
type: boolean
|
||||
description: 'Start Release Candidate'
|
||||
default: false
|
||||
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
get-pr:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
pr_number: ${{ steps.get_pr.outputs.pr_number }}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
# headが$GITHUB_REF_NAME, baseが$STABLE_BRANCHかつopenのPRを1つ取得
|
||||
- name: Get PRs
|
||||
run: |
|
||||
echo "pr_number=$(gh pr list --limit 1 --search "head:$GITHUB_REF_NAME base:$STABLE_BRANCH is:open" --json number --jq '.[] | .number')" >> $GITHUB_OUTPUT
|
||||
id: get_pr
|
||||
env:
|
||||
STABLE_BRANCH: ${{ vars.STABLE_BRANCH }}
|
||||
|
||||
merge:
|
||||
uses: misskey-dev/release-manager-actions/.github/workflows/merge.yml@v2
|
||||
needs: get-pr
|
||||
if: ${{ needs.get-pr.outputs.pr_number != '' && inputs.merge == true }}
|
||||
with:
|
||||
pr_number: ${{ needs.get-pr.outputs.pr_number }}
|
||||
user: 'github-actions[bot]'
|
||||
package_jsons_to_rewrite: ${{ vars.PACKAGE_JSONS_TO_REWRITE }}
|
||||
# Text to prepend to the changelog
|
||||
# The first line must be `## Unreleased`
|
||||
changes_template: |
|
||||
## Unreleased
|
||||
|
||||
### General
|
||||
-
|
||||
|
||||
### Client
|
||||
-
|
||||
|
||||
### Server
|
||||
-
|
||||
|
||||
use_external_app_to_release: ${{ vars.USE_RELEASE_APP == 'true' }}
|
||||
indent: ${{ vars.INDENT }}
|
||||
secrets:
|
||||
RELEASE_APP_ID: ${{ secrets.RELEASE_APP_ID }}
|
||||
RELEASE_APP_PRIVATE_KEY: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
|
||||
|
||||
create-prerelease:
|
||||
uses: misskey-dev/release-manager-actions/.github/workflows/create-prerelease.yml@v2
|
||||
needs: get-pr
|
||||
if: ${{ needs.get-pr.outputs.pr_number != '' && inputs.merge != true }}
|
||||
with:
|
||||
pr_number: ${{ needs.get-pr.outputs.pr_number }}
|
||||
user: 'github-actions[bot]'
|
||||
package_jsons_to_rewrite: ${{ vars.PACKAGE_JSONS_TO_REWRITE }}
|
||||
use_external_app_to_release: ${{ vars.USE_RELEASE_APP == 'true' }}
|
||||
indent: ${{ vars.INDENT }}
|
||||
draft_prerelease_channel: alpha
|
||||
ready_start_prerelease_channel: beta
|
||||
prerelease_channel: ${{ inputs.start-rc && 'rc' || '' }}
|
||||
reset_number_on_channel_change: true
|
||||
secrets:
|
||||
RELEASE_APP_ID: ${{ secrets.RELEASE_APP_ID }}
|
||||
RELEASE_APP_PRIVATE_KEY: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
|
||||
|
||||
create-target:
|
||||
uses: misskey-dev/release-manager-actions/.github/workflows/create-target.yml@v2
|
||||
needs: get-pr
|
||||
if: ${{ needs.get-pr.outputs.pr_number == '' }}
|
||||
with:
|
||||
user: 'github-actions[bot]'
|
||||
# The script for version increment.
|
||||
# process.env.CURRENT_VERSION: The current version.
|
||||
#
|
||||
# Misskey calender versioning (yyyy.MM.patch) example
|
||||
version_increment_script: |
|
||||
const now = new Date();
|
||||
const year = now.toLocaleDateString('en-US', { year: 'numeric', timeZone: 'Asia/Tokyo' });
|
||||
const month = now.toLocaleDateString('en-US', { month: 'numeric', timeZone: 'Asia/Tokyo' });
|
||||
const [major, minor, _patch] = process.env.CURRENT_VERSION.split('.');
|
||||
const patch = Number(_patch.split('-')[0]);
|
||||
if (Number.isNaN(patch)) {
|
||||
console.error('Invalid patch version', year, month, process.env.CURRENT_VERSION, major, minor, _patch);
|
||||
throw new Error('Invalid patch version');
|
||||
}
|
||||
if (year !== major || month !== minor) {
|
||||
return `${year}.${month}.0`;
|
||||
} else {
|
||||
return `${major}.${minor}.${patch + 1}`;
|
||||
}
|
||||
##Semver example
|
||||
#version_increment_script: |
|
||||
# const [major, minor, patch] = process.env.CURRENT_VERSION.split('.');
|
||||
# if ("${{ inputs.version_increment_type }}" === "major") {
|
||||
# return `${Number(major) + 1}.0.0`;
|
||||
# } else if ("${{ inputs.version_increment_type }}" === "minor") {
|
||||
# return `${major}.${Number(minor) + 1}.0`;
|
||||
# } else {
|
||||
# return `${major}.${minor}.${Number(patch) + 1}`;
|
||||
# }
|
||||
package_jsons_to_rewrite: ${{ vars.PACKAGE_JSONS_TO_REWRITE }}
|
||||
use_external_app_to_release: ${{ vars.USE_RELEASE_APP == 'true' }}
|
||||
indent: ${{ vars.INDENT }}
|
||||
stable_branch: ${{ vars.STABLE_BRANCH }}
|
||||
draft_prerelease_channel: alpha
|
||||
secrets:
|
||||
RELEASE_APP_ID: ${{ secrets.RELEASE_APP_ID }}
|
||||
RELEASE_APP_PRIVATE_KEY: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
|
||||
104
.github/workflows/report-api-diff.yml
vendored
104
.github/workflows/report-api-diff.yml
vendored
@@ -1,104 +0,0 @@
|
||||
name: Report API Diff
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
types: [completed]
|
||||
workflows:
|
||||
- Get api.json from Misskey # get-api-diff.yml
|
||||
|
||||
jobs:
|
||||
compare-diff:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
||||
permissions:
|
||||
pull-requests: write
|
||||
|
||||
# api-artifact
|
||||
steps:
|
||||
- name: Download artifact
|
||||
uses: actions/github-script@v9
|
||||
with:
|
||||
script: |
|
||||
const fs = require('fs');
|
||||
let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
run_id: context.payload.workflow_run.id,
|
||||
});
|
||||
let matchArtifacts = allArtifacts.data.artifacts.filter((artifact) => {
|
||||
return artifact.name.startsWith("api-artifact-") || artifact.name == "api-artifact"
|
||||
});
|
||||
await Promise.all(matchArtifacts.map(async (artifact) => {
|
||||
let download = await github.rest.actions.downloadArtifact({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
artifact_id: artifact.id,
|
||||
archive_format: 'zip',
|
||||
});
|
||||
await fs.promises.writeFile(`${process.env.GITHUB_WORKSPACE}/${artifact.name}.zip`, Buffer.from(download.data));
|
||||
}));
|
||||
- name: Extract all artifacts
|
||||
run: |
|
||||
find . -mindepth 1 -maxdepth 1 -type f -name '*.zip' -exec unzip {} -d artifacts ';'
|
||||
ls -la
|
||||
- name: Load PR Number
|
||||
id: load-pr-num
|
||||
run: echo "pr-number=$(cat artifacts/pr_number)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Output base
|
||||
run: cat ./artifacts/api-base.json
|
||||
- name: Output head
|
||||
run: cat ./artifacts/api-head.json
|
||||
- name: Arrange json files
|
||||
run: |
|
||||
jq '.' ./artifacts/api-base.json > ./api-base.json
|
||||
jq '.' ./artifacts/api-head.json > ./api-head.json
|
||||
- name: Get diff of 2 files
|
||||
run: diff -u --label=base --label=head ./api-base.json ./api-head.json | cat > api.json.diff
|
||||
- name: Get full diff
|
||||
run: diff --label=base --label=head --new-line-format='+%L' --old-line-format='-%L' --unchanged-line-format=' %L' ./api-base.json ./api-head.json | cat > api-full.json.diff
|
||||
- name: Echo full diff
|
||||
run: cat ./api-full.json.diff
|
||||
- name: Upload full diff to Artifact
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: api-artifact
|
||||
path: |
|
||||
api-full.json.diff
|
||||
api-base.json
|
||||
api-head.json
|
||||
- id: out-diff
|
||||
name: Build diff Comment
|
||||
run: |
|
||||
HEADER="このPRによるapi.jsonの差分"
|
||||
FOOTER="[Get diff files from Workflow Page](https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID})"
|
||||
DIFF_BYTES="$(stat ./api.json.diff -c '%s' | tr -d '\n')"
|
||||
|
||||
echo "$HEADER" > ./output.md
|
||||
|
||||
if (( "$DIFF_BYTES" <= 1 )); then
|
||||
echo '差分はありません。' >> ./output.md
|
||||
else
|
||||
echo '<details>' >> ./output.md
|
||||
echo '<summary>差分はこちら</summary>' >> ./output.md
|
||||
echo >> ./output.md
|
||||
echo '```diff' >> ./output.md
|
||||
cat ./api.json.diff >> ./output.md
|
||||
echo '```' >> ./output.md
|
||||
echo '</details>' >> .output.md
|
||||
fi
|
||||
|
||||
echo "$FOOTER" >> ./output.md
|
||||
- uses: thollander/actions-comment-pull-request@v3
|
||||
with:
|
||||
pr-number: ${{ steps.load-pr-num.outputs.pr-number }}
|
||||
comment-tag: show_diff
|
||||
file-path: ./output.md
|
||||
- name: Tell error to PR
|
||||
uses: thollander/actions-comment-pull-request@v3
|
||||
if: failure() && steps.load-pr-num.outputs.pr-number
|
||||
with:
|
||||
pr-number: ${{ steps.load-pr-num.outputs.pr-number }}
|
||||
comment-tag: show_diff_error
|
||||
message: |
|
||||
api.jsonの差分作成中にエラーが発生しました。詳細は[Workflowのログ](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})を確認してください。
|
||||
177
.github/workflows/report-backend-memory.yml
vendored
177
.github/workflows/report-backend-memory.yml
vendored
@@ -1,177 +0,0 @@
|
||||
name: Report backend memory
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
types: [completed]
|
||||
workflows:
|
||||
- Get backend memory usage # get-backend-memory.yml
|
||||
|
||||
jobs:
|
||||
compare-memory:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
||||
permissions:
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- name: Download artifact
|
||||
uses: actions/github-script@v9
|
||||
with:
|
||||
script: |
|
||||
const fs = require('fs');
|
||||
let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
run_id: context.payload.workflow_run.id,
|
||||
});
|
||||
let matchArtifacts = allArtifacts.data.artifacts.filter((artifact) => {
|
||||
return artifact.name.startsWith("memory-artifact-") || artifact.name == "memory-artifact"
|
||||
});
|
||||
await Promise.all(matchArtifacts.map(async (artifact) => {
|
||||
let download = await github.rest.actions.downloadArtifact({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
artifact_id: artifact.id,
|
||||
archive_format: 'zip',
|
||||
});
|
||||
await fs.promises.writeFile(`${process.env.GITHUB_WORKSPACE}/${artifact.name}.zip`, Buffer.from(download.data));
|
||||
}));
|
||||
- name: Extract all artifacts
|
||||
run: |
|
||||
find . -mindepth 1 -maxdepth 1 -type f -name '*.zip' -exec unzip {} -d artifacts ';'
|
||||
ls -la artifacts/
|
||||
- name: Load PR Number
|
||||
id: load-pr-num
|
||||
run: echo "pr-number=$(cat artifacts/pr_number)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Output base
|
||||
run: cat ./artifacts/memory-base.json
|
||||
- name: Output head
|
||||
run: cat ./artifacts/memory-head.json
|
||||
- name: Compare memory usage
|
||||
id: compare
|
||||
run: |
|
||||
BASE_MEMORY=$(cat ./artifacts/memory-base.json)
|
||||
HEAD_MEMORY=$(cat ./artifacts/memory-head.json)
|
||||
|
||||
variation() {
|
||||
calc() {
|
||||
BASE=$(echo "$BASE_MEMORY" | jq -r ".${1}.${2} // 0")
|
||||
HEAD=$(echo "$HEAD_MEMORY" | jq -r ".${1}.${2} // 0")
|
||||
|
||||
DIFF=$((HEAD - BASE))
|
||||
if [ "$BASE" -gt 0 ]; then
|
||||
DIFF_PERCENT=$(echo "scale=2; ($DIFF * 100) / $BASE" | bc)
|
||||
else
|
||||
DIFF_PERCENT=0
|
||||
fi
|
||||
|
||||
# Convert KB to MB for readability
|
||||
BASE_MB=$(echo "scale=2; $BASE / 1024" | bc)
|
||||
HEAD_MB=$(echo "scale=2; $HEAD / 1024" | bc)
|
||||
DIFF_MB=$(echo "scale=2; $DIFF / 1024" | bc)
|
||||
|
||||
JSON=$(jq -c -n \
|
||||
--argjson base "$BASE_MB" \
|
||||
--argjson head "$HEAD_MB" \
|
||||
--argjson diff "$DIFF_MB" \
|
||||
--argjson diff_percent "$DIFF_PERCENT" \
|
||||
'{base: $base, head: $head, diff: $diff, diff_percent: $diff_percent}')
|
||||
|
||||
echo "$JSON"
|
||||
}
|
||||
|
||||
JSON=$(jq -c -n \
|
||||
--argjson VmRSS "$(calc $1 VmRSS)" \
|
||||
--argjson VmHWM "$(calc $1 VmHWM)" \
|
||||
--argjson VmSize "$(calc $1 VmSize)" \
|
||||
--argjson VmData "$(calc $1 VmData)" \
|
||||
'{VmRSS: $VmRSS, VmHWM: $VmHWM, VmSize: $VmSize, VmData: $VmData}')
|
||||
|
||||
echo "$JSON"
|
||||
}
|
||||
|
||||
JSON=$(jq -c -n \
|
||||
--argjson beforeGc "$(variation beforeGc)" \
|
||||
--argjson afterGc "$(variation afterGc)" \
|
||||
--argjson afterRequest "$(variation afterRequest)" \
|
||||
'{beforeGc: $beforeGc, afterGc: $afterGc, afterRequest: $afterRequest}')
|
||||
|
||||
echo "res=$JSON" >> "$GITHUB_OUTPUT"
|
||||
- id: build-comment
|
||||
name: Build memory comment
|
||||
env:
|
||||
RES: ${{ steps.compare.outputs.res }}
|
||||
run: |
|
||||
HEADER="## Backend memory usage comparison"
|
||||
FOOTER="[See workflow logs for details](https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID})"
|
||||
|
||||
echo "$HEADER" > ./output.md
|
||||
echo >> ./output.md
|
||||
|
||||
table() {
|
||||
echo "| Metric | base (MB) | head (MB) | Diff (MB) | Diff (%) |" >> ./output.md
|
||||
echo "|--------|------:|------:|------:|------:|" >> ./output.md
|
||||
|
||||
line() {
|
||||
METRIC=$2
|
||||
BASE=$(echo "$RES" | jq -r ".${1}.${2}.base")
|
||||
HEAD=$(echo "$RES" | jq -r ".${1}.${2}.head")
|
||||
DIFF=$(echo "$RES" | jq -r ".${1}.${2}.diff")
|
||||
DIFF_PERCENT=$(echo "$RES" | jq -r ".${1}.${2}.diff_percent")
|
||||
|
||||
if (( $(echo "$DIFF_PERCENT > 0" | bc -l) )); then
|
||||
DIFF="+$DIFF"
|
||||
DIFF_PERCENT="+$DIFF_PERCENT"
|
||||
fi
|
||||
|
||||
# highlight VmRSS
|
||||
if [ "$2" = "VmRSS" ]; then
|
||||
METRIC="**${METRIC}**"
|
||||
BASE="**${BASE}**"
|
||||
HEAD="**${HEAD}**"
|
||||
DIFF="**${DIFF}**"
|
||||
DIFF_PERCENT="**${DIFF_PERCENT}**"
|
||||
fi
|
||||
|
||||
echo "| ${METRIC} | ${BASE} MB | ${HEAD} MB | ${DIFF} MB | ${DIFF_PERCENT}% |" >> ./output.md
|
||||
}
|
||||
|
||||
line $1 VmRSS
|
||||
line $1 VmHWM
|
||||
line $1 VmSize
|
||||
line $1 VmData
|
||||
}
|
||||
|
||||
echo "### Before GC" >> ./output.md
|
||||
table beforeGc
|
||||
echo >> ./output.md
|
||||
|
||||
echo "### After GC" >> ./output.md
|
||||
table afterGc
|
||||
echo >> ./output.md
|
||||
|
||||
echo "### After Request" >> ./output.md
|
||||
table afterRequest
|
||||
echo >> ./output.md
|
||||
|
||||
# Determine if this is a significant change (more than 5% increase)
|
||||
if [ "$(echo "$RES" | jq -r '.afterGc.VmRSS.diff_percent | tonumber > 5')" = "true" ]; then
|
||||
echo "⚠️ **Warning**: Memory usage has increased by more than 5%. Please verify this is not an unintended change." >> ./output.md
|
||||
echo >> ./output.md
|
||||
fi
|
||||
|
||||
echo "$FOOTER" >> ./output.md
|
||||
- uses: thollander/actions-comment-pull-request@v3
|
||||
with:
|
||||
pr-number: ${{ steps.load-pr-num.outputs.pr-number }}
|
||||
comment-tag: show_memory_diff
|
||||
file-path: ./output.md
|
||||
- name: Tell error to PR
|
||||
uses: thollander/actions-comment-pull-request@v3
|
||||
if: failure() && steps.load-pr-num.outputs.pr-number
|
||||
with:
|
||||
pr-number: ${{ steps.load-pr-num.outputs.pr-number }}
|
||||
comment-tag: show_memory_diff_error
|
||||
message: |
|
||||
An error occurred while comparing backend memory usage. See [workflow logs](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details.
|
||||
51
.github/workflows/request-release-review.yml
vendored
51
.github/workflows/request-release-review.yml
vendored
@@ -1,51 +0,0 @@
|
||||
name: Request release review
|
||||
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
|
||||
jobs:
|
||||
reply:
|
||||
if: github.event.comment.body == '/request-release-review'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Reply
|
||||
uses: actions/github-script@v9
|
||||
with:
|
||||
script: |
|
||||
const body = `To dev team (@misskey-dev/dev):
|
||||
|
||||
リリースが提案されています :rocket:
|
||||
|
||||
GOの場合はapprove、NO GOの場合はその旨コメントをお願いいたします。
|
||||
|
||||
判断にあたって考慮すべき観点は、
|
||||
|
||||
- やり残したことはないか?
|
||||
- CHANGELOGは過不足ないか?
|
||||
- バージョンに問題はないか?(月跨いでいるのに更新忘れているなど)
|
||||
- 再考すべき仕様・実装はないか?
|
||||
- ベータ版を検証したサーバーから不具合の報告等は上がってないか?
|
||||
- (セキュリティの修正や重要なバグ修正などのため)リリースを急いだ方が良いか?そうではないか?
|
||||
- Actionsが落ちていないか?
|
||||
|
||||
などが挙げられます。
|
||||
|
||||
ご協力ありがとうございます :sparkles:
|
||||
`
|
||||
|
||||
const issue_number = context.payload.issue ? context.payload.issue.number : (context.payload.pull_request && context.payload.pull_request.number)
|
||||
if (!issue_number) {
|
||||
console.log('No issue or PR number found in payload; skipping')
|
||||
} else {
|
||||
await github.rest.issues.createComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number,
|
||||
body,
|
||||
})
|
||||
}
|
||||
108
.github/workflows/storybook.yml
vendored
108
.github/workflows/storybook.yml
vendored
@@ -1,108 +0,0 @@
|
||||
name: Storybook
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
pull_request_target:
|
||||
branches-ignore:
|
||||
# Since pull requests targets master mostly is the "develop" branch.
|
||||
# Storybook CI is checked on the "push" event of "develop" branch so it would cause a duplicate build.
|
||||
# This is a waste of chromatic build quota, so we don't run storybook CI on pull requests targets master.
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
# Chromatic is not likely to be available for fork repositories, so we disable for fork repositories.
|
||||
if: github.repository == 'misskey-dev/misskey'
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
env:
|
||||
NODE_OPTIONS: "--max_old_space_size=7168"
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6.0.2
|
||||
if: github.event_name != 'pull_request_target'
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
- uses: actions/checkout@v6.0.2
|
||||
if: github.event_name == 'pull_request_target'
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
ref: "refs/pull/${{ github.event.number }}/merge"
|
||||
- name: Checkout actual HEAD
|
||||
if: github.event_name == 'pull_request_target'
|
||||
run: git checkout "$(git rev-list --parents -n1 HEAD | cut -d" " -f3)"
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v6.0.3
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v6.4.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
- run: pnpm i --frozen-lockfile
|
||||
- name: Check pnpm-lock.yaml
|
||||
run: git diff --exit-code pnpm-lock.yaml
|
||||
- name: Build dependent packages
|
||||
run: pnpm -F misskey-js -F misskey-bubble-game -F misskey-reversi build
|
||||
- name: Build storybook
|
||||
run: pnpm --filter frontend build-storybook
|
||||
- name: Publish to Chromatic
|
||||
if: github.event_name != 'pull_request_target' && github.ref == 'refs/heads/master'
|
||||
run: pnpm --filter frontend chromatic --exit-once-uploaded -d storybook-static
|
||||
env:
|
||||
CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
|
||||
- name: Publish to Chromatic
|
||||
if: github.event_name != 'pull_request_target' && github.ref != 'refs/heads/master'
|
||||
id: chromatic_push
|
||||
run: |
|
||||
DIFF="${{ github.event.before }} HEAD"
|
||||
if [ "$DIFF" = "0000000000000000000000000000000000000000 HEAD" ]; then
|
||||
DIFF="HEAD"
|
||||
fi
|
||||
CHROMATIC_PARAMETER="$(node packages/frontend/.storybook/changes.js $(git diff-tree --no-commit-id --name-only -r $(echo "$DIFF") | xargs))"
|
||||
if [ "$CHROMATIC_PARAMETER" = " --skip" ]; then
|
||||
echo "skip=true" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
if pnpm --filter frontend chromatic -d storybook-static $(echo "$CHROMATIC_PARAMETER"); then
|
||||
echo "success=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "success=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
env:
|
||||
CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
|
||||
- name: Publish to Chromatic
|
||||
if: github.event_name == 'pull_request_target'
|
||||
id: chromatic_pull_request
|
||||
run: |
|
||||
CHROMATIC_PARAMETER="$(node packages/frontend/.storybook/changes.js $(git diff --name-only origin/${GITHUB_BASE_REF}...origin/${GITHUB_HEAD_REF} | xargs))"
|
||||
if [ "$CHROMATIC_PARAMETER" = " --skip" ]; then
|
||||
echo "skip=true" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
BRANCH="${{ github.event.pull_request.head.user.login }}:$GITHUB_HEAD_REF"
|
||||
if [ "$BRANCH" = "misskey-dev:$GITHUB_HEAD_REF" ]; then
|
||||
BRANCH="$GITHUB_HEAD_REF"
|
||||
fi
|
||||
pnpm --filter frontend chromatic --exit-once-uploaded -d storybook-static --branch-name "$BRANCH" $(echo "$CHROMATIC_PARAMETER")
|
||||
env:
|
||||
CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
|
||||
- name: Notify that Chromatic detects changes
|
||||
uses: actions/github-script@v9
|
||||
if: github.event_name != 'pull_request_target' && steps.chromatic_push.outputs.success == 'false'
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
github.rest.repos.createCommitComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
commit_sha: context.sha,
|
||||
body: 'Chromatic detects changes. Please [review the changes on Chromatic](https://www.chromatic.com/builds?appId=6428f7d7b962f0b79f97d6e4).'
|
||||
})
|
||||
- name: Upload Artifacts
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: storybook
|
||||
path: packages/frontend/storybook-static
|
||||
206
.github/workflows/test-backend.yml
vendored
206
.github/workflows/test-backend.yml
vendored
@@ -1,206 +0,0 @@
|
||||
name: Test (backend)
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
paths:
|
||||
- packages/backend/**
|
||||
# for permissions
|
||||
- packages/misskey-js/**
|
||||
- .github/workflows/test-backend.yml
|
||||
- .github/misskey/test.yml
|
||||
pull_request:
|
||||
paths:
|
||||
- packages/backend/**
|
||||
# for permissions
|
||||
- packages/misskey-js/**
|
||||
- .github/workflows/test-backend.yml
|
||||
- .github/misskey/test.yml
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
force_ffmpeg_cache_update:
|
||||
description: 'Force update ffmpeg cache'
|
||||
required: false
|
||||
default: false
|
||||
type: boolean
|
||||
|
||||
jobs:
|
||||
unit:
|
||||
name: Unit tests (backend)
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version-file:
|
||||
- .node-version
|
||||
- .github/min.node-version
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:18
|
||||
ports:
|
||||
- 54312:5432
|
||||
env:
|
||||
POSTGRES_DB: test-misskey
|
||||
POSTGRES_HOST_AUTH_METHOD: trust
|
||||
redis:
|
||||
image: redis:8
|
||||
ports:
|
||||
- 56312:6379
|
||||
meilisearch:
|
||||
image: getmeili/meilisearch:v1.42.1
|
||||
ports:
|
||||
- 57712:7700
|
||||
env:
|
||||
MEILI_NO_ANALYTICS: true
|
||||
MEILI_ENV: development
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6.0.2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v6.0.3
|
||||
- name: Get current date
|
||||
id: current-date
|
||||
run: echo "today=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT
|
||||
- name: Setup and Restore ffmpeg/ffprobe Cache
|
||||
id: cache-ffmpeg
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: |
|
||||
/usr/local/bin/ffmpeg
|
||||
/usr/local/bin/ffprobe
|
||||
# daily cache
|
||||
key: ${{ runner.os }}-ffmpeg-${{ steps.current-date.outputs.today }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-ffmpeg-${{ steps.current-date.outputs.today }}
|
||||
- name: Install FFmpeg
|
||||
if: steps.cache-ffmpeg.outputs.cache-hit != 'true' || github.event.inputs.force_ffmpeg_cache_update == true
|
||||
run: |
|
||||
for i in {1..3}; do
|
||||
echo "Attempt $i: Installing FFmpeg..."
|
||||
curl -s -L https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz -o ffmpeg.tar.xz && \
|
||||
tar -xf ffmpeg.tar.xz && \
|
||||
mv ffmpeg-*-static/ffmpeg /usr/local/bin/ && \
|
||||
mv ffmpeg-*-static/ffprobe /usr/local/bin/ && \
|
||||
rm -rf ffmpeg.tar.xz ffmpeg-*-static/ && \
|
||||
break || sleep 10
|
||||
if [ $i -eq 3 ]; then
|
||||
echo "Failed to install FFmpeg after 3 attempts"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v6.4.0
|
||||
with:
|
||||
node-version-file: ${{ matrix.node-version-file }}
|
||||
cache: 'pnpm'
|
||||
- run: pnpm i --frozen-lockfile
|
||||
- name: Check pnpm-lock.yaml
|
||||
run: git diff --exit-code pnpm-lock.yaml
|
||||
- name: Copy Configure
|
||||
run: cp .github/misskey/test.yml .config
|
||||
- name: Build
|
||||
run: pnpm build
|
||||
- name: Test
|
||||
run: pnpm --filter backend test-and-coverage
|
||||
- name: Upload to Codecov
|
||||
uses: codecov/codecov-action@v6
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
files: ./packages/backend/coverage/coverage-final.json
|
||||
|
||||
e2e:
|
||||
name: E2E tests (backend)
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node-version-file:
|
||||
- .node-version
|
||||
- .github/min.node-version
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:18
|
||||
ports:
|
||||
- 54312:5432
|
||||
env:
|
||||
POSTGRES_DB: test-misskey
|
||||
POSTGRES_HOST_AUTH_METHOD: trust
|
||||
redis:
|
||||
image: redis:8
|
||||
ports:
|
||||
- 56312:6379
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6.0.2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v6.0.3
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v6.4.0
|
||||
with:
|
||||
node-version-file: ${{ matrix.node-version-file }}
|
||||
cache: 'pnpm'
|
||||
- run: pnpm i --frozen-lockfile
|
||||
- name: Check pnpm-lock.yaml
|
||||
run: git diff --exit-code pnpm-lock.yaml
|
||||
- name: Copy Configure
|
||||
run: cp .github/misskey/test.yml .config
|
||||
- name: Build
|
||||
run: pnpm build
|
||||
- name: Test
|
||||
run: pnpm --filter backend test-and-coverage:e2e
|
||||
- name: Upload to Codecov
|
||||
uses: codecov/codecov-action@v6
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
files: ./packages/backend/coverage/coverage-final.json
|
||||
|
||||
migration:
|
||||
name: Migration tests (backend)
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version-file:
|
||||
- .node-version
|
||||
#- .github/min.node-version
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:18
|
||||
ports:
|
||||
- 54312:5432
|
||||
env:
|
||||
POSTGRES_DB: test-misskey
|
||||
POSTGRES_HOST_AUTH_METHOD: trust
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6.0.2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v6.0.3
|
||||
- name: Get current date
|
||||
id: current-date
|
||||
run: echo "today=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v6.4.0
|
||||
with:
|
||||
node-version-file: ${{ matrix.node-version-file }}
|
||||
cache: 'pnpm'
|
||||
- run: pnpm i --frozen-lockfile
|
||||
- name: Check pnpm-lock.yaml
|
||||
run: git diff --exit-code pnpm-lock.yaml
|
||||
- name: Copy Configure
|
||||
run: cp .github/misskey/test.yml .config
|
||||
- name: Build
|
||||
run: pnpm build
|
||||
- name: Run migrations
|
||||
run: MISSKEY_CONFIG_YML=test.yml pnpm --filter backend migrate
|
||||
- name: Check no migrations are remaining
|
||||
run: MISSKEY_CONFIG_YML=test.yml pnpm --filter backend check-migrations
|
||||
111
.github/workflows/test-federation.yml
vendored
111
.github/workflows/test-federation.yml
vendored
@@ -1,111 +0,0 @@
|
||||
name: Test (federation)
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
paths:
|
||||
- packages/backend/**
|
||||
- packages/misskey-js/**
|
||||
- .github/workflows/test-federation.yml
|
||||
pull_request:
|
||||
paths:
|
||||
- packages/backend/**
|
||||
- packages/misskey-js/**
|
||||
- .github/workflows/test-federation.yml
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
force_ffmpeg_cache_update:
|
||||
description: 'Force update ffmpeg cache'
|
||||
required: false
|
||||
default: false
|
||||
type: boolean
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Federation test
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version-file:
|
||||
- .node-version
|
||||
- .github/min.node-version
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: true
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v6.0.3
|
||||
- name: Get current date
|
||||
id: current-date
|
||||
run: echo "today=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT
|
||||
- name: Setup and Restore ffmpeg/ffprobe Cache
|
||||
id: cache-ffmpeg
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: |
|
||||
/usr/local/bin/ffmpeg
|
||||
/usr/local/bin/ffprobe
|
||||
# daily cache
|
||||
key: ${{ runner.os }}-ffmpeg-${{ steps.current-date.outputs.today }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-ffmpeg-${{ steps.current-date.outputs.today }}
|
||||
- name: Install FFmpeg
|
||||
if: steps.cache-ffmpeg.outputs.cache-hit != 'true' || github.event.inputs.force_ffmpeg_cache_update == true
|
||||
run: |
|
||||
for i in {1..3}; do
|
||||
echo "Attempt $i: Installing FFmpeg..."
|
||||
curl -s -L https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz -o ffmpeg.tar.xz && \
|
||||
tar -xf ffmpeg.tar.xz && \
|
||||
mv ffmpeg-*-static/ffmpeg /usr/local/bin/ && \
|
||||
mv ffmpeg-*-static/ffprobe /usr/local/bin/ && \
|
||||
rm -rf ffmpeg.tar.xz ffmpeg-*-static/ && \
|
||||
break || sleep 10
|
||||
if [ $i -eq 3 ]; then
|
||||
echo "Failed to install FFmpeg after 3 attempts"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v6.4.0
|
||||
with:
|
||||
node-version-file: ${{ matrix.node-version-file }}
|
||||
cache: 'pnpm'
|
||||
- name: Build Misskey
|
||||
run: |
|
||||
pnpm i --frozen-lockfile
|
||||
pnpm build
|
||||
- name: Setup
|
||||
run: |
|
||||
echo "NODE_VERSION=$(cat ${{ matrix.node-version-file }})" >> $GITHUB_ENV
|
||||
cd packages/backend/test-federation
|
||||
bash ./setup.sh
|
||||
sudo chmod 644 ./certificates/*.test.key
|
||||
- name: Start servers
|
||||
id: start_servers
|
||||
continue-on-error: true
|
||||
# https://github.com/docker/compose/issues/1294#issuecomment-374847206
|
||||
run: |
|
||||
cd packages/backend/test-federation
|
||||
docker compose up -d --scale tester=0
|
||||
- name: Print start_servers error
|
||||
if: ${{ steps.start_servers.outcome == 'failure' }}
|
||||
run: |
|
||||
cd packages/backend/test-federation
|
||||
docker compose logs | tail -n 300
|
||||
exit 1
|
||||
- name: Test
|
||||
run: |
|
||||
cd packages/backend/test-federation
|
||||
docker compose run --no-deps tester
|
||||
- name: Log
|
||||
if: always()
|
||||
run: |
|
||||
cd packages/backend/test-federation
|
||||
docker compose logs
|
||||
- name: Stop servers
|
||||
if: always()
|
||||
run: |
|
||||
cd packages/backend/test-federation
|
||||
docker compose down
|
||||
125
.github/workflows/test-frontend.yml
vendored
125
.github/workflows/test-frontend.yml
vendored
@@ -1,125 +0,0 @@
|
||||
name: Test (frontend)
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
paths:
|
||||
- packages/frontend/**
|
||||
# for permissions
|
||||
- packages/misskey-js/**
|
||||
# for e2e
|
||||
- packages/backend/**
|
||||
- .github/workflows/test-frontend.yml
|
||||
- .github/misskey/test.yml
|
||||
pull_request:
|
||||
paths:
|
||||
- packages/frontend/**
|
||||
# for permissions
|
||||
- packages/misskey-js/**
|
||||
# for e2e
|
||||
- packages/backend/**
|
||||
- .github/workflows/test-frontend.yml
|
||||
- .github/misskey/test.yml
|
||||
jobs:
|
||||
vitest:
|
||||
name: Unit tests (frontend)
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6.0.2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v6.0.3
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v6.4.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
- run: pnpm i --frozen-lockfile
|
||||
- name: Check pnpm-lock.yaml
|
||||
run: git diff --exit-code pnpm-lock.yaml
|
||||
- name: Copy Configure
|
||||
run: cp .github/misskey/test.yml .config
|
||||
- name: Build
|
||||
run: pnpm build
|
||||
- name: Test
|
||||
run: pnpm --filter frontend test-and-coverage
|
||||
- name: Upload Coverage
|
||||
uses: codecov/codecov-action@v6
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
files: ./packages/frontend/coverage/coverage-final.json
|
||||
|
||||
e2e:
|
||||
name: E2E tests (frontend)
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
browser: [chrome]
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:18
|
||||
ports:
|
||||
- 54312:5432
|
||||
env:
|
||||
POSTGRES_DB: test-misskey
|
||||
POSTGRES_HOST_AUTH_METHOD: trust
|
||||
redis:
|
||||
image: redis:8
|
||||
ports:
|
||||
- 56312:6379
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6.0.2
|
||||
with:
|
||||
submodules: true
|
||||
# https://github.com/cypress-io/cypress-docker-images/issues/150
|
||||
#- name: Install mplayer for FireFox
|
||||
# run: sudo apt install mplayer -y
|
||||
# if: ${{ matrix.browser == 'firefox' }}
|
||||
#- uses: browser-actions/setup-firefox@latest
|
||||
# if: ${{ matrix.browser == 'firefox' }}
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v6.0.3
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v6.4.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
- run: pnpm i --frozen-lockfile
|
||||
- name: Copy Configure
|
||||
run: cp .github/misskey/test.yml .config
|
||||
- name: Build
|
||||
run: pnpm build
|
||||
# https://github.com/cypress-io/cypress/issues/4351#issuecomment-559489091
|
||||
- name: ALSA Env
|
||||
run: echo -e 'pcm.!default {\n type hw\n card 0\n}\n\nctl.!default {\n type hw\n card 0\n}' > ~/.asoundrc
|
||||
# XXX: This tries reinstalling Cypress if the binary is not cached
|
||||
# Remove this when the cache issue is fixed
|
||||
- name: Cypress install
|
||||
run: pnpm exec cypress install
|
||||
- name: Cypress run
|
||||
uses: cypress-io/github-action@v7.1.9
|
||||
timeout-minutes: 15
|
||||
with:
|
||||
install: false
|
||||
start: pnpm start:test
|
||||
wait-on: 'http://localhost:61812'
|
||||
headed: true
|
||||
browser: ${{ matrix.browser }}
|
||||
- uses: actions/upload-artifact@v7
|
||||
if: failure()
|
||||
with:
|
||||
name: ${{ matrix.browser }}-cypress-screenshots
|
||||
path: cypress/screenshots
|
||||
- uses: actions/upload-artifact@v7
|
||||
if: always()
|
||||
with:
|
||||
name: ${{ matrix.browser }}-cypress-videos
|
||||
path: cypress/videos
|
||||
54
.github/workflows/test-misskey-js.yml
vendored
54
.github/workflows/test-misskey-js.yml
vendored
@@ -1,54 +0,0 @@
|
||||
# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
|
||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
|
||||
|
||||
name: Test (misskey.js)
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ develop ]
|
||||
paths:
|
||||
- packages/misskey-js/**
|
||||
- .github/workflows/test-misskey-js.yml
|
||||
pull_request:
|
||||
branches: [ develop ]
|
||||
paths:
|
||||
- packages/misskey-js/**
|
||||
- .github/workflows/test-misskey-js.yml
|
||||
jobs:
|
||||
test:
|
||||
name: Unit tests (misskey.js)
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6.0.2
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v6.0.3
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6.4.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm i --frozen-lockfile
|
||||
|
||||
- name: Check pnpm-lock.yaml
|
||||
run: git diff --exit-code pnpm-lock.yaml
|
||||
|
||||
- name: Build
|
||||
run: pnpm --filter misskey-js build
|
||||
|
||||
- name: Test
|
||||
run: pnpm --filter misskey-js test
|
||||
env:
|
||||
CI: true
|
||||
|
||||
- name: Upload Coverage
|
||||
uses: codecov/codecov-action@v6
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
files: ./packages/misskey-js/coverage/coverage-final.json
|
||||
35
.github/workflows/test-production.yml
vendored
35
.github/workflows/test-production.yml
vendored
@@ -1,35 +0,0 @@
|
||||
name: Test (production install and build)
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
pull_request:
|
||||
|
||||
env:
|
||||
NODE_ENV: production
|
||||
|
||||
jobs:
|
||||
production:
|
||||
name: Production build
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6.0.2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v6.0.3
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v6.4.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
- run: pnpm i --frozen-lockfile
|
||||
- name: Check pnpm-lock.yaml
|
||||
run: git diff --exit-code pnpm-lock.yaml
|
||||
- name: Copy Configure
|
||||
run: cp .github/misskey/test.yml .config/default.yml
|
||||
- name: Build
|
||||
run: pnpm build
|
||||
122
.github/workflows/test.yml
vendored
Normal file
122
.github/workflows/test.yml
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
name: Test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
mocha:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [18.x]
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:13
|
||||
ports:
|
||||
- 54312:5432
|
||||
env:
|
||||
POSTGRES_DB: test-misskey
|
||||
POSTGRES_HOST_AUTH_METHOD: trust
|
||||
redis:
|
||||
image: redis:6
|
||||
ports:
|
||||
- 56312:6379
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'yarn'
|
||||
cache-dependency-path: |
|
||||
packages/backend/yarn.lock
|
||||
packages/client/yarn.lock
|
||||
- name: Install dependencies
|
||||
run: yarn install
|
||||
- name: Check yarn.lock
|
||||
run: git diff --exit-code yarn.lock
|
||||
- name: Copy Configure
|
||||
run: cp .github/misskey/test.yml .config
|
||||
- name: Build
|
||||
run: yarn build
|
||||
- name: Test
|
||||
run: yarn mocha
|
||||
|
||||
e2e:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node-version: [18.x]
|
||||
browser: [chrome]
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:13
|
||||
ports:
|
||||
- 54312:5432
|
||||
env:
|
||||
POSTGRES_DB: test-misskey
|
||||
POSTGRES_HOST_AUTH_METHOD: trust
|
||||
redis:
|
||||
image: redis:6
|
||||
ports:
|
||||
- 56312:6379
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
# https://github.com/cypress-io/cypress-docker-images/issues/150
|
||||
#- name: Install mplayer for FireFox
|
||||
# run: sudo apt install mplayer -y
|
||||
# if: ${{ matrix.browser == 'firefox' }}
|
||||
#- uses: browser-actions/setup-firefox@latest
|
||||
# if: ${{ matrix.browser == 'firefox' }}
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'yarn'
|
||||
cache-dependency-path: |
|
||||
packages/backend/yarn.lock
|
||||
packages/client/yarn.lock
|
||||
- name: Install dependencies
|
||||
run: yarn install
|
||||
- name: Check yarn.lock
|
||||
run: git diff --exit-code yarn.lock
|
||||
- name: Copy Configure
|
||||
run: cp .github/misskey/test.yml .config
|
||||
- name: Build
|
||||
run: yarn build
|
||||
# https://github.com/cypress-io/cypress/issues/4351#issuecomment-559489091
|
||||
- name: ALSA Env
|
||||
run: echo -e 'pcm.!default {\n type hw\n card 0\n}\n\nctl.!default {\n type hw\n card 0\n}' > ~/.asoundrc
|
||||
- name: Cypress run
|
||||
uses: cypress-io/github-action@v4
|
||||
with:
|
||||
install: false
|
||||
start: npm run start:test
|
||||
wait-on: 'http://localhost:61812'
|
||||
headless: false
|
||||
browser: ${{ matrix.browser }}
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: failure()
|
||||
with:
|
||||
name: ${{ matrix.browser }}-cypress-screenshots
|
||||
path: cypress/screenshots
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: always()
|
||||
with:
|
||||
name: ${{ matrix.browser }}-cypress-videos
|
||||
path: cypress/videos
|
||||
40
.github/workflows/validate-api-json.yml
vendored
40
.github/workflows/validate-api-json.yml
vendored
@@ -1,40 +0,0 @@
|
||||
name: api.json validation
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
paths:
|
||||
- packages/backend/**
|
||||
- .github/workflows/validate-api-json.yml
|
||||
pull_request:
|
||||
paths:
|
||||
- packages/backend/**
|
||||
- .github/workflows/validate-api-json.yml
|
||||
jobs:
|
||||
validate-api-json:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6.0.2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v6.0.3
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v6.4.0
|
||||
with:
|
||||
node-version-file: '.node-version'
|
||||
cache: 'pnpm'
|
||||
- name: Install Redocly CLI
|
||||
run: npm i -g @redocly/cli
|
||||
- run: pnpm i --frozen-lockfile
|
||||
- name: Check pnpm-lock.yaml
|
||||
run: git diff --exit-code pnpm-lock.yaml
|
||||
- name: Copy Configure
|
||||
run: cp .config/example.yml .config/default.yml
|
||||
- name: Build and generate
|
||||
run: pnpm build && pnpm --filter backend generate-api-json
|
||||
- name: Validation
|
||||
run: npx @redocly/cli lint --extends=minimal ./packages/backend/built/api.json
|
||||
38
.gitignore
vendored
38
.gitignore
vendored
@@ -9,20 +9,6 @@
|
||||
node_modules
|
||||
report.*.json
|
||||
|
||||
# Yarn
|
||||
.yarn/*
|
||||
!.yarn/patches
|
||||
!.yarn/plugins
|
||||
!.yarn/releases
|
||||
!.yarn/sdks
|
||||
!.yarn/versions
|
||||
packages/frontend/.yarn/cache
|
||||
packages/backend/.yarn/cache
|
||||
packages/sw/.yarn/cache
|
||||
|
||||
# pnpm
|
||||
.pnpm-store
|
||||
|
||||
# Cypress
|
||||
cypress/screenshots
|
||||
cypress/videos
|
||||
@@ -33,24 +19,15 @@ coverage
|
||||
# config
|
||||
/.config/*
|
||||
!/.config/example.yml
|
||||
!/.config/docker_example.yml
|
||||
!/.config/docker_example.env
|
||||
!/.config/cypress-devcontainer.yml
|
||||
docker-compose.yml
|
||||
./compose.yml
|
||||
.devcontainer/compose.yml
|
||||
!/.devcontainer/compose.yml
|
||||
|
||||
# misskey
|
||||
/build
|
||||
built
|
||||
built-test
|
||||
js-built
|
||||
src-js
|
||||
/data
|
||||
/.cache-loader
|
||||
/db
|
||||
/meili_data
|
||||
/elasticsearch
|
||||
npm-debug.log
|
||||
*.pem
|
||||
run.bat
|
||||
@@ -61,16 +38,6 @@ api-docs.json
|
||||
.DS_Store
|
||||
/files
|
||||
ormconfig.json
|
||||
temp
|
||||
/packages/frontend/src/**/*.stories.ts
|
||||
tsdoc-metadata.json
|
||||
misskey-assets
|
||||
|
||||
# Vite temporary files
|
||||
vite.config.js.timestamp-*
|
||||
vite.config.ts.timestamp-*
|
||||
vite.config.local-dev.js.timestamp-*
|
||||
vite.config.local-dev.ts.timestamp-*
|
||||
|
||||
# blender backups
|
||||
*.blend1
|
||||
@@ -78,6 +45,3 @@ vite.config.local-dev.ts.timestamp-*
|
||||
*.blend3
|
||||
*.blend4
|
||||
*.blend5
|
||||
|
||||
# VSCode addon
|
||||
.favorites.json
|
||||
|
||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -0,0 +1,3 @@
|
||||
[submodule "misskey-assets"]
|
||||
path = misskey-assets
|
||||
url = https://github.com/misskey-dev/assets.git
|
||||
|
||||
@@ -1 +1 @@
|
||||
22.15.0
|
||||
v16.15.0
|
||||
|
||||
3
.npmrc
3
.npmrc
@@ -1,3 +1,2 @@
|
||||
engine-strict = true
|
||||
save-exact = true
|
||||
shell-emulator = true
|
||||
package-lock = false
|
||||
|
||||
4
.vscode/extensions.json
vendored
4
.vscode/extensions.json
vendored
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"editorconfig.editorconfig",
|
||||
"eg2.vscode-npm-script",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"Vue.volar",
|
||||
"Orta.vscode-jest",
|
||||
"mrmlnc.vscode-json5"
|
||||
"Vue.vscode-typescript-vue-plugin"
|
||||
]
|
||||
}
|
||||
|
||||
20
.vscode/settings.json
vendored
20
.vscode/settings.json
vendored
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"search.exclude": {
|
||||
"**/node_modules": true
|
||||
},
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"typescript.enablePromptUseWorkspaceTsdk": true,
|
||||
"files.associations": {
|
||||
"*.test.ts": "typescript"
|
||||
},
|
||||
"jest.runMode": "on-demand",
|
||||
"jest.virtualFolders": [
|
||||
{ "name": "backend unit", "jestCommandLine": "pnpm -F backend run test" },
|
||||
{ "name": "backend e2e", "jestCommandLine": "pnpm -F backend run test:e2e"},
|
||||
{ "name": "misskey-js", "jestCommandLine": "pnpm -F misskey-js run jest" }
|
||||
],
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll": "explicit"
|
||||
},
|
||||
"editor.formatOnSave": false
|
||||
}
|
||||
139
AGENTS.md
139
AGENTS.md
@@ -1,139 +0,0 @@
|
||||
# Misskey – AI Agent Guide
|
||||
|
||||
このファイルは Misskey リポジトリで動く AI コーディングエージェント (Claude Code / OpenAI Codex / GitHub Copilot 等) が共通で参照する **最低限のルールと索引**。次の 3 経路から参照・読み込みされる:
|
||||
|
||||
- **Claude Code**: ルート `CLAUDE.md` から `@AGENTS.md` で取り込まれる
|
||||
- **OpenAI Codex**: ルート `AGENTS.md` を直接読み込む
|
||||
- **GitHub Copilot**: `.github/copilot-instructions.md` (本ファイルを参照しつつ、Copilot code review 向けに必須規約を再掲するファイル) 経由で参照する
|
||||
|
||||
人間 contributor 向けの一般規約 (Issue / PR の出し方、ActivityPub 拡張など) は [CONTRIBUTING.md](CONTRIBUTING.md) を参照。本ファイルは AI が **コードを書く・直す** 際に踏み外してはいけない事項に絞っている。
|
||||
|
||||
---
|
||||
|
||||
## 事故直結ルール (必ず守る)
|
||||
|
||||
違反すると CI 失敗または本番事故になる。順守すること。
|
||||
|
||||
### 1. SPDX ヘッダー必須
|
||||
|
||||
AGPL-3.0-only 管轄かつ SPDX CI 対象ディレクトリに新規 `.ts` / `.js` / `.cjs` / `.mjs` / `.vue` / `.scss` / `.html` ファイルを追加する場合、冒頭に以下を必ず付ける。欠落すると CI (`spdx` ジョブ) が失敗する。CI の対象判定は [.github/workflows/check-spdx-license-id.yml](.github/workflows/check-spdx-license-id.yml) の `directories` 配列を参照 (`*.config.{ts,js,cjs,mjs}` と `*eslint*` は除外)。
|
||||
|
||||
`packages/misskey-js` は MIT ライセンスのサブパッケージなので、この AGPL ヘッダーを一律に付けない。サブパッケージ固有の `package.json` / `LICENSE` / 既存ファイルのヘッダーに従う。
|
||||
|
||||
`.ts` / `.js` / `.cjs` / `.mjs` / `.scss`:
|
||||
|
||||
```text
|
||||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
```
|
||||
|
||||
`.vue` / `.html` (HTML コメント形式):
|
||||
|
||||
```text
|
||||
<!--
|
||||
SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
```
|
||||
|
||||
### 2. locales/*.yml は `ja-JP.yml` のみ編集可
|
||||
|
||||
`locales/` 配下の YAML は **`ja-JP.yml` のみ手動編集してよい**。他言語ファイル (`en-US.yml` 等) は Crowdin の自動配信先で、手動編集すると上書きで失われる。根拠: `locales/README.md` (ja-JP.yml 以外を手動編集しない運用) と `crowdin.yml` (`ja-JP.yml` → `locales/%locale%.yml` の同期設定)。
|
||||
|
||||
### 3. マージ済み migration を絶対に編集しない
|
||||
|
||||
`packages/backend/migration/{unixMs}-{PascalName}.js` のうち、既に `develop` / `master` にマージ済みのファイルは **絶対に変更しない**。本番環境で履歴改変が起きると深刻なデータ不整合を引き起こす。
|
||||
|
||||
スキーマ変更が必要な場合は **新しいタイムスタンプで新規ファイル** を作成する:
|
||||
|
||||
- ファイル名: `node -e "console.log(Date.now())"` で UNIX ms を取得し、`{ms}-<descriptive-name>.js` として置く。命名スタイルは既存履歴で混在しており (`1716129964060-ChannelIdDenormalizedForMiPoll.js` のような PascalCase、`1721666053703-fixDriveUrl.js` のような camelCase、`1672704136584-remove-latestStatus.js` のような kebab-case)、変更を表す単一の英語名であれば良い。クラス名側は PascalCase + 13 桁タイムスタンプ (`class FixDriveUrl1721666053703 { ... }`) を必ず守ること。
|
||||
- `up()` と `down()` の両方を必ず実装する (`down` は `up` の完全な巻き戻し)。
|
||||
- `pnpm --filter backend check-migrations` を通す。これは **TypeORM schema builder で pending DDL を検出する** 検査 ([packages/backend/scripts/check_migrations_clean.js](packages/backend/scripts/check_migrations_clean.js))。エンティティの `@Column` / `@Entity` 変更が migration に取り込まれていないとここで検出される。タイムスタンプの順序自体を直接検査するわけではない (順序が壊れた場合の失敗は別経路で出る)。
|
||||
|
||||
エンティティ差分から TypeORM CLI で自動生成したい / `CREATE INDEX CONCURRENTLY` 等のオプションを使いたい場合は [.claude/skills/create-migration/SKILL.md](.claude/skills/create-migration/SKILL.md) を参照。手書き / CLI どちらの方式でも上記 3 点 (履歴改変禁止 / `up`+`down` / `check-migrations`) が満たせれば良い。
|
||||
|
||||
---
|
||||
|
||||
## 必須コマンド
|
||||
|
||||
| 用途 | コマンド |
|
||||
| --- | --- |
|
||||
| 全体ビルド | `pnpm build` |
|
||||
| 開発サーバー (backend + frontend watch) | `pnpm dev` |
|
||||
| Lint (typecheck + eslint, 全パッケージ) | `pnpm lint` (= `pnpm --no-bail -r lint`。最初の失敗で止まらず全パッケージの結果を収集する) |
|
||||
| Backend unit test (Vitest) | `pnpm --filter backend test` |
|
||||
| Backend e2e test | `pnpm --filter backend test:e2e` |
|
||||
| Backend federation test | `pnpm --filter backend test:fed` |
|
||||
| Frontend test (Vitest) | `pnpm --filter frontend test` |
|
||||
| Cypress E2E (要 `start:test`) | `pnpm e2e` |
|
||||
| Storybook dev (frontend) | `pnpm --filter frontend storybook-dev` |
|
||||
| Migration 適用 | `pnpm migrate` |
|
||||
| Migration ロールバック | `pnpm revert` |
|
||||
| Migration の pending DDL 検査 (エンティティ差分の取り込み漏れ検出) | `pnpm --filter backend check-migrations` |
|
||||
| `misskey-js` 再生成 (API 変更後必須) | `pnpm build-misskey-js-with-types` |
|
||||
|
||||
> Backend の TypeScript 型チェックは `pnpm --filter backend typecheck` (tsgo)。
|
||||
> 個別ファイルへの ESLint --fix は `pnpm exec eslint --fix <path>`。
|
||||
> **backend テスト (`test` / `test:e2e` / `test:fed`) 実行前に `.config/test.yml` が必要** (未作成だとテスト自体が起動しない)。コピー手順と詳細は [.claude/docs/testing.md §Backend 全般の前提](.claude/docs/testing.md#backend-全般の前提-configtestyml) を参照。
|
||||
|
||||
---
|
||||
|
||||
## CHANGELOG
|
||||
|
||||
ユーザー影響のある変更 (機能追加・修正・改善) は `CHANGELOG.md` の冒頭 `## Unreleased` セクションに 1 行追加する。リファクタリング等の内部変更は不要。
|
||||
|
||||
### セクション構造
|
||||
|
||||
`## Unreleased` 配下に **3 つのサブセクション** が用意されている:
|
||||
|
||||
- `### General` — 共通 / 横断的な変更
|
||||
- `### Client` — `packages/frontend` 系
|
||||
- `### Server` — `packages/backend` 系
|
||||
|
||||
### エントリ書式
|
||||
|
||||
該当サブセクションに `- <Prefix>: <概要>` の形式で追加。Prefix は先頭大文字。
|
||||
|
||||
```text
|
||||
- Enhance: ノートの詳細表示での公開範囲の表示を改善
|
||||
- Fix: 通知が約10秒遅延する問題を修正
|
||||
- Feat: 新機能の追加
|
||||
```
|
||||
|
||||
### 触ってはいけない範囲
|
||||
|
||||
- `## Unreleased` **以外** のセクション (過去リリース) は変更しない。
|
||||
- `## Unreleased` の見出しと 3 つの空サブセクション骨格自体は維持する (リリーススクリプトが期待する構造)。
|
||||
|
||||
> 参考: コミットメッセージ側は `enhance(frontend): ...` / `fix(backend): ...` の小文字 + スコープ形式 ([CONTRIBUTING.md](CONTRIBUTING.md) 参照)。CHANGELOG とは書式が異なる点に注意。
|
||||
|
||||
---
|
||||
|
||||
## オンデマンド参照 (必要時に Read すること)
|
||||
|
||||
以下は AI が **作業対象に応じて必要なときだけ** 開く詳細ドキュメント。常時コンテキストには載せない。
|
||||
|
||||
| 何をしたい時 | 参照先 |
|
||||
| --- | --- |
|
||||
| パッケージ構成・依存関係を把握したい | [.claude/docs/architecture.md](.claude/docs/architecture.md) |
|
||||
| `packages/backend` を編集する (NestJS / TypeORM / migration / API endpoint) | [.claude/docs/backend.md](.claude/docs/backend.md) |
|
||||
| `packages/frontend` を編集する (Vue 3 / Mk* / i18n / SCSS module / `os.ts`) | [.claude/docs/frontend.md](.claude/docs/frontend.md) |
|
||||
| テストを書く・走らせる (Vitest / Cypress / Storybook) | [.claude/docs/testing.md](.claude/docs/testing.md) |
|
||||
| 有効化済 Claude Code プラグインの用途を確認 | [.claude/docs/plugins.md](.claude/docs/plugins.md) |
|
||||
|
||||
---
|
||||
|
||||
## ツール固有の補助ファイル
|
||||
|
||||
`.claude/` 配下は Claude Code 固有の skills / agents / slash commands を集約している (Codex / Copilot は読み飛ばしてよい):
|
||||
|
||||
- `.claude/skills/` — 繰り返しタスク用の skill 定義 (例: `add-api-endpoint`, `create-migration`)
|
||||
- `.claude/agents/` — 専門レビューエージェント (例: `misskey-api-reviewer`, `vue-component-reviewer`)
|
||||
- `.claude/commands/` — Claude Code のスラッシュコマンド (例: `/check-misskey-js`, `/changelog-add`)
|
||||
- `.claude/docs/` — オンデマンド参照ドキュメント (上記の表で示したもの。Codex / Copilot からも内容自体は読める)
|
||||
- `.claude/settings.json` — Claude Code の有効プラグイン (`enabledPlugins`) のみを記載した共有設定。hook は意図的に登録しない (各 contributor が `.claude/settings.local.json` で opt-in する方針)
|
||||
- `.claude/settings.local.json` — 個人ローカル設定 (`.gitignore` 済)
|
||||
|
||||
サードパーティ由来 (everything-claude-code 由来の MIT ライセンスファイル等) の出典は [.claude/THIRD_PARTY_LICENSES.md](.claude/THIRD_PARTY_LICENSES.md) を参照。
|
||||
2949
CHANGELOG.md
2949
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
@@ -1,7 +0,0 @@
|
||||
# Misskey – Claude Code Guide
|
||||
|
||||
ルール本体は [AGENTS.md](AGENTS.md) (Codex / Copilot と共有する単一ソース)。本ファイルは Claude Code 用の薄いラッパーで、`@AGENTS.md` 構文で本体規約をセッション開始時にコンテキストへ展開する。
|
||||
|
||||
Claude Code 固有の補助 (skills / agents / slash commands / docs) は `.claude/` 配下にコミット済。個人ローカル設定は `.claude/settings.local.json` に、MCP 認証情報は `.claude/.credentials.json` に置く (いずれも `.gitignore` 済)。
|
||||
|
||||
@AGENTS.md
|
||||
@@ -2,131 +2,45 @@
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, caste, color, religion, or sexual
|
||||
identity and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
Examples of behavior that contributes to creating a positive environment include:
|
||||
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the overall
|
||||
community
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or advances of
|
||||
any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or email address,
|
||||
without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
## Our Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official e-mail address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
<syuilotan@yahoo.co.jp>.
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at syuilotan@yahoo.co.jp. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series of
|
||||
actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or permanent
|
||||
ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within the
|
||||
community.
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.1, available at
|
||||
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
Community Impact Guidelines were inspired by
|
||||
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
|
||||
[https://www.contributor-covenant.org/translations][translations].
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
|
||||
[Mozilla CoC]: https://github.com/mozilla/diversity
|
||||
[FAQ]: https://www.contributor-covenant.org/faq
|
||||
[translations]: https://www.contributor-covenant.org/translations
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
||||
|
||||
455
CONTRIBUTING.md
455
CONTRIBUTING.md
@@ -1,7 +1,7 @@
|
||||
# Contribution guide
|
||||
We're glad you're interested in contributing Misskey! In this document you will find the information you need to contribute to the project.
|
||||
|
||||
> [!NOTE]
|
||||
> **Note**
|
||||
> This project uses Japanese as its major language, **but you do not need to translate and write the Issues/PRs in Japanese.**
|
||||
> Also, you might receive comments on your Issue/PR in Japanese, but you do not need to reply to them in Japanese as well.\
|
||||
> The accuracy of machine translation into Japanese is not high, so it will be easier for us to understand if you write it in the original language.
|
||||
@@ -15,33 +15,18 @@ Before creating an issue, please check the following:
|
||||
- To avoid duplication, please search for similar issues before creating a new issue.
|
||||
- Do not use Issues to ask questions or troubleshooting.
|
||||
- Issues should only be used to feature requests, suggestions, and bug tracking.
|
||||
- Please ask questions or troubleshooting in [GitHub Discussions](https://github.com/misskey-dev/misskey/discussions) or [Discord](https://discord.gg/Wp8gVStHW3).
|
||||
- Please ask questions or troubleshooting in the [Misskey Forum](https://forum.misskey.io/) or [Discord](https://discord.gg/Wp8gVStHW3).
|
||||
|
||||
> [!WARNING]
|
||||
> **Warning**
|
||||
> Do not close issues that are about to be resolved. It should remain open until a commit that actually resolves it is merged.
|
||||
|
||||
### Recommended discussing before implementation
|
||||
We welcome your proposal.
|
||||
|
||||
## Before implementation
|
||||
When you want to add a feature or fix a bug, **first have the design and policy reviewed in an Issue** (if it is not there, please make one). Without this step, there is a high possibility that the PR will not be merged even if it is implemented.
|
||||
|
||||
At this point, you also need to clarify the goals of the PR you will create, and make sure that the other members of the team are aware of them.
|
||||
PRs that do not have a clear set of do's and don'ts tend to be bloated and difficult to review.
|
||||
|
||||
Also, when you start implementation, assign yourself to the Issue (if you cannot do it yourself, ask Committer to assign you).
|
||||
By expressing your intention to work on the Issue, you can prevent conflicts in the work.
|
||||
|
||||
To the Committers: you should not assign someone on it before the Final Decision.
|
||||
|
||||
### How issues are triaged
|
||||
|
||||
The Committers may:
|
||||
* close an issue that is not reproducible on latest stable release,
|
||||
* merge an issue into another issue,
|
||||
* split an issue into multiple issues,
|
||||
* or re-open that has been closed for some reason which is not applicable anymore.
|
||||
|
||||
@syuilo reserves the Final Decision rights including whether the project will implement feature and how to implement, these rights are not always exercised.
|
||||
Also, when you start implementation, assign yourself to the Issue (if you cannot do it yourself, ask another member to assign you). By expressing your intention to work the Issue, you can prevent conflicts in the work.
|
||||
|
||||
## Well-known branches
|
||||
- **`master`** branch is tracking the latest release and used for production purposes.
|
||||
@@ -52,45 +37,25 @@ The Committers may:
|
||||
## Creating a PR
|
||||
Thank you for your PR! Before creating a PR, please check the following:
|
||||
- If possible, prefix the title with a keyword that identifies the type of this PR, as shown below.
|
||||
- `fix` / `refactor` / `feat` / `enhance` / `perf` / `chore` etc
|
||||
- Also, make sure that the granularity of this PR is appropriate. Please do not include more than one type of change or interest in a single PR.
|
||||
- `fix` / `refactor` / `feat` / `enhance` / `perf` / `chore` etc
|
||||
- Also, make sure that the granularity of this PR is appropriate. Please do not include more than one type of change or interest in a single PR.
|
||||
- If there is an Issue which will be resolved by this PR, please include a reference to the Issue in the text.
|
||||
- Please add the summary of the changes to [`CHANGELOG.md`](/CHANGELOG.md). However, this is not necessary for changes that do not affect the users, such as refactoring.
|
||||
- Check if there are any documents that need to be created or updated due to this change.
|
||||
- If you have added a feature or fixed a bug, please add a test case if possible.
|
||||
- Please make sure that tests and Lint are passed in advance.
|
||||
- You can run it with `pnpm test` and `pnpm lint`. [See more info](#testing)
|
||||
- You can run it with `npm run test` and `npm run lint`. [See more info](#testing)
|
||||
- If this PR includes UI changes, please attach a screenshot in the text.
|
||||
|
||||
Thanks for your cooperation 🤗
|
||||
|
||||
### Additional things for ActivityPub payload changes
|
||||
*This section is specific to misskey-dev implementation. Other fork or implementation may take different way. A significant difference is that non-"misskey-dev" extension is not described in the misskey-hub's document.*
|
||||
|
||||
If PR includes changes to ActivityPub payload, please reflect it in [misskey-hub's document](https://github.com/misskey-dev/misskey-hub-next/blob/master/content/ns.md) by sending PR.
|
||||
|
||||
The name of purporsed extension property (referred as "extended property" in later) to ActivityPub shall be prefixed by `_misskey_`. (i.e. `_misskey_quote`)
|
||||
|
||||
The extended property in `packages/backend/src/core/activitypub/type.ts` **must** be declared as optional because ActivityPub payloads that comes from older Misskey or other implementation may not contain it.
|
||||
|
||||
The extended property must be included in the context definition. Context is defined in `packages/backend/src/core/activitypub/misc/contexts.ts`.
|
||||
The key shall be same as the name of extended property, and the value shall be same as "short IRI".
|
||||
|
||||
"Short IRI" is defined in misskey-hub's document, but usually takes form of `misskey:<name of extended property>`. (i.e. `misskey:_misskey_quote`)
|
||||
|
||||
One should not add property that has defined before by other implementation, or add custom variant value to "well-known" property.
|
||||
|
||||
## Reviewers guide
|
||||
Be willing to comment on the good points and not just the things you want fixed 💯
|
||||
|
||||
読んでおくといいやつ
|
||||
- https://blog.lacolaco.net/posts/1e2cf439b3c2/
|
||||
- https://konifar-zatsu.hatenadiary.jp/entry/2024/11/05/192421
|
||||
|
||||
### Review perspective
|
||||
- Scope
|
||||
- Are the goals of the PR clear?
|
||||
- Is the granularity of the PR appropriate?
|
||||
- Are the goals of the PR clear?
|
||||
- Is the granularity of the PR appropriate?
|
||||
- Security
|
||||
- Does merging this PR create a vulnerability?
|
||||
- Performance
|
||||
@@ -101,22 +66,6 @@ Be willing to comment on the good points and not just the things you want fixed
|
||||
- Are there any omissions or gaps?
|
||||
- Does it check for anomalies?
|
||||
|
||||
## Security Advisory
|
||||
### For reporter
|
||||
Thank you for your reporting!
|
||||
|
||||
If you can also create a patch to fix the vulnerability, please create a PR on the private fork.
|
||||
|
||||
> [!note]
|
||||
> There is a GitHub bug that prevents merging if a PR not following the develop branch of upstream, so please keep follow the develop branch.
|
||||
|
||||
### For misskey-dev member
|
||||
修正PRがdevelopに追従されていないとマージできないので、マージできなかったら
|
||||
|
||||
> Could you merge or rebase onto upstream develop branch?
|
||||
|
||||
などと伝える。
|
||||
|
||||
## Deploy
|
||||
The `/deploy` command by issue comment can be used to deploy the contents of a PR to the preview environment.
|
||||
```
|
||||
@@ -128,125 +77,58 @@ An actual domain will be assigned so you can test the federation.
|
||||
|
||||
## Release
|
||||
### Release Instructions
|
||||
1. Commit version changes in the `develop` branch ([package.json](package.json))
|
||||
1. Commit version changes in the `develop` branch ([package.json](https://github.com/misskey-dev/misskey/blob/develop/package.json))
|
||||
2. Create a release PR.
|
||||
- Into `master` from `develop` branch.
|
||||
- The title must be in the format `Release: x.y.z`.
|
||||
- `x.y.z` is the new version you are trying to release.
|
||||
3. Deploy and perform a simple QA check. Also verify that the tests passed.
|
||||
4. Merge it. (Do not squash commit)
|
||||
4. Merge it.
|
||||
5. Create a [release of GitHub](https://github.com/misskey-dev/misskey/releases)
|
||||
- The target branch must be `master`
|
||||
- The tag name must be the version
|
||||
|
||||
> [!NOTE]
|
||||
> Why this instruction is necessary:
|
||||
> - To perform final QA checks
|
||||
> - To distribute responsibility
|
||||
> - To check direct commits to develop
|
||||
> - To celebrate the release together 🎉
|
||||
|
||||
## Localization (l10n)
|
||||
Misskey uses [Crowdin](https://crowdin.com/project/misskey) for localization management.
|
||||
You can improve our translations with your Crowdin account.
|
||||
Your changes in Crowdin are automatically submitted as a PR (with the title "New Crowdin translations") to the repository.
|
||||
The owner [@syuilo](https://github.com/syuilo) merges the PR into the develop branch before the next release.
|
||||
|
||||
If your language is not listed in Crowdin, please open an issue. We will add it to Crowdin.
|
||||
For newly added languages, once the translation progress per language exceeds 70%, it will be officially introduced into Misskey and made available to users.
|
||||
If your language is not listed in Crowdin, please open an issue.
|
||||
|
||||

|
||||
|
||||
## Development
|
||||
### Setup
|
||||
Before developing, you have to set up environment. Misskey requires Redis, PostgreSQL, and FFmpeg.
|
||||
|
||||
You would want to install Meilisearch to experiment related features. Technically, meilisearch is not strict requirement, but some features and tests require it.
|
||||
|
||||
There are a few ways to proceed.
|
||||
|
||||
#### Use system-wide software
|
||||
You could install them in system-wide (such as from package manager).
|
||||
|
||||
#### Use `docker compose`
|
||||
You could obtain middleware container by typing `docker compose -f $PROJECT_ROOT/compose.local-db.yml up -d`.
|
||||
|
||||
#### Use Devcontainer
|
||||
Devcontainer also has necessary setting. This method can be done by connecting from VSCode.
|
||||
|
||||
Instead of running `pnpm` locally, you can use Dev Container to set up your development environment.
|
||||
To use Dev Container, open the project directory on VSCode with Dev Containers installed.
|
||||
**Note:** If you are using Windows, please clone the repository with WSL. Using Git for Windows will result in broken files due to the difference in how newlines are handled.
|
||||
|
||||
It will run the following command automatically inside the container.
|
||||
``` bash
|
||||
git submodule update --init
|
||||
pnpm install --frozen-lockfile
|
||||
cp .devcontainer/devcontainer.yml .config/default.yml
|
||||
pnpm build
|
||||
pnpm migrate
|
||||
```
|
||||
|
||||
After finishing the migration, you can proceed.
|
||||
|
||||
### Start developing
|
||||
During development, it is useful to use the
|
||||
```
|
||||
pnpm dev
|
||||
```
|
||||
command.
|
||||
|
||||
- Server-side source files and automatically builds them if they are modified. Automatically start the server process(es).
|
||||
- Service Worker is watched by esbuild.
|
||||
- Vite HMR (just the `vite` command) is available. The behavior may be different from production.
|
||||
- Vite runs behind the backend (the backend will proxy Vite at /vite and /embed_vite except for websocket used for HMR).
|
||||
- You can see Misskey by accessing `http://localhost:3000` (Replace `3000` with the port configured with `port` in .config/default.yml).
|
||||
During development, it is useful to use the `npm run dev` command.
|
||||
This command monitors the server-side and client-side source files and automatically builds them if they are modified.
|
||||
In addition, it will also automatically start the Misskey server process.
|
||||
|
||||
## Testing
|
||||
You can run non-backend tests by executing following commands:
|
||||
```sh
|
||||
pnpm --filter frontend test
|
||||
pnpm --filter misskey-js test
|
||||
- Test codes are located in [`/test`](/test).
|
||||
|
||||
### Run test
|
||||
Create a config file.
|
||||
```
|
||||
cp test/test.yml .config/
|
||||
```
|
||||
Prepare DB/Redis for testing.
|
||||
```
|
||||
docker-compose -f test/docker-compose.yml up
|
||||
```
|
||||
Alternatively, prepare an empty (data can be erased) DB and edit `.config/test.yml`.
|
||||
|
||||
Run all test.
|
||||
```
|
||||
npm run test
|
||||
```
|
||||
|
||||
Backend tests require manual preparation of servers. See the next section for more on this.
|
||||
|
||||
### Backend
|
||||
There are three types of test codes for the backend:
|
||||
- Unit tests: [`/packages/backend/test/unit`](/packages/backend/test/unit)
|
||||
- Single-server E2E tests: [`/packages/backend/test/e2e`](/packages/backend/test/e2e)
|
||||
- Multiple-server E2E tests: [`/packages/backend/test-federation`](/packages/backend/test-federation)
|
||||
|
||||
#### Running Unit Tests or Single-server E2E Tests
|
||||
1. Create a config file:
|
||||
```sh
|
||||
cp .github/misskey/test.yml .config/
|
||||
#### Run specify test
|
||||
```
|
||||
npx cross-env TS_NODE_FILES=true TS_NODE_TRANSPILE_ONLY=true TS_NODE_PROJECT="./test/tsconfig.json" npx mocha test/foo.ts --require ts-node/register
|
||||
```
|
||||
|
||||
2. Start DB and Redis servers for testing:
|
||||
```sh
|
||||
docker compose -f packages/backend/test/compose.yml up
|
||||
```
|
||||
Instead, you can prepare an empty (data can be erased) DB and edit `.config/test.yml` appropriately.
|
||||
|
||||
3. Run all tests:
|
||||
```sh
|
||||
pnpm --filter backend test # unit tests
|
||||
pnpm --filter backend test:e2e # single-server E2E tests
|
||||
```
|
||||
If you want to run a specific test, run as a following command:
|
||||
```sh
|
||||
pnpm --filter backend test -- packages/backend/test/unit/activitypub.ts
|
||||
pnpm --filter backend test:e2e -- packages/backend/test/e2e/nodeinfo.ts
|
||||
```
|
||||
|
||||
#### Running Multiple-server E2E Tests
|
||||
See [`/packages/backend/test-federation/README.md`](/packages/backend/test-federation/README.md).
|
||||
|
||||
## Environment Variable
|
||||
|
||||
- `MISSKEY_CONFIG_YML`: Specify the file path of config.yml instead of default.yml (e.g. `2nd.yml`).
|
||||
- `MISSKEY_WEBFINGER_USE_HTTP`: If it's set true, WebFinger requests will be http instead of https, useful for testing federation between servers in localhost. NEVER USE IN PRODUCTION.
|
||||
### e2e tests
|
||||
TODO
|
||||
|
||||
## Continuous integration
|
||||
Misskey uses GitHub Actions for executing automated tests.
|
||||
@@ -258,12 +140,6 @@ Misskey uses Vue(v3) as its front-end framework.
|
||||
- **When creating a new component, please use the Composition API (with [setup sugar](https://v3.vuejs.org/api/sfc-script-setup.html) and [ref sugar](https://github.com/vuejs/rfcs/discussions/369)) instead of the Options API.**
|
||||
- Some of the existing components are implemented in the Options API, but it is an old implementation. Refactors that migrate those components to the Composition API are also welcome.
|
||||
|
||||
## Tabler Icons
|
||||
アイコンは、Production Build時に使用されていないものが削除されるようになっています。
|
||||
|
||||
**アイコンを動的に設定する際には、 `ti-${someVal}` のような、アイコン名のみを動的に変化させる実装を行わないでください。**
|
||||
必ず `ti-xxx` のような完全なクラス名を含めるようにしてください。
|
||||
|
||||
## nirax
|
||||
niraxは、Misskeyで使用しているオリジナルのフロントエンドルーティングシステムです。
|
||||
**vue-routerから影響を多大に受けているので、まずはvue-routerについて学ぶことをお勧めします。**
|
||||
@@ -271,7 +147,7 @@ niraxは、Misskeyで使用しているオリジナルのフロントエンド
|
||||
### ルート定義
|
||||
ルート定義は、以下の形式のオブジェクトの配列です。
|
||||
|
||||
```ts
|
||||
``` ts
|
||||
{
|
||||
name?: string;
|
||||
path: string;
|
||||
@@ -279,11 +155,12 @@ niraxは、Misskeyで使用しているオリジナルのフロントエンド
|
||||
query?: Record<string, string>;
|
||||
loginRequired?: boolean;
|
||||
hash?: string;
|
||||
globalCacheKey?: string;
|
||||
children?: RouteDef[];
|
||||
}
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> **Warning**
|
||||
> 現状、ルートは定義された順に評価されます。
|
||||
> たとえば、`/foo/:id`ルート定義の次に`/foo/bar`ルート定義がされていた場合、後者がマッチすることはありません。
|
||||
|
||||
@@ -291,204 +168,10 @@ niraxは、Misskeyで使用しているオリジナルのフロントエンド
|
||||
vue-routerとの最大の違いは、niraxは複数のルーターが存在することを許可している点です。
|
||||
これにより、アプリ内ウィンドウでブラウザとは個別にルーティングすることなどが可能になります。
|
||||
|
||||
## Storybook
|
||||
|
||||
Misskey uses [Storybook](https://storybook.js.org/) for UI development.
|
||||
|
||||
### Setup & Run
|
||||
|
||||
#### Setup
|
||||
|
||||
```bash
|
||||
pnpm --filter misskey-js build
|
||||
```
|
||||
|
||||
#### Run
|
||||
|
||||
```bash
|
||||
pnpm --filter frontend storybook-dev
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
When you create a new component (in this example, `MyComponent.vue`), the story file (`MyComponent.stories.ts`) will be automatically generated by the `.storybook/generate.js` script.
|
||||
You can override the default story by creating a impl story file (`MyComponent.stories.impl.ts`).
|
||||
|
||||
```ts
|
||||
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
||||
import { StoryObj } from '@storybook/vue3';
|
||||
import MyComponent from './MyComponent.vue';
|
||||
export const Default = {
|
||||
render(args) {
|
||||
return {
|
||||
components: {
|
||||
MyComponent,
|
||||
},
|
||||
setup() {
|
||||
return {
|
||||
args,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
props() {
|
||||
return {
|
||||
...this.args,
|
||||
};
|
||||
},
|
||||
},
|
||||
template: '<MyComponent v-bind="props" />',
|
||||
};
|
||||
},
|
||||
args: {
|
||||
foo: 'bar',
|
||||
},
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
},
|
||||
} satisfies StoryObj<typeof MyComponent>;
|
||||
```
|
||||
|
||||
If you want to opt-out from the automatic generation, create a `MyComponent.stories.impl.ts` file and add the following line to the file.
|
||||
|
||||
```ts
|
||||
import MyComponent from './MyComponent.vue';
|
||||
void MyComponent;
|
||||
```
|
||||
|
||||
You can override the component meta by creating a meta story file (`MyComponent.stories.meta.ts`).
|
||||
|
||||
```ts
|
||||
export const argTypes = {
|
||||
scale: {
|
||||
control: {
|
||||
type: 'range',
|
||||
min: 1,
|
||||
max: 4,
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
Also, you can use msw to mock API requests in the storybook. Creating a `MyComponent.stories.msw.ts` file to define the mock handlers.
|
||||
|
||||
```ts
|
||||
import { HttpResponse, http } from 'msw';
|
||||
export const handlers = [
|
||||
http.post('/api/notes/timeline', ({ request }) => {
|
||||
return HttpResponse.json([]);
|
||||
}),
|
||||
];
|
||||
```
|
||||
|
||||
Don't forget to re-run the `.storybook/generate.js` script after adding, editing, or removing the above files.
|
||||
|
||||
## Nest
|
||||
|
||||
### Nest Service Circular dependency / Nestでサービスの循環参照でエラーが起きた場合
|
||||
|
||||
#### forwardRef
|
||||
まずは簡単に`forwardRef`を試してみる
|
||||
|
||||
```typescript
|
||||
export class FooService {
|
||||
constructor(
|
||||
@Inject(forwardRef(() => BarService))
|
||||
private barService: BarService
|
||||
) {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### OnModuleInit
|
||||
できなければ`OnModuleInit`を使う
|
||||
|
||||
```typescript
|
||||
import { Injectable, OnModuleInit } from '@nestjs/common';
|
||||
import { ModuleRef } from '@nestjs/core';
|
||||
import { BarService } from '@/core/BarService';
|
||||
|
||||
@Injectable()
|
||||
export class FooService implements OnModuleInit {
|
||||
private barService: BarService // constructorから移動してくる
|
||||
|
||||
constructor(
|
||||
private moduleRef: ModuleRef,
|
||||
) {
|
||||
}
|
||||
|
||||
async onModuleInit() {
|
||||
this.barService = this.moduleRef.get(BarService.name);
|
||||
}
|
||||
|
||||
public async niceMethod() {
|
||||
return await this.barService.incredibleMethod({ hoge: 'fuga' });
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
##### Service Unit Test
|
||||
テストで`onModuleInit`を呼び出す必要がある
|
||||
|
||||
```typescript
|
||||
// import ...
|
||||
|
||||
describe('test', () => {
|
||||
let app: TestingModule;
|
||||
let fooService: FooService; // for test case
|
||||
let barService: BarService; // for test case
|
||||
|
||||
beforeEach(async () => {
|
||||
app = await Test.createTestingModule({
|
||||
imports: ...,
|
||||
providers: [
|
||||
FooService,
|
||||
{ // mockする (mockは必須ではないかもしれない)
|
||||
provide: BarService,
|
||||
useFactory: () => ({
|
||||
incredibleMethod: jest.fn(),
|
||||
}),
|
||||
},
|
||||
{ // Provideにする
|
||||
provide: BarService.name,
|
||||
useExisting: BarService,
|
||||
},
|
||||
],
|
||||
})
|
||||
.useMocker(...
|
||||
.compile();
|
||||
|
||||
fooService = app.get<FooService>(FooService);
|
||||
barService = app.get<BarService>(BarService) as jest.Mocked<BarService>;
|
||||
|
||||
// onModuleInitを実行する
|
||||
await fooService.onModuleInit();
|
||||
});
|
||||
|
||||
test('nice', () => {
|
||||
await fooService.niceMethod();
|
||||
|
||||
expect(barService.incredibleMethod).toHaveBeenCalled();
|
||||
expect(barService.incredibleMethod.mock.lastCall![0])
|
||||
.toEqual({ hoge: 'fuga' });
|
||||
});
|
||||
})
|
||||
```
|
||||
|
||||
## Notes
|
||||
### How to resolve conflictions occurred at yarn.lock?
|
||||
|
||||
### Misskeyのドメイン固有の概念は`Mi`をprefixする
|
||||
例えばGoogleが自社サービスをMap、Earth、DriveではなくGoogle Map、Google Earth、Google Driveのように命名するのと同じ
|
||||
コード上でMisskeyのドメイン固有の概念には`Mi`をprefixすることで、他のドメインの同様の概念と区別できるほか、名前の衝突を防ぐ。
|
||||
ただし、文脈上Misskeyのものを指すことが明らかであり、名前の衝突の恐れがない場合は、一時的なローカル変数に限って`Mi`を省略してもよい。
|
||||
|
||||
### Misskey.jsの型生成
|
||||
```bash
|
||||
pnpm build-misskey-js-with-types
|
||||
```
|
||||
|
||||
### How to resolve conflictions occurred at pnpm-lock.yaml?
|
||||
|
||||
Just execute `pnpm` to fix it.
|
||||
Just execute `yarn` to fix it.
|
||||
|
||||
### INSERTするときにはsaveではなくinsertを使用する
|
||||
#6441
|
||||
@@ -567,20 +250,18 @@ SQLでは配列のインデックスは**1始まり**。
|
||||
### null IN
|
||||
nullが含まれる可能性のあるカラムにINするときは、そのままだとおかしくなるのでORなどでnullのハンドリングをしよう。
|
||||
|
||||
### enumの削除は気をつける
|
||||
enumの列挙の内容の削除は、その値をもつレコードを全て削除しないといけない
|
||||
|
||||
削除が重たかったり不可能だったりする場合は、削除しないでおく
|
||||
### `undefined`にご用心
|
||||
MongoDBの時とは違い、findOneでレコードを取得する時に対象レコードが存在しない場合 **`undefined`** が返ってくるので注意。
|
||||
MongoDBは`null`で返してきてたので、その感覚で`if (x === null)`とか書くとバグる。代わりに`if (x == null)`と書いてください
|
||||
|
||||
### Migration作成方法
|
||||
packages/backendで:
|
||||
```sh
|
||||
pnpm dlx typeorm migration:generate -d ormconfig.js -o --esm <migration name>
|
||||
npx typeorm migration:generate -d ormconfig.js -o <migration name>
|
||||
```
|
||||
|
||||
- 生成後、ファイルをmigration下に移してください
|
||||
- 作成されたスクリプトは不必要な変更を含むため除去してください
|
||||
- `-o` (`--outputJs`) で JS 形式、`--esm` で ESM 形式に生成する。Misskey の既存 migration はすべて ESM JS なので両方のオプションが必要
|
||||
|
||||
### コネクションには`markRaw`せよ
|
||||
**Vueのコンポーネントのdataオプションとして**misskey.jsのコネクションを設定するとき、必ず`markRaw`でラップしてください。インスタンスが不必要にリアクティブ化されることで、misskey.js内の処理で不具合が発生するとともに、パフォーマンス上の問題にも繋がる。なお、Composition APIを使う場合はこの限りではない(リアクティブ化はマニュアルなため)。
|
||||
@@ -595,47 +276,3 @@ marginはそのコンポーネントを使う側が設定する
|
||||
## その他
|
||||
### HTMLのクラス名で follow という単語は使わない
|
||||
広告ブロッカーで誤ってブロックされる
|
||||
|
||||
### indexというファイル名を使うな
|
||||
ESMではディレクトリインポートは廃止されているのと、ディレクトリインポートせずともファイル名が index だと何故か一部のライブラリ?でディレクトリインポートだと見做されてエラーになる
|
||||
|
||||
## CSS Recipe
|
||||
|
||||
### Lighten CSS vars
|
||||
|
||||
``` css
|
||||
color: hsl(from var(--MI_THEME-accent) h s calc(l + 10));
|
||||
```
|
||||
|
||||
### Darken CSS vars
|
||||
|
||||
``` css
|
||||
color: hsl(from var(--MI_THEME-accent) h s calc(l - 10));
|
||||
```
|
||||
|
||||
### Add alpha to CSS vars
|
||||
|
||||
``` css
|
||||
color: color(from var(--MI_THEME-accent) srgb r g b / 0.5);
|
||||
```
|
||||
|
||||
## 考え方
|
||||
### DRYに囚われるな
|
||||
必要なのは一般化ではなく抽象化と考えます。
|
||||
盲信せず、誤った・不必要な共通化は避け、それが自然だと感じる場合は重複させる勇気を持ちましょう。
|
||||
|
||||
### Misskeyを複雑にしない実装
|
||||
それがいくら複雑であっても、Misskey固有のコンテキストと関心が分離されている(もしくは事実上分離されていると見做すことができる)実装であれば、それはMisskeyのコードベースに対する複雑性に影響を与えないと考えます。
|
||||
|
||||
例えるなら、VueやAiScriptといったMisskeyが使用しているライブラリの内部実装がいくら複雑だったとしても、「それを使用しているからMisskeyの実装は複雑である」ということにはならないのと同じです。
|
||||
|
||||
Misskeyのドメイン知識から関心が分離されているということは、Misskeyの実装について考える時にそれらの内部実装を考慮する必要が無く、認知負荷を増やさないからです。
|
||||
|
||||
また重要な点は、その実装が、Misskeyリポジトリの外部にあるか・内部にあるかということや、Misskeyがメンテナンスするものか・第三者がメンテナンスするものかといったことは複雑性を考える上ではほとんど無視できるという点です。
|
||||
|
||||
もちろんその実装がMisskeyリポジトリにあり、Misskeyがメンテナンスしなければならないものは、保守のコストはかかります。
|
||||
しかし、Misskeyの本質的な設計・実装という観点で見たときは、その実装は実質的に外部ライブラリのように振る舞います。
|
||||
換言すれば「たまたまMisskeyの開発者と同じ人たちがメンテナンスしているし、たまたまMisskeyのリポジトリ内に置いてあるだけの外部ライブラリ」です。
|
||||
|
||||
そのため、実装をなるべくMisskeyのドメイン知識から独立したものにすれば、Misskeyのコードベースの複雑性を上げることなく機能実装を行うことができ、お得であると言えます。
|
||||
もちろんそれにこだわって、些細な実装でもそのように分離してしまうとかえって認知負荷が増えたり、実装量が増えてメリットをデメリットが上回る場合もあるので、ケースバイケースではあります。
|
||||
|
||||
9
COPYING
9
COPYING
@@ -1,8 +1,15 @@
|
||||
Unless otherwise stated this repository is
|
||||
Copyright © 2014-2026 syuilo and contributors
|
||||
Copyright © 2014-2022 syuilo and contributers
|
||||
|
||||
And is distributed under The GNU Affero General Public License Version 3, you should have received a copy of the license file as LICENSE.
|
||||
|
||||
|
||||
Misskey includes several third-party Open-Source softwares.
|
||||
|
||||
Emoji keywords for Unicode 11 and below by Mu-An Chiou
|
||||
License: MIT
|
||||
https://github.com/muan/emojilib/blob/master/LICENSE
|
||||
|
||||
RsaSignature2017 implementation by Transmute Industries Inc
|
||||
License: MIT
|
||||
https://github.com/transmute-industries/RsaSignature2017/blob/master/LICENSE
|
||||
|
||||
116
Dockerfile
116
Dockerfile
@@ -1,112 +1,32 @@
|
||||
# syntax = docker/dockerfile:1.23
|
||||
|
||||
ARG NODE_VERSION=22.22.2-bookworm
|
||||
|
||||
# build assets & compile TypeScript
|
||||
|
||||
FROM --platform=$BUILDPLATFORM node:${NODE_VERSION} AS native-builder
|
||||
|
||||
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
--mount=type=cache,target=/var/lib/apt,sharing=locked \
|
||||
rm -f /etc/apt/apt.conf.d/docker-clean \
|
||||
; echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache \
|
||||
&& apt-get update \
|
||||
&& apt-get install -yqq --no-install-recommends \
|
||||
build-essential
|
||||
|
||||
WORKDIR /misskey
|
||||
|
||||
COPY --link ["pnpm-lock.yaml", "pnpm-workspace.yaml", "package.json", "./"]
|
||||
COPY --link ["scripts", "./scripts"]
|
||||
COPY --link ["patches", "./patches"]
|
||||
COPY --link ["packages/backend/package.json", "./packages/backend/"]
|
||||
COPY --link ["packages/frontend-shared/package.json", "./packages/frontend-shared/"]
|
||||
COPY --link ["packages/frontend/package.json", "./packages/frontend/"]
|
||||
COPY --link ["packages/frontend-embed/package.json", "./packages/frontend-embed/"]
|
||||
COPY --link ["packages/frontend-builder/package.json", "./packages/frontend-builder/"]
|
||||
COPY --link ["packages/i18n/package.json", "./packages/i18n/"]
|
||||
COPY --link ["packages/icons-subsetter/package.json", "./packages/icons-subsetter/"]
|
||||
COPY --link ["packages/sw/package.json", "./packages/sw/"]
|
||||
COPY --link ["packages/misskey-js/package.json", "./packages/misskey-js/"]
|
||||
COPY --link ["packages/misskey-reversi/package.json", "./packages/misskey-reversi/"]
|
||||
COPY --link ["packages/misskey-bubble-game/package.json", "./packages/misskey-bubble-game/"]
|
||||
FROM node:16.15.1-bullseye AS builder
|
||||
|
||||
ARG NODE_ENV=production
|
||||
|
||||
RUN node -e "console.log(JSON.parse(require('node:fs').readFileSync('./package.json')).packageManager)" | xargs npm install -g
|
||||
WORKDIR /misskey
|
||||
|
||||
RUN --mount=type=cache,target=/root/.local/share/pnpm/store,sharing=locked \
|
||||
pnpm i --frozen-lockfile --aggregate-output
|
||||
|
||||
COPY --link . ./
|
||||
COPY . ./
|
||||
|
||||
RUN apt-get update
|
||||
RUN apt-get install -y build-essential
|
||||
RUN git submodule update --init
|
||||
RUN pnpm build
|
||||
RUN rm -rf .git/
|
||||
RUN yarn install
|
||||
RUN yarn build
|
||||
RUN rm -rf .git
|
||||
|
||||
# build native dependencies for target platform
|
||||
|
||||
FROM --platform=$TARGETPLATFORM node:${NODE_VERSION} AS target-builder
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -yqq --no-install-recommends \
|
||||
build-essential
|
||||
FROM node:16.15.1-bullseye-slim AS runner
|
||||
|
||||
WORKDIR /misskey
|
||||
|
||||
COPY --link ["pnpm-lock.yaml", "pnpm-workspace.yaml", "package.json", "./"]
|
||||
COPY --link ["scripts", "./scripts"]
|
||||
COPY --link ["patches", "./patches"]
|
||||
COPY --link ["packages/backend/package.json", "./packages/backend/"]
|
||||
COPY --link ["packages/misskey-js/package.json", "./packages/misskey-js/"]
|
||||
COPY --link ["packages/misskey-reversi/package.json", "./packages/misskey-reversi/"]
|
||||
COPY --link ["packages/misskey-bubble-game/package.json", "./packages/misskey-bubble-game/"]
|
||||
RUN apt-get update
|
||||
RUN apt-get install -y ffmpeg tini
|
||||
|
||||
ARG NODE_ENV=production
|
||||
COPY --from=builder /misskey/node_modules ./node_modules
|
||||
COPY --from=builder /misskey/built ./built
|
||||
COPY --from=builder /misskey/packages/backend/node_modules ./packages/backend/node_modules
|
||||
COPY --from=builder /misskey/packages/backend/built ./packages/backend/built
|
||||
COPY --from=builder /misskey/packages/client/node_modules ./packages/client/node_modules
|
||||
COPY . ./
|
||||
|
||||
RUN node -e "console.log(JSON.parse(require('node:fs').readFileSync('./package.json')).packageManager)" | xargs npm install -g
|
||||
|
||||
RUN --mount=type=cache,target=/root/.local/share/pnpm/store,sharing=locked \
|
||||
pnpm i --frozen-lockfile --aggregate-output
|
||||
|
||||
FROM --platform=$TARGETPLATFORM node:${NODE_VERSION}-slim AS runner
|
||||
|
||||
ARG UID="991"
|
||||
ARG GID="991"
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
ffmpeg tini curl libjemalloc-dev libjemalloc2 \
|
||||
&& ln -s /usr/lib/$(uname -m)-linux-gnu/libjemalloc.so.2 /usr/local/lib/libjemalloc.so \
|
||||
&& groupadd -g "${GID}" misskey \
|
||||
&& useradd -l -u "${UID}" -g "${GID}" -m -d /misskey misskey \
|
||||
&& find / -type d -path /sys -prune -o -type d -path /proc -prune -o -type f -perm /u+s -ignore_readdir_race -exec chmod u-s {} \; \
|
||||
&& find / -type d -path /sys -prune -o -type d -path /proc -prune -o -type f -perm /g+s -ignore_readdir_race -exec chmod g-s {} \; \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists
|
||||
|
||||
# add package.json to add pnpm
|
||||
COPY ./package.json ./package.json
|
||||
RUN node -e "console.log(JSON.parse(require('node:fs').readFileSync('./package.json')).packageManager)" | xargs npm install -g
|
||||
|
||||
USER misskey
|
||||
WORKDIR /misskey
|
||||
|
||||
COPY --chown=misskey:misskey --from=target-builder /misskey/node_modules ./node_modules
|
||||
COPY --chown=misskey:misskey --from=target-builder /misskey/packages/backend/node_modules ./packages/backend/node_modules
|
||||
COPY --chown=misskey:misskey --from=target-builder /misskey/packages/misskey-js/node_modules ./packages/misskey-js/node_modules
|
||||
COPY --chown=misskey:misskey --from=target-builder /misskey/packages/misskey-reversi/node_modules ./packages/misskey-reversi/node_modules
|
||||
COPY --chown=misskey:misskey --from=target-builder /misskey/packages/misskey-bubble-game/node_modules ./packages/misskey-bubble-game/node_modules
|
||||
COPY --chown=misskey:misskey --from=native-builder /misskey/built ./built
|
||||
COPY --chown=misskey:misskey --from=native-builder /misskey/packages/misskey-js/built ./packages/misskey-js/built
|
||||
COPY --chown=misskey:misskey --from=native-builder /misskey/packages/misskey-reversi/built ./packages/misskey-reversi/built
|
||||
COPY --chown=misskey:misskey --from=native-builder /misskey/packages/misskey-bubble-game/built ./packages/misskey-bubble-game/built
|
||||
COPY --chown=misskey:misskey --from=native-builder /misskey/packages/backend/built ./packages/backend/built
|
||||
COPY --chown=misskey:misskey --from=native-builder /misskey/packages/i18n/built ./packages/i18n/built
|
||||
COPY --chown=misskey:misskey . ./
|
||||
|
||||
ENV LD_PRELOAD=/usr/local/lib/libjemalloc.so
|
||||
ENV NODE_ENV=production
|
||||
HEALTHCHECK --interval=5s --retries=20 CMD ["/bin/bash", "/misskey/healthcheck.sh"]
|
||||
ENTRYPOINT ["/usr/bin/tini", "--"]
|
||||
CMD ["pnpm", "run", "migrateandstart"]
|
||||
CMD ["npm", "run", "migrateandstart"]
|
||||
|
||||
76
README.md
76
README.md
@@ -1,18 +1,16 @@
|
||||
<div align="center">
|
||||
<a href="https://misskey-hub.net">
|
||||
<img src="./assets/title_float.svg" alt="Misskey logo" style="border-radius:50%" width="300"/>
|
||||
<img src="./assets/title_float.svg" alt="Misskey logo" style="border-radius:50%" width="400"/>
|
||||
</a>
|
||||
|
||||
**🌎 **Misskey** is an open source, federated social media platform that's free forever! 🚀**
|
||||
|
||||
[Learn more](https://misskey-hub.net/)
|
||||
|
||||
|
||||
**🌎 **[Misskey](https://misskey-hub.net/)** is an open source, decentralized social media platform that's free forever! 🚀**
|
||||
|
||||
---
|
||||
|
||||
<a href="https://misskey-hub.net/servers/">
|
||||
<a href="https://misskey-hub.net/instances.html">
|
||||
<img src="https://custom-icon-badges.herokuapp.com/badge/find_an-instance-acea31?logoColor=acea31&style=for-the-badge&logo=misskey&labelColor=363B40" alt="find an instance"/></a>
|
||||
|
||||
<a href="https://misskey-hub.net/docs/for-admin/install/guides/">
|
||||
<a href="https://misskey-hub.net/docs/install.html">
|
||||
<img src="https://custom-icon-badges.herokuapp.com/badge/create_an-instance-FBD53C?logoColor=FBD53C&style=for-the-badge&logo=server&labelColor=363B40" alt="create an instance"/></a>
|
||||
|
||||
<a href="./CONTRIBUTING.md">
|
||||
@@ -23,41 +21,37 @@
|
||||
|
||||
<a href="https://www.patreon.com/syuilo">
|
||||
<img src="https://custom-icon-badges.herokuapp.com/badge/become_a-patron-F96854?logoColor=F96854&style=for-the-badge&logo=patreon&labelColor=363B40" alt="become a patron"/></a>
|
||||
|
||||
[](https://deepwiki.com/misskey-dev/misskey)
|
||||
|
||||
<a href="https://flatt.tech/oss/gmo/trampoline" target="_blank"><img src="https://flatt.tech/assets/images/badges/gmo-oss.svg" height="24px"/></a>
|
||||
|
||||
</div>
|
||||
|
||||
## Thanks
|
||||
|
||||
<a href="https://sentry.io/"><img src="https://github.com/misskey-dev/misskey/assets/4439005/98576556-222f-467a-94be-e98dbda1d852" height="30" alt="Sentry" /></a>
|
||||
|
||||
Thanks to [Sentry](https://sentry.io/) for providing the error tracking platform that helps us catch unexpected errors.
|
||||
|
||||
<a href="https://www.chromatic.com/"><img src="https://user-images.githubusercontent.com/321738/84662277-e3db4f80-af1b-11ea-88f5-91d67a5e59f6.png" height="30" alt="Chromatic" /></a>
|
||||
|
||||
Thanks to [Chromatic](https://www.chromatic.com/) for providing the visual testing platform that helps us review UI changes and catch visual regressions.
|
||||
|
||||
<a href="https://about.codecov.io/for/open-source/"><img src="https://about.codecov.io/wp-content/themes/codecov/assets/brand/sentry-cobranding/logos/codecov-by-sentry-logo.svg" height="30" alt="Codecov" /></a>
|
||||
|
||||
Thanks to [Codecov](https://about.codecov.io/for/open-source/) for providing the code coverage platform that helps us improve our test coverage.
|
||||
|
||||
<a href="https://crowdin.com/"><img src="https://user-images.githubusercontent.com/20679825/230709597-1299a011-171a-4294-a91e-355a9b37c672.svg" height="30" alt="Crowdin" /></a>
|
||||
|
||||
Thanks to [Crowdin](https://crowdin.com/) for providing the localization platform that helps us translate Misskey into many languages.
|
||||
|
||||
<a href="https://hub.docker.com/"><img src="https://user-images.githubusercontent.com/20679825/230148221-f8e73a32-a49b-47c3-9029-9a15c3824f92.png" height="30" alt="Docker" /></a>
|
||||
|
||||
Thanks to [Docker](https://hub.docker.com/) for providing the container platform that helps us run Misskey in production.
|
||||
|
||||
|
||||
---
|
||||
|
||||
<div align="center">
|
||||
|
||||
Support us with a ⭐ !
|
||||
</div>
|
||||
|
||||
[](https://star-history.com/#misskey-dev/misskey&Date)
|
||||
<div>
|
||||
|
||||
<a href="https://xn--931a.moe/"><img src="https://github.com/misskey-dev/misskey/blob/develop/assets/ai.png?raw=true" align="right" height="320px"/></a>
|
||||
|
||||
## ✨ Features
|
||||
- **ActivityPub support**\
|
||||
Not on Misskey? No problem! Not only can Misskey instances talk to each other, but you can make friends with people on other networks like Mastodon and Pixelfed!
|
||||
- **Reactions**\
|
||||
You can add emoji reactions to any post! No longer are you bound by a like button, show everyone exactly how you feel with the tap of a button.
|
||||
- **Drive**\
|
||||
With Misskey's built in drive, you get cloud storage right in your social media, where you can upload any files, make folders, and find media from posts you've made!
|
||||
- **Rich Web UI**\
|
||||
Misskey has a rich and easy to use Web UI!
|
||||
It is highly customizable, from changing the layout and adding widgets to making custom themes.
|
||||
Furthermore, plugins can be created using AiScript, an original programming language.
|
||||
- And much more...
|
||||
|
||||
</div>
|
||||
|
||||
<div style="clear: both;"></div>
|
||||
|
||||
## Documentation
|
||||
|
||||
Misskey Documentation can be found at [Misskey Hub](https://misskey-hub.net/), some of the links and graphics above also lead to specific portions of it.
|
||||
|
||||
## Sponsors
|
||||
<div align="center">
|
||||
<a class="rss3" title="RSS3" href="https://rss3.io/" target="_blank"><img src="https://rss3.mypinata.cloud/ipfs/QmUG6H3Z7D5P511shn7sB4CPmpjH5uZWu4m5mWX7U3Gqbu" alt="RSS3" height="60"></a>
|
||||
</div>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user