GitHub REST API を Wolfram Language から操作するヘルパーパッケージ(コンテキスト: `GitHubREST``)
Wolfram Language(Mathematica)のパッケージ開発では、コードを書き上げた後に GitHub へアップロードする作業が手動になりがちです。github(`GitHubREST``)は、その一連の操作――リポジトリ作成・ファイル同期・コミット・プルリクエスト管理――をすべて Wolfram Language のセル内から完結させることを目的として設計されています。
APIキーをコード中に直書きしない安全設計を採用しています。GitHub Personal Access Token の取得・保持はすべて NBAccess の NBGetAPIKey["github"] に委譲します。これにより、github パッケージ自身は認証情報を一切保持せず、複数パッケージ間で統一されたキー管理が実現されます。
単純な .wl ファイル単体のアップロードだけでなく、パクレット(フォルダ型パッケージ)や付属ドキュメント群をまとめて同期するために、マニフェスト(packageName_info/upload_manifest.json)を導入しています。マニフェストにはアップロード対象ファイル・ディレクトリ・除外パターンを記述でき、パッケージ種別(.wl 単体 / パクレットフォルダ)を自動検出して初回は自動生成されます。パッケージ種別が変更された場合(.wl からパクレットへの変換など)もマニフェストは自動更新されます。_info/docs/README.md が存在する場合はリポジトリのトップレベル README.md として自動配置されるため、ドキュメント管理も一元化できます。
GitHub Contents API の単純なファイル更新ではなく、Git の低レベル API(blob 作成 → tree 作成 → commit 作成 → ref 更新)を使っています。これにより複数ファイルを一つのコミットにまとめて反映でき、履歴が汚れません。blob 作成処理では Catch/Throw パターンを採用し、ファイル読み込みエラー・API エラー・SHA 取得失敗(空文字列を含む)のいずれも即座に検出・伝播します。エントリが空の場合は "EmptyEntries" エラーとして報告され、tree SHA の検証でも空文字列を不正値として扱うため、問題の原因を正確に特定できます。Windows 環境での UTF-8 エンコード問題は iEncodeJSONBody / iForceASCIIJSON で内部的に回避しており、日本語ファイル名・コミットメッセージも正しく送信できます。
GitHub リポジトリ名には ASCII 文字しか使えないため、日本語などの非 ASCII パッケージ名と英語リポジトリ名の対応を GithubRepositories/repo_database.json で管理するリポジトリ名データベースを内蔵しています。未登録の非 ASCII 名は claudecode の Claude API を呼び出し、意味のある英語リポジトリ名を 3 候補生成し、GitHub 上の重複を確認した上で自動登録します。Claude API が利用できない場合は Transliterate によるフォールバックが行われます。Fallback -> True オプションを指定すると、API 制限時も代替モデルで継続処理されます。Fallback -> True が明示されていない場合はエラーを伝播して処理を停止し、不正なリポジトリ名が登録されることを防ぎます。
$packageDirectory/GithubRepositories/packageName をローカル作業フォルダとして使います。GitHub からの Pull(取得)はこのフォルダへ展開され、Commit 時はこのフォルダの内容を GitHub へ送信します。中間フォルダを挟む設計により、$packageDirectory 本体を直接汚染せずに安全にバージョン管理できます。
GitHubCommitDataset の「Pull」ボタンで過去コミットのファイルをローカルに取得する際、初回のみ現在の作業状態を GithubRepositories/_local_snapshot/packageName/ にスナップショットとして自動保存します。各ファイルの SHA-256 ハッシュも _snapshot_hashes.json に記録され、スナップショット後に変更されたファイルを検出できます。GitHubCommitDataset の「#0 行」から「Pull」ボタンを押すことでローカル最新版へいつでも復元可能です。2 回目以降の過去コミットへの巻き戻しでは既存スナップショットを温存するため、最初の作業状態が失われません。
復元時に変更されたファイルが検出された場合は、ファイル一覧と確認ボタン(「すべてローカル最新版に置き換える」/「キャンセル」)を含む警告セルグループが Grid の直後に挿入されます。
GitHubPullRequestDataset は、オープン PR の一覧を Review / Pull / Merge / Close のボタン付き Grid として返します。緊急度・ラベル・依存関係によるソートも行われるため、Mathematica のノートブック上でそのままコードレビューからマージまで完結できます。
GitHubCommitDataset は、コミット履歴を Review / Pull / Revert のボタン付き Grid として表示します。表示時に既存スナップショットを削除して現在の作業状態を新規保存するため、常に最新のローカル状態が記録されます。特定コミットのファイルをローカルに取得して検証したり、変更を打ち消すリバートコミットを作成したりする操作がノートブック上で完結します。ボタンの二重実行は $iGitHubEvalGuard による再評価防止ガードで保護されています。
GitHubInstallPackage[packageName, url] の 2 引数版を使うと、GitHub URL を直接指定して他者のリポジトリをインストールできます。インストール時に owner・repository 名が repo_database.json へ自動登録されるため、以後は packageName だけで GitHubUpdatePackage や GitHubCommitDataset などの操作が可能になります。
インストール先の振り分けはリポジトリの種別によって自動判定されます。
| パターン | 条件 | 動作 |
|---|---|---|
| A (自分のリポジトリ) | RepoDB に owner が登録されていない | 全ファイル・全フォルダをそのまま $packageDirectory へコピー |
B (リモート + _info あり) |
RepoDB に owner 登録あり、packageName_info/ フォルダが存在 |
README.md を除く全ファイルを $packageDirectory へコピー |
C (リモート + _info なし) |
RepoDB に owner 登録あり、_info フォルダなし |
.wl のみ $packageDirectory へ、それ以外は _info/originals/ に保存 |
パターン C の場合、非 .wl ファイル(README 等)は packageName_info/originals/ へ振り分けられ、doc_options.json にマッピングが保存されます。コミット時に iRestoreOriginalsToRepo が元の位置へ書き戻します。
| 項目 | 内容 |
|---|---|
| Mathematica | 13.0 以上推奨 |
| OS | Windows 11 想定(macOS / Linux は未検証) |
| 依存パッケージ | NBAccess、claudecode(日本語パッケージ名の自動翻訳に使用) |
| 外部サービス | GitHub アカウント・Personal Access Token(スコープ: repo) |
本パッケージは NBAccess に依存します。先に NBAccess.wl が $packageDirectory に配置済みであることを確認してください。日本語パッケージ名の自動英語翻訳には claudecode も必要です。
FileExistsQ[FileNameJoin[{$packageDirectory, "NBAccess.wl"}]]
(* True であれば OK *)github_fixed.wl を $packageDirectory にコピーします。
(* $packageDirectory の場所を確認 *)
$packageDirectoryファイル名だけで指定できるのは、$packageDirectory が $Path に含まれているためです。Windows 環境での文字化けを防ぐため、必ず $CharacterEncoding = "UTF-8" を指定して読み込んでください。
Block[{$CharacterEncoding = "UTF-8"},
Needs["GitHubREST`", "github_fixed.wl"]];認証は NBAccess に委譲されます。以下の手順でトークンを登録してください。
Personal Access Token の取得:
- GitHub → Settings → Developer settings → Personal access tokens
- Fine-grained tokens または Classic tokens を生成
- 必要スコープ:
repo(リポジトリの読み書き)
NBAccess へのキー登録:
Block[{$CharacterEncoding = "UTF-8"},
Needs["NBAccess`", "NBAccess.wl"]];
NBSetAPIKey["github", "ghp_xxxxxxxxxxxxxxxxxxxx"]
(* 登録後は永続化されるため、再設定不要 *)$GitHubLicenseHolder を設定すると、_info/docs/README.md を GitHub へ同期する際に MIT ライセンスセクションが自動挿入されます。空文字列のままにするとライセンスセクションは挿入されません。
$GitHubLicenseHolder = "Katsunobu Imai"以下の手順を順に実行するだけで、パッケージの GitHub リポジトリ管理が始められます。
(* 1. パッケージの読み込み *)
Block[{$CharacterEncoding = "UTF-8"},
Needs["GitHubREST`", "github_fixed.wl"]];
(* 2. $packageDirectory 内のパッケージ URL 一覧を確認 *)
GitHubPackageURLs[]
(* -> <|"mypackage" -> "https://github.com/<owner>/mypackage", ...|> *)
(* 3. 新規リポジトリを作成してファイルを初回コミット
(upload_manifest.json が自動生成され、対象ファイルが一括コミットされる) *)
GitHubCreateRepository["mypackage", Public -> False, Description -> "My WL package"]
(* -> <|"DefaultBranch" -> "main", ...|> *)
(* 4. ファイルを修正した後、リフレッシュ → コミットを一括実行 *)
GitHubRefreshAndCommit["mypackage", "fix: バグ修正"]
(* -> <|"CommitSHA" -> "a1b2c3...", "Branch" -> "main", ...|> *)
(* 5. プルリクエストを作成する場合 *)
GitHubSubmitPullRequest["mypackage",
"feat: 新機能追加",
"詳細な変更内容をここに記述する。"]
(* -> <|"PullRequest" -> <|"Number" -> 1, "URL" -> "https://github.com/.../pull/1"|>, ...|> *)
(* 6. オープン PR を一覧表示(ボタン付き Grid) *)
GitHubPullRequestDataset["mypackage"]
(* 7. コミット履歴を表示(ボタン付き Grid) *)
GitHubCommitDataset["mypackage"]
(* 8. 自分のパッケージをダウンロード *)
GitHubInstallPackage["fact", Owner -> "transreal"]
(* 9. 他人のリポジトリを URL 指定でインストール *)
GitHubInstallPackage["pkg", "https://github.com/alice/repo"]
(* -> owner と repository が repo_database.json に自動登録される *)主要オプション(既定値):
| オプション | 既定値 | 説明 |
|---|---|---|
Owner |
Automatic |
GitHub ユーザー名(省略時はトークンから自動取得、または RepoDB から解決) |
Repository |
Automatic |
リポジトリ名(省略時は packageName、非 ASCII なら自動翻訳) |
Branch |
Automatic |
操作対象ブランチ |
BaseBranch |
Automatic |
デフォルトブランチ(API から自動取得) |
Public |
False |
True で公開リポジトリ作成 |
CreateBranch |
Automatic |
ブランチ不在時に自動作成するか(Branch =!= BaseBranch なら True) |
DeleteMissing |
False |
ローカルに無いリモートファイルを削除するか |
MaxItems |
30 |
GitHubListCommits / GitHubCommitDataset で取得するコミット数の上限 |
ExtraDirectories |
{} |
マニフェストに永続追加するディレクトリのリスト(例: {"Claude Directives"}) |
Fallback |
False |
True で API 制限時に代替モデルでの処理を有効化 |
GitHubPackageURL[name]—$packageDirectory内パッケージの GitHub URL を返すGitHubPackageURLs[]— 全パッケージの<|name -> url|>を返すGitHubRepoPath[name]— ローカル作業フォルダのパスを返すGitHubEnsureLocalRepo[name]— ローカル作業フォルダを作成して返す
GitHubReadManifest[name]—packageName_info/upload_manifest.jsonを読む(不在時は自動生成)。パッケージ種別変更時は自動更新GitHubRefreshLocalPackageGroup[name]— マニフェストに従いファイルをローカル作業フォルダへコピー。_info/originals/の内容を元のリポジトリパスへ書き戻す処理(iRestoreOriginalsToRepo)も実行するGitHubRefreshLocalPackage[name]—.wl単体をローカルへコピー(後方互換用)
GitHubCreateRepository[name]— GitHub に新規リポジトリを作成し、ファイルを初回コミット。ExtraDirectoriesでマニフェストにディレクトリを追加可能GitHubReadFile[name, path]— GitHub 上のファイルを読み取るGitHubPull[name]— リモートの内容をローカル作業フォルダへ取得GitHubCommit[name, message]— ローカル作業フォルダの内容を GitHub へ一括コミット。blob 作成時のエラーはCatch/Throwパターンで確実に伝播され、エントリ空・SHA 欠落・空文字列も検出するGitHubRefreshAndCommit[name, message]— リフレッシュ → コミットを一括実行。ExtraDirectoriesでマニフェストにディレクトリを追加可能
GitHubSubmitPullRequest[name, title, message]— refresh → branch 作成 → commit → PR 作成を一括実行。ブランチ名はpr/packageName/日時-slugified-titleで自動生成GitHubListPullRequests[name]— オープン PR 一覧を優先度・依存関係でソートして返すGitHubPullRequestDataset[name]— PR 一覧を Review / Pull / Merge / Close ボタン付き Grid で返すGitHubMergePullRequest[name, prNumber, reason]— PR をマージする(理由をコメントとして記録)GitHubClosePullRequest[name, prNumber, reason]— PR をクローズする(理由をコメントとして記録)GitHubReviewPullRequest[name, prNumber]— PR のコードをダウンロードしてノートブックに CellGroup として出力するGitHubCreatePullRequest[name, title]— PR を作成する。head と base が同一ブランチの場合はエラーメッセージで代替手段を案内
GitHubListCommits[name]— リポジトリのコミット履歴をリストで返す。オプション:Owner,Repository,Branch,MaxItemsGitHubCommitDataset[name]— コミット履歴を Review / Pull / Revert ボタン付き Grid で表示する。表示時に既存スナップショットを削除して現在の作業状態を新規保存し、#0 行(ローカル最新版)への復元ボタンも表示される。Grid はタグ付き Output セルとして出力され、再実行時に古いセルは自動削除される。オプション:Owner,Repository,Branch,MaxItemsGitHubReviewCommit[name, sha]— 指定コミットの詳細・差分をノートブックに CellGroup として表示する。Pull / Revert ボタン付きGitHubRevertCommit[name, sha, reason]— 指定コミットの変更を打ち消すリバートコミットを作成する(親コミットの tree を使用)
GitHubRepoDB[]—repo_database.jsonの全レコードを返すGitHubRepoDBSet[name, repoName]— パッケージ名 → リポジトリ名の対応を登録GitHubRepoDBSet[name, repoName, owner]— パッケージ名 → リポジトリ名 + owner を登録。他人のリポジトリをインストールする際にGitHubInstallPackage[name, url]が自動的に呼び出すGitHubRepoDBLookup[name]— DB からリポジトリ名を解決(未登録ならnameをそのまま返す)
未登録の非 ASCII パッケージ名は claudecode の Claude API を呼び出して意味のある英語リポジトリ名を 3 候補生成し、GitHub 上の重複を確認した上で自動登録します。全候補が重複する場合はサフィックス(-2 ~ -20)または日付が付与されます。RepoDB に owner が登録されている場合、iResolveOwner はトークンからの自動取得よりも RepoDB の値を優先します。
GitHubInstallPackage[name]— GitHub から$packageDirectoryへ初回ダウンロード。Ownerオプションで所有者を指定可能GitHubInstallPackage[name, url]— GitHub URL を直接指定して他者のリポジトリをインストール。urlから owner・repository 名を解析してrepo_database.jsonに自動登録し、以後はパッケージ名だけで操作できるGitHubUpdatePackage[name]— 既存パッケージを GitHub 最新版に更新(内部的にGitHubInstallPackageと同じ処理)
$GitHubLicenseHolder— MIT ライセンスの著作権者名。空文字列""の場合、ライセンスセクションはREADME.mdに挿入されません。例:$GitHubLicenseHolder = "Katsunobu Imai"
| ファイル | 内容 |
|---|---|
api.md |
全関数・オプションのリファレンス |
setup.md |
セットアップガイド(要件・インストール・API キー設定・トラブルシューティング) |
user_manual.md |
各関数の詳細な使い方と引数説明 |
example.md |
典型的なユースケースのコード例 |
リポジトリ: https://github.com/transreal/github
(* パッケージの GitHub リポジトリを作成してファイルを初回アップロード *)
GitHubCreateRepository["mypackage",
Public -> True,
Description -> "My Wolfram Language package",
ExtraDirectories -> {"Claude Directives"}](* パッケージを更新してプルリクエストを作成 *)
GitHubSubmitPullRequest["mypackage",
"feat: 新機能追加",
"詳細な変更内容を記述"]
(* プルリクエスト一覧を表示(レビュー・マージボタン付き) *)
GitHubPullRequestDataset["mypackage"](* GitHub URL を指定して他人のパッケージをインストール *)
GitHubInstallPackage["ResistorBuilder",
"https://github.com/dzhang314/ResistorBuilder"]
(* 以降はパッケージ名だけで操作可能 *)
GitHubCommitDataset["ResistorBuilder"](* コミット履歴を表示(レビュー・プル・リバートボタン付き) *)
GitHubCommitDataset["mypackage", MaxItems -> 50]
(* 特定コミットの詳細をレビュー *)
GitHubReviewCommit["mypackage", "a1b2c3d4e5f6..."](* 日本語パッケージ名でもリポジトリ名を自動翻訳 *)
GitHubCreateRepository["情報工学科時間割"]
(* -> 自動的に "jouhou-timetable" などの英語リポジトリ名を生成 *)本ソフトウェアは "as is"(現状有姿)で提供されており、明示・黙示を問わずいかなる保証もありません。 本ソフトウェアの使用または使用不能から生じるいかなる損害についても責任を負いません。 今後の動作保証のための更新が行われるとは限りません。 本ソフトウェアとドキュメントはほぼすべてが生成AIによって生成されたものです。 Windows 11上での実行を想定しており、MacOS, LinuxのMathematicaでの動作検証は一切していません(生成AIの処理で対応可能と想定されます)。
MIT License
Copyright (c) 2026 Katsunobu Imai
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.