OreOreBot2 への貢献を検討していただきありがとうございます。
バグ報告や機能追加の提案、ドキュメントの改善など、様々な貢献をお待ちしています。
OreOreBot2 では以下のような Issue を提出することができます。
これらの Issue はテンプレートが用意されており、それぞれの目的に応じた内容を記述することで、簡単に Issue を提出できます。
テンプレートを使用せず、空の Issue を使用して提出することも可能です。ただしその場合はしっかり内容を記述してください。
自分で開発したり修正した機能・不具合を Pull Request として提出することも可能です。
- OreOreBot2 のリポジトリをフォークする
リポジトリ画面の右上にある "Fork" から自分のアカウントにクローンしてください。
Note
approversのメンバーはフォークする必要はありません。
- ローカルにクローンする
次のコマンドを実行してリポジトリをローカルにクローンしてください。
git clone https://github.com/approvers/OreOreBot2.git
- 依存関係をインストールする
次のコマンドを実行して依存関係をインストールしてください。
このコマンドを実行すると共通のパッケージ・@oreorebot2/bot
(はらちょ本体)・@oreorebot2/docs
(はらちょのドキュメント)、それぞれの依存関係がインストールされます。
必ず、ルートディレクトリ上で実行してください。
bun install
- ブランチを作成、チェックアウトする
ブランチ名には特に規則はありませんが、内容が逸脱しすぎているブランチ名ではプッシュしないでください。
git checkout -b <branch-name>
- 開発を行い、その内容を GitHub にプッシュする
git add <file-name>
git commit -m <commit-message>
git push
- 開発が完了したら GitHub の OreOreBot2 レポジトリ (フォーク元でもフォーク先でも可) にアクセスし、 当リポジトリの main ブランチへのプルリクエストを作成してください。 当リポジトリのメンテナーによるレビューと CI によるテストが行われ、両方に合格すればマージできます。
OreOreBot2 は以下のような構成になっています。
OreOreBot2 (@oreorebot2/common)
│
├── packages
│ │
│ ├── bot (@oreorebot2/bot) // OreOreBot2 本体
│ │
│ └── docs (@oreorebot2/docs) // OreOreBot2 のドキュメント
- ルートディレクトリ (
@oreorebot2/common
) 上は@oreorebot2/bot
・@oreorebot2/docs
で使用される依存関係やコンフィグファイルが管理されています。- このディレクトリ上で
bun install
を実行すると、@oreorebot2/common
・@oreorebot2/bot
・@oreorebot2/docs
の依存関係がインストールされます。
- このディレクトリ上で
- ルートディレクトリ (
@oreorebot2/common
) 上から@oreorebot2/bot
・@oreorebot2/docs
のスクリプトにアクセスすることが可能です。 - 依存関係をインストールする必要がある場合はインストール先に注意してください。それぞれパッケージの依存関係はそれぞれのディレクトリ上でインストールする必要があります。
- 2つのパッケージ (
@oreorebot2/bot
・@oreorebot2/docs
) に共通するような依存関係は@oreorebot2/common
上でインストールしてください。 - それぞれのパッケージのみが依存するような依存関係はそれぞれのディレクトリ上でインストールしてください。
- 2つのパッケージ (
コミットメッセージを書く際は Conventional Commit に従ってください。
Conventional Commits の仕様はコミットメッセージのための軽量の規約です。 明示的なコミット履歴を作成するための簡単なルールを提供します。この規則に従うことで自動化ツールの導入を簡単にします。 コミットメッセージで機能追加・修正・破壊的変更などを説明することで、この規約は SemVer と協調動作します。
コミットメッセージは次のような形にする必要があります。
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
<type>
は、OreOreBot2 を使用する利用者や開発者に意図を伝えるために以下に記載するそれぞれの型を指定する必要があります。
型 | 要素 |
---|---|
fix |
この型を持つコミットはコードベースのバグにパッチを当てます。 |
feat |
この型を持つコミットはコードベースに新しい機能を追加します。 |
build |
この型を持つコミットはプログラムをコンパイル、ビルドする部分の変更を行います。 |
ci |
この型を持つコミットは GitHub Actions に関する変更を行います。 |
docs |
この型を持つコミットはドキュメントなどの変更を行います。 |
refactor |
この型を持つコミットはコードベースのリファクタリングを行います。 |
chore |
この型を持つコミットはファイル整理や依存関係の更新などを行います。 |
BREAKING CHANGE
とフッターにかかれているか型/スコープの直後に !
が追加されているコミットは仕様の破壊的変更を意味します。 (Semantic Versioning における MAJOR
に相当します)
また、 BREAKING CHANGE
は任意の型のコミットに含めることも可能です。
詳しくは Conventional Commits を参照してください。
プロジェクトの構成 にあるように OreOreBot2 は @oreorebot2/bot
・@oreorebot2/docs
という2つのパッケージで構成されています。
それぞれのパッケージにはそれぞれの開発環境が用意されていますが、スクリプトを実行する場合はそれぞれのパッケージのディレクトリに移動する必要はありません。
以下は使用可能なスクリプトのリストです。
start
: ビルドした成果物で OreOreBot2 を起動します。build:bot
:@oreorebot2/bot
をビルドします。build:docs
:@oreorebot2/docs
をビルドします。dev:bot
:@oreorebot2/bot
を開発環境で起動します。コンパイルは実施しません。dev:docs
:@oreorebot2/docs
を開発サーバーで起動します。lint:bot
,lint:docs
:@oreorebot2/bot
・@oreorebot2/docs
のコードに対して ESLint を実行します。format:bot
,format:docs
:@oreorebot2/bot
・@oreorebot2/docs
のコードに対して Prettier を実行します。test
:@oreorebot2/bot
のテストを実行します。coverage
:@oreorebot2/bot
のカバレッジを計測します。
以下のものをインストールしていることを想定しています。
- Git
- FFmpeg (音楽再生系の機能で必要です)
- bun v1
- 型、クラスの命名には
PascalCase
を使用してください。 - 関数、変数の命名には
camelCase
を使用してください。 null
は使用せず、undefined
を使用してください。- 文字列はシングルクォーテーションで囲ってください。
- ファイル名を小文字英字とハイフンのみの
kabeb-case
としてください。 - コミット時に必ず Husky で Prettier と ESLint を実行してください。
- 新機能の追加や、既存の機能の変更を行った際はテストを追加してください。
- OreOreBot2 ではテストフレームワーク Vitest を使用してテストを行っています。
- テストファイルの名前は
<file-name>.test.ts
とします。<file-name>
は機能の処理を行うファイルと同じ名前にし、.test.ts
との競合を回避するため、<file-name>
で.
を含めないようにしてください。- テストファイルは機能の処理を行うファイルと同じディレクトリに配置します。
- ミーム構文のみ
test/
配下に配置してください。
- ミーム構文のみ
コマンド
import { afterEach, describe, expect, it, vi } from 'vitest';
import { parseStringsOrThrow } from '../../adaptor/proxy/command/schema.js';
import { createMockMessage } from './command-message.js';
import { RoleInfo, RoleStatsRepository } from './role-info.js';
describe('RoleRank', () => {
afterEach(() => {
vi.restoreAllMocks();
});
const repo: RoleStatsRepository = {
fetchStats: (id) =>
Promise.resolve(
id === '101'
? {
color: '1a1d1a',
createdAt: new Date(20200101),
position: 1,
numOfMembersBelonged: 3
}
: null
)
};
const roleInfo = new RoleInfo(repo);
it('gets info of role', async () => {
const fetchStats = vi.spyOn(repo, 'fetchStats');
const fn = vi.fn();
await roleInfo.on(
createMockMessage(
parseStringsOrThrow(['roleinfo', '101'], roleInfo.schema),
fn
)
);
expect(fn).toHaveBeenCalledWith({
title: 'ロールの情報',
description: '司令官、頼まれていた <@&101> の情報だよ',
fields: [
{
name: 'ID',
value: '101',
inline: true
},
{
name: '所属人数',
value: `3人`,
inline: true
},
{
name: 'ポジション',
value: `1番目`,
inline: true
},
{
name: 'カラーコード',
value: '1a1d1a',
inline: true
},
{
name: '作成日時',
value: `<t:20200>(<t:20200:R>)`,
inline: true
}
],
thumbnail: undefined
});
expect(fetchStats).toHaveBeenCalledOnce();
});
it('errors with invalid id', async () => {
const fetchStats = vi.spyOn(repo, 'fetchStats');
const fn = vi.fn();
await roleInfo.on(
createMockMessage(
parseStringsOrThrow(['roleinfo', '100'], roleInfo.schema),
fn
)
);
expect(fn).toHaveBeenCalledWith({
title: '引数エラー',
description: '指定のIDのロールが見つからないみたい……'
});
expect(fetchStats).toHaveBeenCalledOnce();
});
});
ミーム
import { expect, it, vi } from 'vitest';
import { createMockMessage } from './command-message.js';
import { Meme } from './meme.js';
it('use case of hukueki', async () => {
const fn = vi.fn();
const responder = new Meme();
await responder.on(
createMockMessage(
{
args: ['hukueki', 'こるく']
},
fn
)
);
expect(fn).toHaveBeenCalledWith({
description:
'ねぇ、将来何してるだろうね\n' +
'こるくはしてないといいね\n' +
'困らないでよ'
});
});
詳しいテストの記述方法については Vitest Guide をご覧ください。
環境変数 FEATURE
で有効にする機能を指定できます。
以下の文字列をコンマで区切りで与えると、それら複数の機能を有効にして起動します。指定しない場合はスラッシュコマンドを除く全ての機能が有効になります。
"MEESAGE_CREATE"
- メッセージ作成関連の機能"MESSAGE_UPDATE"
- メッセージ更新関連の機能"COMMAND"
- コマンド全般の機能"VOICE_ROOM"
- VC 関連の機能"ROLE"
- ロール関連の機能"EMOJI"
- 絵文字関連の機能"STICKER"
- スタンプ関連の機能"SLASH_COMMAND"
- スラッシュコマンド関連の機能 (指定しない場合はスラッシュコマンドは登録されず、メッセージコマンド形式だけになります。)"MEMBER"
- メンバー関連の機能
!party
などの音楽再生系の機能は利用するには、FFmpeg がインストールされていてその PATH
が通っている必要があります。
以下のものをインストールしていることを想定しています。
- Git
- bun v1
- コンポーネント、型の命名には
PascalCase
を使用してください。 - 関数、変数の命名には
camelCase
を使用してください。 null
は使用せず、undefined
を使用してください。
- 各ページのファイル名は小文字英字とハイフンのみの
kabeb-case
としてください。 - コミット時に必ず Husky で Prettier と ESLint を実行してください。
リファレンスは docs/reference
に MDX ファイルとして追加してください。
commands
: 各コマンドのリファレンスを追加します。ファイル名と OreOreBot2 のpageName
プロパティが一致するように書いてください。
// 例: src/commands/version.ts
help: Readonly<HelpInfo> = {
title: 'はらちょバージョン',
description: '現在の私のバージョンを出力するよ。',
pageName: 'version'
};
features
: コマンド以外の機能のリファレンスを追加します。
コマンドリファレンス
コマンドリファレンスには以下の情報は必ず含めてください。
- 各引数が要求するものの説明
コンポーネント CommandArgs
を使用することで綺麗に記述可能です。
import { CommandArgs } from '../../../organisms/command-args';
# チャンネル情報表示
<CommandArgs
versionAvailableFrom="v1.37.0"
commandName="channelinfo/channel/chinfo"
args={[
{
name: 'チャンネルID',
about:
'情報を表示したいチャンネルのIDです。チャンネルのメンションを指定しないようにしてください。'
}
]}
/>
- どのバージョンから利用可能になったのか
- 機能追加系のPRの場合は基本的にマイナーバージョンがあがります。
コンポーネント CommandArgs
の versionAvailableFrom
を指定するか、機能リファレンスの場合は VersionBadge
を使用してください。
import { FeatureBadge } from '../../../molecules/feature-badge';
import { VersionBadge } from '../../../molecules/version-badge';
# Kawaemon has given a new role
<FeatureBadge>その他</FeatureBadge>,<VersionBadge>v1.16.0</VersionBadge>