OreOreBot2 への貢献を検討していただきありがとうございます。
バグ報告や機能追加の提案、ドキュメントの改善など、様々な貢献をお待ちしています。
OreOreBot2 では以下のような Issue を提出することができます。
これらの Issue はテンプレートが用意されており、それぞれの目的に応じた内容を記述することで、簡単に Issue を提出できます。
テンプレートを使用せず、空の Issue を使用して提出することも可能です。ただしその場合はしっかり内容を記述してください。
自分で開発したり修正した機能・不具合を Pull Request として提出することも可能です。
- OreOreBot2 のリポジトリをフォークする
リポジトリ画面の右上にある "Fork" から自分のアカウントにクローンしてください。
Note
approversのメンバーはフォークする必要はありません。
- ローカルにクローンする
次のコマンドを実行してリポジトリをローカルにクローンしてください。
git clone https://github.com/approvers/OreOreBot2.git- 依存関係をインストールする
次のコマンドを実行して依存関係をインストールしてください。
このコマンドを実行すると共通のパッケージ・@oreorebot2/bot(はらちょ本体)・@oreorebot2/docs(はらちょのドキュメント)、それぞれの依存関係がインストールされます。
必ず、ルートディレクトリ上で実行してください。
pnpm 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で使用される依存関係やコンフィグファイルが管理されています。- このディレクトリ上で
pnpm 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 (音楽再生系の機能で必要です)
- pnpm v10
- 型、クラスの命名には
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
- pnpm v10
- コンポーネント、型の命名には
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
availableFrom="v1.37.0"
names={["channelinfo", "channel", "chinfo"]}
args={[
{
name: 'チャンネルID',
about:
'情報を表示したいチャンネルのIDです。チャンネルのメンションを指定しないようにしてください。'
}
]}
/>- どのバージョンから利用可能になったのか
- 機能追加系のPRの場合は基本的にマイナーバージョンがあがります。
コンポーネント CommandArgs の availableFrom を指定するか、機能リファレンスの場合は VersionBadge を使用してください。
import { FeatureBadge } from '../../../molecules/feature-badge';
import { VersionBadge } from '../../../molecules/version-badge';
<FeatureBadge>その他</FeatureBadge>,<VersionBadge>v1.16.0</VersionBadge>