開発への参加
問題の報告、アイデアの提案、ThirtyFile のコード変更の方法です。
参加者は 行動規範 に従ってください。
問題とアイデア
- Issue を作成 し、問題の報告、アイデアの提案、アクセシビリティの問題、ガイドの改善、コードの改善 から選びます。フォームで必要な情報を確認します。
- 先に 既存の Issue を探し、同じものがあれば新規作成せず追記してください。
コードを変更する
main へ直接 push しません。すべて独自のブランチからプルリクエストにします。
- Issue から始めます。 小さな修正より大きいものは、先に方針をそこで合意します。
mainから、内容を表す名前で ブランチを作ります。ブランチ 用途 feat/share-link-editing新しい機能 fix/upload-resume修正 docs/backup-guideサイトとガイド chore/update-actionsツール、ビルド、依存関係 - 変更を行い、以下の確認を実行します。
- プルリクエストを作ります。 内容を平易に表すタイトルと 1 つのラベルを付けます。説明に
Closes #123を書くとマージ時に Issue を閉じます。 - チェックを待ちます。 軽量の Checks passed が通るまでマージできません。
- マージします。
mainの 1 コミットになり、ブランチを削除します。
チェック
プルリクエスト作成前に、1 つのスクリプトでローカルの全チェックを実行します。リリースと手動の完全検証も実行しますが、自動の PR チェックは軽量です。
scripts/check.sh
| 対象 | 確認内容 |
|---|---|
scripts/check.sh quick | PR の自動確認:フロントエンドの整形、翻訳、モジュール境界、E2E 構造、型、lint、Rust の整形、migration の番号と既公開分の不変性、サイトのリンク。単体・ブラウザーテスト、Rust コンパイル、イメージビルドは実行しません |
scripts/check.sh web | 画面:lock 通りの依存関係、整形(pnpm format:check)、翻訳(node scripts/check-i18n.mjs)、Office の web/src/ooxml が他のアプリコードを import しないこと(node scripts/check-boundaries.mjs)、E2E に固定待機やランダム部分のない名前がないこと(node scripts/check-e2e.mjs)、型、lint、単体テスト。GitHub と同じ scripts/check.sh web --coverage では web/vitest.config.ts のカバレッジ下限未満も失敗になります |
scripts/check.sh server | サーバー:整形(cargo fmt --check)、cargo test、警告をエラーにする cargo clippy |
scripts/check.sh e2e | ソースからビルドしたサーバーへ、実ブラウザー(Playwright)でサインイン、アップロード、プレビューします。並列実行(GitHub は 4)するため、各テストで独自フォルダーとランダム名を使い、固定時間でなく操作後のサーバー応答を待ちます。web/tests/e2e/helpers.ts にヘルパーがあります。初回は cd web && pnpm exec playwright install chromium でブラウザーを取得します |
scripts/check.sh site | サイト:各言語の全ページ、相互の言語リンク、サイト内リンクとアンカーを確認します(node scripts/check-site.mjs)。Node だけで実行でき、サイトの変更でも実行します |
Windows では Git Bash で実行します。GitHub の完全検証は依存関係の既知の脆弱性(cargo deny、pnpm audit)も確認し、サーバーと E2E を合わせて行カバレッジ 90% 以上を必要とします(cargo llvm-cov、下限は .github/workflows/build.yml)。
コードはツールで整形し、未整形はチェックで失敗します。コミット前に実行してください。
cd server && cargo fmt
cd web && pnpm format
サーバーは rustfmt(server/rustfmt.toml)、画面は oxfmt(web/.oxfmtrc.json、対象は web/src、web/tests、web/scripts)を使います。エディターの拡張でも同じ設定で保存時に整形できます。手で 1 行に複数項目を並べた表は、前の // oxfmt-ignore で保持できます。web/src/lib/i18n/ の辞書は整形せず、1 行 1 項目です。
整形だけのコミットは .git-blame-ignore-revs に列挙します。GitHub の blame は無視します。ローカルの git blame でも無視するには git config blame.ignoreRevsFile .git-blame-ignore-revs を一度実行してください。
- コード、コメント、ガイドの原文は英語です。
- 画面の文字はコードで英語を使い、
web/src/lib/i18n/の各言語の同名ファイルに翻訳します。繁体字中国語(zh-TW)、簡体字中国語(zh-CN)、日本語(ja)はすべて必須で、新しい文字にも用語集に従う翻訳が必要です。node scripts/check-i18n.mjsは全言語を確認し、必須言語の不足や未使用項目は失敗にします。ほかの言語は報告のみで、残るプレースホルダー数も示します。COMPLETEの一覧に入ると必須になり、言語メニューの言語は必須です。--require <language>で新しい言語の不足を確認できます。 - サーバーのメール原文は
server/src/i18n/texts.rs、翻訳は隣のzh_tw.rs、zh_cn.rs、ja.rsです。不足分は英語で送ります。texts.rsのCOMPLETEや言語メニューの言語で不足する場合、または{parameters}が原文と違う場合、テストは失敗します。 - 動作を変更したら
site/docs/の対応ガイドも更新します。 - 0.4.0 のデータ構造は固定し、既存データが使えるようにします。変更は
server/migrations/0002_<name>.sql以降の新ファイルで 0.4.0 を更新します。0001_init.sqlと既公開 migration は編集禁止で、チェックで失敗します。 - Web アプリの API の型(
web/src/api/types.ts)は手書きです。サーバーのテストが主なレスポンスの構造をweb/tests/contract/shapes.jsonに記録しており、構造が変わると失敗します。server/でTHIRTYFILE_UPDATE_SHAPES=1 cargo test api_shapesを実行し、pnpm typecheckが通るまで型を直してください。 - 数式、ブック保存、文字コードなど、ファイルを変更するロジックには
web/tests/unit/の単体テストを用意します。
PR は軽量チェックを実行します。完全テストとイメージはリリース、プレリリース前、または Actions › Build › Run workflow で実行し、手動検証では公開しません。公開前に両アーキテクチャを compose.yaml と前リリースのデータで起動します。CodeQL はマージ後の main、週次、リリース前に走ります。main のマージはサイトも含め何も公開しません。ガイドはインストールできる内容を示すためリリースで公開します。既公開版にも正しいガイドの修正は、Actions › Website › Run workflow で公開元に main を指定して手動公開できます。
他言語のサイト
ホームと全 16 ガイドは英語、繁体字中国語、簡体字中国語、日本語で利用でき、各言語に同じ 17 ページがあります。
| ページ | 英語 | 他言語 |
|---|---|---|
| ホーム | site/index.html | site/<language>/index.html |
| インストール | site/docs/index.html | site/<language>/docs/index.html |
| ほかの全ガイド | site/docs/<guide>.html | site/<language>/docs/<guide>.html |
メニュー、関連、前後、章のリンクは選択言語を保ちます。切り替えは同じガイドへ、JavaScript があれば同じ章へ移ります。README も README.md と並ぶ README.zh-TW.md、README.zh-CN.md、README.ja.md があり、それぞれ同言語サイトへリンクします。
- 翻訳ページの変更は、同じ PR で全言語を更新します。 書けない言語があれば PR に記し、メンテナーが翻訳できる人を探します。
- 各版は
<html lang>、独自タイトルと説明、自分を含む全版の<link rel="alternate" hreflang>を持ちます。言語、ガイド、章のメニューを各 HTML に書き、JavaScript なしでも動くようにします。章 ID とコマンド、設定例は全言語で同じにします。 - 言語と全ページは
site/assets/site.js上部のLANGUAGES、TRANSLATEDにあり、メニューとフッターの翻訳もあります。ナビゲーションやガイドの見出しを変更したら、node scripts/update-site-navigation.mjsで静的メニューと章の一覧を更新します。scripts/check.sh siteは不足、誤ったメタデータと切り替え、章漏れ、コード変更、壊れたリンク、意図しない別言語リンクを検出します。新ページも同じ PR で全言語に追加します。node --test scripts/check-site.test.mjsでチェック機能をテストできます。フロントエンドの Playwright 依存関係と Chromium を導入した環境では、node scripts/check-site-browser.mjs <scratch-directory>が実際のページ、言語と章の切り替え、モバイル表示、JavaScript なしのナビゲーションを確認し、サイトの外にスクリーンショットを保存します。 - 画面と同じ 用語集(
web/src/lib/i18n/glossary.md)に従います。簡体字は繁体字の文字変換だけでなく中国本土の語を使い、日本語はです・ます調で、エクスプローラーと Finder の用語を使います。 - ホームの主画像は各言語のサンプル入りローカル環境から、1280 × 720、2 倍解像度の WebP で撮ります(
site/assets/files-light-<language>.webp、files-dark-<language>.webp)。ほかの画像は英語のままです。
ラベル
| ラベル | リリースノートの分類 |
|---|---|
enhancement | 新機能 |
bug | 修正 |
performance | 高速化 |
accessibility | 誰でも使いやすく |
documentation | ガイドとサイト |
dependencies | 依存関係の更新 |
maintenance | 保守 |
リリース
ghcr.io/thirtyfile/thirtyfile と docker.io/thirtyfile/thirtyfile の両方へ公開します。Docker Hub 初回前に Settings › Secrets and variables › Actions で変数 DOCKERHUB_USERNAME と secret DOCKERHUB_TOKEN を追加します。対象倉庫への読み書き権限の token を使ってください。認証をスキャン、ビルド前に確認し、検証済みイメージを digest でコピーして全 Hub タグを確認してから GitHub リリースを公開します。
マージした変更はメンテナーが公開を決めるまで main に集まります。Actions › Release › Run workflow で main を選び、1.2.3、プレリリースなら 1.2.3-rc.1 を入力して手動開始します。コマンドでもできます。
gh workflow run release.yml -f version=1.2.3
main を CodeQL でスキャンし、テスト、amd64 と arm64 のイメージをビルド、起動します。すべて通ってから、まだタグなしで push します。次にイメージから両プログラムを取得し、チェックサム、ライセンス、系列に固定した compose.yaml(1.0.0 前は :1.2、以後は :1)付きドラフトを作ります。再ビルドせず 1.2.3、1.2、1(1.0.0 以後)、latest を付け、前リリース以降の PR をまとめたノートで公開して v1.2.3 を作り、タグからサイトを公開します。high、critical の未解決警告、テスト、イメージの失敗では何も push、タグ、公開しません。修正するか、該当しない警告は Security › Code scanning で却下して再実行します。後段の失敗は同じ番号で再実行すると、既に 1.2.3 のイメージを使い、作り直しません。番号は前回より新しく、v タグは移動、削除できません。
1.2.3-rc.1 のように - を含む版はプレリリースです。1.2.3-rc.1 のタグのみを付け、GitHub でも表示を付けるため、明示しない人には配りません。サイトも公開しません。良好でその後マージがなければ、同じコミットから 1.2.3 を公開します。再ビルドせず試したイメージにタグを付けるため、完全に同じ内容です(内部の版ラベルはプレリリース名のまま)。
| 番号 | 増やす場合 |
|---|---|
第 1(2.0.0) | 利用者が依存するものの変更や削除 |
第 2(1.3.0) | 新しいものの追加 |
第 3(1.2.4) | 修正のみ |
既存リリースをコピーするには Actions › Mirror a release to Docker Hub › Run workflow で main と 0.6.0 などの公開版を指定します。Git タグ、イメージ revision、GHCR の署名来歴を確認します。系列、major、latest は現在 GHCR の同じタグが同じイメージを指す場合だけ進め、古い版で新しい版を置き換えません。正確な版の既存タグは digest が違うと停止します。一致するコピーの再試行は安全で、再ビルドしません。
ライセンス
ThirtyFile は Apache License 2.0 です。貢献も同じ条件で提供します。
依存関係は許容的ライセンスが必要です。Rust は server/deny.toml と同じ一覧を持つ server/about.toml、npm は同じ一覧とフォントの OFL-1.1 を使う web/scripts/third-party-notices.mjs で確認し、両方をテストします。ビルド時に全 crate、npm、musl、認証局、タイムゾーンデータの告知を THIRD-PARTY-NOTICES にまとめ、一覧外のライセンスなら失敗します。