{
"$type": "site.standard.document",
"bskyPostRef": {
"cid": "bafyreigi3rpttge2ayozxsxftbtus2kep5osxqusgkb6h23bw6kab66ufu",
"uri": "at://did:plc:g4wcucb6ko2frmko2x3lvgyi/app.bsky.feed.post/3mbcykefjatj2"
},
"path": "/2025/12/31/open-source-in-2025/",
"publishedAt": "2026-04-15T07:27:40.336Z",
"site": "https://efcl.info",
"tags": [
"textlint",
"JSer.info",
"JavaScript Primer",
"secretlint",
"npmパッケージ/GitHub Actionsを利用する側/公開する側でサプライチェーン攻撃を防ぐためにやることメモ",
"https://efcl.info/2014/12/31/oss-in-2014/",
"https://efcl.info/2015/12/31/oss-in-2015/",
"https://efcl.info/2016/12/31/oss-in-2016/",
"https://efcl.info/2017/12/30/oss-in-2017/",
"https://efcl.info/2018/12/31/oss-in-2018/",
"https://efcl.info/2019/12/31/oss-in-2019/",
"https://efcl.info/2020/12/31/open-source-in-2020/",
"https://efcl.info/2021/12/31/open-source-in-2021/",
"https://efcl.info/2022/12/31/open-source-in-2022/",
"https://efcl.info/2023/12/31/open-source-in-2023/",
"https://efcl.info/2024/12/31/open-source-in-2024/",
"Secretlint",
"HonKit",
"philan.net",
"Komesan",
"Irodr",
"ECMAScript Daily",
"JavaScript Promiseの本",
"@azuのGitHub Sponsors",
"JavaScript Primer - Open Collective",
"Thanks OSS Award presented by Toyokumo",
"GitHub Sponsorsの募集を始めてから2年が経ったので振り返る | Web Scratch",
"Sponsor @azu on GitHub Sponsors",
"textlint v15.0.0",
"textlint v15.0.0をリリースしました。非推奨APIの削除とNode.js 20+サポート/MCPサーバの改善 | Web Scratch",
"textlint v14.8.0をリリースしました - MCP(Model Context Protocol)をサポート | Web Scratch",
"@textlint-ja/textlint-rule-preset-ai-writing",
"npm Trusted PublishingでOIDCを使ってトークンレスでCIからnpmパッケージを公開する | Web Scratch",
"v7.0.0",
"JavaScript Primer v7.0.0リリース: ES2025対応とIterator Helpersの新章追加 | Web Scratch",
"Contributing Expenses Policy",
"v10.0.0",
"v11.0.0",
"Secretlint v10.0.0リリース: デフォルトでシークレットをマスク表示するように変更、Node.js 20+のサポート | Web Scratch",
"1067",
"@secretlint/secretlint-rule-anthropic",
"@secretlint/secretlint-rule-database-connection-string",
"JSer.info 14周年",
"JSer.info のMCPサーバー",
"https://mcp.jser.info/mcp",
"@jser/mcp",
"TSKaigi 2025で「技術書をソフトウェア開発する」という発表をしました | Web Scratch",
"https://azu.github.io/slide/2025/tskaigi/jsprimer.html",
"https://www.youtube.com/watch?v=r5CZdn8IQlc",
"YAPC::Fukuoka 2025で「読む技術・書く技術・伝える技術 - 15年続けて分かった持続可能なオープンソース開発」という発表をしました | Web Scratch",
"https://azu.github.io/slide/2025/yapc/opensource-15years.html",
"azu/confirm-pam",
"AI Agentのコマンド実行にTouch IDを使った「人間の確認」を挟むCLIツール confirm-pam を作った | Web Scratch",
"textlint-ja/textlint-rule-preset-ai-writing",
"textlint/vscode-textlint",
"azu/setup-npm-trusted-publish",
"jser/mcp",
"azu/intl-format-date",
"azu/madori",
"azu/humidifier-similator",
"azu/monorepo-npm-oidc-releases",
"jser/jser-info-prompt",
"azu/nextjs-cve-2025-29927-poc",
"azu/request-filtering-agent-https127-test",
"azu/pnpm-10-with-postinstall-lifecyle",
"azu/pnpm–frozen-lockfile-bug",
"azu/panda-css-vscode-example",
"azu/panda-css-eslint-demm",
"azu/pandacss-nested-condition-bug",
"azu/no-physical-properties-text-align",
"azu/next-prefetch-txt-bug",
"azu/latest-next",
"azu/react-server-example",
"azu/react-aria-reading-target-error",
"azu/react-aria-table-execption",
"azu/textlint-mcp-example",
"azu/copilot-review-automerge",
"azu/base64-research",
"azu/simple-oidc-example-package",
"npm Trusted PublishingでOIDCを使ってトークンレスでCIからnpmパッケージを公開する",
"ni.zsh v1.8.0",
"ni.zsh v1.8.0リリース: Socket Firewallによるパッケージインストール時のチェック機能を追加 | Web Scratch",
"HonKit v6.1.4",
"pinact",
"zizmor",
"ni.zsh",
"1Passwordで管理",
"actionlint",
"クラシックトークン作成の無効化",
"pull_request_targetのブランチ保護強化",
"TSKaigi 2025",
"YAPC::Fukuoka 2025",
"@secretlint",
"@pandacss"
],
"textContent": "2025年のオープンソース活動の振り返りとGitHub Sponsorsでの収入をまとめた記事です。\n\n今年はtextlintとJSer.infoにMCPサーバーを実装しました。 また、JavaScript PrimerをES2025に対応し、secretlintに新しい検出ルールを追加しました。 AI連携とECMAScript最新仕様への対応が中心の年でした。 TSKaigi 2025とYAPC::Fukuoka 2025では、継続的なメンテナンスについて発表しました。\n\nサプライチェーン攻撃対策についてはZennに記事をまとめました。\n\n * npmパッケージ/GitHub Actionsを利用する側/公開する側でサプライチェーン攻撃を防ぐためにやることメモ\n\n\n\n## 今までの振り返り\n\n * 2014年: https://efcl.info/2014/12/31/oss-in-2014/\n * 2015年: https://efcl.info/2015/12/31/oss-in-2015/\n * 2016年: https://efcl.info/2016/12/31/oss-in-2016/\n * 2017年: https://efcl.info/2017/12/30/oss-in-2017/\n * 2018年: https://efcl.info/2018/12/31/oss-in-2018/\n * 2019年: https://efcl.info/2019/12/31/oss-in-2019/\n * 2020年: https://efcl.info/2020/12/31/open-source-in-2020/\n * 2021年: https://efcl.info/2021/12/31/open-source-in-2021/\n * 2022年: https://efcl.info/2022/12/31/open-source-in-2022/\n * 2023年: https://efcl.info/2023/12/31/open-source-in-2023/\n * 2024年: https://efcl.info/2024/12/31/open-source-in-2024/\n\n\n\n## オープンソース活動の種類\n\n自分のオープンソース活動の種類として、次のようなものがあります。\n\n * ソフトウェア開発: textlint、Secretlint、HonKitなどの開発やメンテナンス\n * ウェブサービス開発: philan.net、Komesan、Irodrなどの開発やメンテナンス\n * ブログ: JSer.infoやECMAScript Dailyのブログの投稿\n * 書籍: JavaScript PrimerやJavaScript Promiseの本の執筆\n\n\n\n## オープンソース関係の収入の種類\n\n自分のオープンソース関係の収入は、ほぼGitHub Sponsors経由となっています。\n\n * @azuのGitHub Sponsors\n\n\n\nGitHub SponsorsではMonthlyとOne-Timeでのサポートができます。 自分の場合は、GitHub SponsorsのMonthlyでの支援がベースとなっています。\n\nまた、JavaScript PrimerのOpen Collectiveからの収入もあります。\n\n * JavaScript Primer - Open Collective\n\n\n\n今年のjsprimer Contributorへの支払いもOpen Collectiveの予算から行なっています。\n\n## オープンソース関係の収入の合計金額\n\n2025年のGitHub Sponsorsの収入は**約229万円** となりました。\n\n月毎のGitHub Sponsorsの収入は次のようになります。\n\nDate | 金額(円)\n---|---\n2025/01 | 365,934\n2025/02 | 194,231\n2025/03 | 165,227\n2025/04 | 164,772\n2025/05 | 175,487\n2025/06 | 160,140\n2025/07 | 176,382\n2025/08 | 172,587\n2025/09 | 162,930\n2025/10 | 164,611\n2025/11 | 169,251\n2025/12 | 216,958\n\n1月が多いのは、Thanks OSS Award presented by Toyokumoの2024年度(7月〜12月)分が入っているためです。 12月が多いのはスポンサーのアカウント移行に伴う一時的な重複によるものです。\n\n## 継続的なサポートをしてくれている人の数\n\nGitHub Sponsorsで継続的にサポートしてくれている人の推移は次のとおりです。\n\nこの人数は現在も継続している人数だけを出しています。\n\nMonthly Estimated Income(単位は$)は次のようになっています。\n\nGitHub Sponsorsは、2019年10月から始めています。 今までのGitHub Sponsorsでの収入の推移は、次のとおりです。\n\nGitHub Sponsorsを始めた経緯については、次の記事にまとめてあります。\n\n * GitHub Sponsorsの募集を始めてから2年が経ったので振り返る | Web Scratch\n\n\n\n## GitHub Sponsorsに感謝\n\nGitHub Sponsors でご支援いただきありがとうございます!\n\n * Sponsor @azu on GitHub Sponsors\n\n\n\n## Contributions/Issues/PR\n\n * Contributions: 11082\n * 作成したリポジトリ: 40\n * 作成したIssue: 99\n * 作成したPull Request: 371\n\n\n\n今年は検証用のリポジトリをたくさん作りました。 pnpmやPanda CSS、Next.js、React Ariaなどのバグ再現リポジトリを作成して、Issueを報告していました。\n\n## textlint\n\n今年のtextlintは結構大きな変更がありました。\n\n### textlint v15\n\n6月にtextlint v15.0.0をリリースしました。\n\n * textlint v15.0.0をリリースしました。非推奨APIの削除とNode.js 20+サポート/MCPサーバの改善 | Web Scratch\n\n\n\nv14で非推奨にしていた`TextLintEngine`などの古いAPIを削除して、`createLinter()` への移行を完了しました。 Node.js 20以上が必須となり、コードベースがかなり整理されました。\n\n### MCPサーバー\n\nMCP(Model Context Protocol)サーバーをサポートしました。 v14.8.0で `--mcp` フラグを追加して、textlintをMCPサーバーとして起動できるようにしました。\n\n * textlint v14.8.0をリリースしました - MCP(Model Context Protocol)をサポート | Web Scratch\n\n\n\nAI Agentから直接textlintを呼び出せるようになりました。 テキストのチェックと修正を自動実行できるので、かなり便利になりました。\n\n### textlint-rule-preset-ai-writing\n\n新しいプリセット@textlint-ja/textlint-rule-preset-ai-writingも作りました。\n\nAI生成テキスト特有のパターンを検出するルール集で、機械的なリスト形式、誇張表現、コロン継続などを検出します。 AIがAI生成文章をチェックするというフィードバックループが実現できて面白いです。\n\n### インフラ改善\n\nパッケージマネージャーをnpmからpnpmに移行して、テストフレームワークもMochaからVitestに変更しました。 CI時間が21分5秒から7分20秒に短縮されました。\n\nnpm Trusted Publishing(OIDC)対応も完了して、トークンレスでnpmへのリリースができるようになりました。\n\n * npm Trusted PublishingでOIDCを使ってトークンレスでCIからnpmパッケージを公開する | Web Scratch\n\n\n\n## JavaScript Primer\n\n今年のJavaScript Primerは、ES2025の対応がメインでした。\n\n### v7.0.0\n\n8月にv7.0.0をリリースして、ECMAScript 2025に完全対応しました。\n\n * JavaScript Primer v7.0.0リリース: ES2025対応とIterator Helpersの新章追加 | Web Scratch\n\n\n\n新章「イテレータとジェネレータ」を追加して、Iterator Helpersを詳細に解説しています。\n\n * `Iterator.from()`\n * `.map()`、`.filter()`、`.take()`、`.drop()`、`.flatMap()`\n\n\n\nSet Methodsの解説も追加しました。`intersection()`、`union()`、`difference()`など7つのメソッドが使えるようになったので、Setの章を更新しています。\n\n他にも `RegExp.escape()` やImport Attributesの解説を追加しました。\n\n### Contributing Expenses Policy\n\n今年はContributing Expenses Policyを本格的に運用し始めました。\n\nES2025対応でコントリビュートしてくれた人には、Open Collective経由で報酬を支払うか、別のOSSプロジェクトへ寄付する仕組みにしています。 年間更新費用は約68万円と試算していて、これをどう継続的に回していくかが課題です。\n\n * JavaScript Primer - Open Collective\n\n\n\n## secretlint\n\n今年のsecretlintは、新しい検出ルールの追加とメジャーアップデートが中心でした。\n\n### v10とv11\n\n6月にv10.0.0、8月にv11.0.0をリリースしました。\n\n * Secretlint v10.0.0リリース: デフォルトでシークレットをマスク表示するように変更、Node.js 20+のサポート | Web Scratch\n\n\n\nv10ではデフォルトでシークレットをマスク表示するようにしました。 AIエージェントがstdoutを読むケースが増えてきたため、デフォルトをマスク表示に変更しました(#1067)。\n\n### 新しい検出ルール\n\nv11で2つの新ルールを推奨プリセットに追加しました。\n\n * @secretlint/secretlint-rule-anthropic\n * Claude APIキー(`sk-ant-api0\\d-...`パターン)を検出\n * @secretlint/secretlint-rule-database-connection-string\n * MongoDB等のデータベース接続文字列を検出\n\n\n\nv11.1.0では `@secretlint/secretlint-rule-pattern` に `filePathGlobs` オプションを追加しました。 ファイルパスのglob指定とコンテンツ検索を組み合わせられるようになっています。\n\n### インフラ改善\n\ntextlintと同様に、Yarn BerryからpnpmへのmigrationとMochaからVitestへのテストフレームワーク移行を完了しました。 npm Trusted Publishing対応も完了しています。\n\n## JSer.info\n\nJSer.infoは今年で14周年を迎えました。\n\n * JSer.info 14周年\n\n\n\n大体の週刊更新は継続していて、1月9日の#721号から12月末まで約40本の週刊記事を配信しました。(今年は結構ゆっくりペースでした)\n\n来月で15周年です。\n\n### MCPサーバー\n\n5月にJSer.info のMCPサーバーを公開しました。\n\n * https://mcp.jser.info/mcp\n\n\n\n`jser_search_items`、`jser_search_posts`、`jser_weeks`などのツールを用意して、AIエージェントがJSer.infoのデータへアクセスできるようになりました。 npmパッケージ@jser/mcpとしても配布しています。\n\nこれは、JSer.infoの更新フローが結構楽になったので、今後も継続的にメンテナンスしていきたいです。\n\n## TSKaigi 2025\n\n5月のTSKaigi 2025で「技術書をソフトウェア開発する - jsprimerの10年から学ぶ継続的メンテナンスの技術」という発表をしました。\n\n * TSKaigi 2025で「技術書をソフトウェア開発する」という発表をしました | Web Scratch\n * スライド: https://azu.github.io/slide/2025/tskaigi/jsprimer.html\n * 動画: https://www.youtube.com/watch?v=r5CZdn8IQlc\n\n\n\njsprimerを10年間メンテナンスし続けてきた方法を話しました。 技術書もソフトウェアと同じように、CIでテストしたり、依存関係を管理したり、リリースサイクルを回したりすることで継続できるという内容です。\n\n## YAPC::Fukuoka 2025\n\n11月のYAPC::Fukuoka 2025で「読む技術・書く技術・伝える技術 - 15年続けて分かった持続可能なオープンソース開発」という発表をしました。\n\n * YAPC::Fukuoka 2025で「読む技術・書く技術・伝える技術 - 15年続けて分かった持続可能なオープンソース開発」という発表をしました | Web Scratch\n * スライド: https://azu.github.io/slide/2025/yapc/opensource-15years.html\n\n\n\nJSer.info(14年)、textlint(11年)、JavaScript Primer(9年)という長期プロジェクトを題材に、バーンアウトを防ぐ開発手法を話しました。 メインのテーマは「心理的負荷を技術的依存に転換する」ということです。\n\n## 作ったリポジトリ\n\n今年作ったリポジトリは40個です。\n\n### ツール・ライブラリ\n\n * azu/confirm-pam\n * AI Agentのコマンド実行にTouch IDを使った「人間の確認」を挟むCLIツール confirm-pam を作った | Web Scratch\n * macOSのTouch ID認証をCLIから呼び出して、AIエージェントのコマンド実行前に人間の確認を求める「Human-in-the-loop」を実現するツール\n * Rustで実装してcrates.ioで公開\n * textlint-ja/textlint-rule-preset-ai-writing\n * AI生成テキスト特有のパターンを検出するtextlintプリセット\n * 機械的なリスト形式、誇張表現、コロン継続などを検出\n * 反響があった\n * textlint/vscode-textlint\n * VS Code拡張をtextlint orgに移管してメンテナンスを継続\n * azu/setup-npm-trusted-publish\n * npm Trusted Publishing(OIDC)を簡単に設定するためのヘルパーツール\n * READMEのみの初期パッケージを公開してOIDC設定できるようにする\n * jser/mcp\n * JSer.infoのMCPサーバー\n * AIエージェントがJSer.infoのデータへアクセスできるようにする\n * azu/intl-format-date\n * `Intl.DateTimeFormat`と`formatToParts`を使った日付フォーマットライブラリ\n * azu/madori\n * 間取り図エディタ\n * azu/humidifier-similator\n * 加湿器シミュレータ\n * azu/monorepo-npm-oidc-releases\n * pnpm + GitHub Release + npm OIDCでのモノレポリリースフローのサンプル\n * jser/jser-info-prompt\n * JSer.infoのプロンプト用データ\n\n\n\n### セキュリティ関連\n\nNext.jsのSecurity Issueやサプライチェーン攻撃について調べることが多かったです。\n\n * azu/nextjs-cve-2025-29927-poc\n * Next.jsのCVE-2025-29927(Middleware認証バイパス)のPoC\n * `X-Middleware-Subrequest`ヘッダを使ったMiddlewareバイパスの再現\n * azu/request-filtering-agent-https127-test\n * request-filtering-agentの127.0.0.1脆弱性のテスト\n\n\n\n### バグ再現・検証リポジトリ\n\n今年は検証用のリポジトリをたくさん作りました。\n\n**pnpm関連:**\n\n * azu/pnpm-10-with-postinstall-lifecyle - pnpm 10のpostinstall動作検証\n * azu/pnpm–frozen-lockfile-bug - `--frozen-lockfile`のバグ再現\n * pnpm catalogとdependabotの連携検証用リポジトリ(複数)\n\n\n\n**Panda CSS関連:**\n\n * azu/panda-css-vscode-example\n * azu/panda-css-eslint-demm - ESLintが数100回実行すると落ちるrace conditionバグの再現\n * azu/pandacss-nested-condition-bug - Panda CSSのMixed conditionsバグ\n * azu/no-physical-properties-text-align - `@pandacss/no-physical-properties`が`text-align: left`を許可してしまう問題\n\n\n\n**Next.js関連:**\n\n * azu/next-prefetch-txt-bug - .txtファイルへのナビゲーションバグ\n * azu/latest-next\n * azu/react-server-example\n\n\n\n**React Aria関連:**\n\n * azu/react-aria-reading-target-error - `Cannot read properties of undefined (reading 'target')`の再現\n * azu/react-aria-table-execption - 数100回実行すると落ちる例外をPlaywrightで再現するリポジトリ。結構大変だった\n\n\n\n**その他:**\n\n * azu/textlint-mcp-example - textlint MCPサーバーのデモ\n * azu/copilot-review-automerge - Copilotレビュー自動マージの検証\n * azu/base64-research - Base64の調査。サプライチェーン攻撃で検知逃れのためにBase64を3回エンコードするケースがあったので調べていた\n * azu/simple-oidc-example-package - npm Trusted PublishingでOIDCを使ってトークンレスでCIからnpmパッケージを公開するのサンプル\n\n\n\n## その他の更新\n\n * ni.zsh v1.8.0\n * ni.zsh v1.8.0リリース: Socket Firewallによるパッケージインストール時のチェック機能を追加 | Web Scratch\n * Socket Firewallと連携して、パッケージインストール時のサプライチェーン攻撃対策機能を追加しました\n * HonKit v6.1.4\n * npm Trusted Publishing対応を完了しました\n\n\n\n## サプライチェーン攻撃対策\n\n今年はサプライチェーン攻撃対策についてZennに記事をまとめました。\n\n * npmパッケージ/GitHub Actionsを利用する側/公開する側でサプライチェーン攻撃を防ぐためにやることメモ\n\n\n\n2024年後半から2025年にかけてサプライチェーン攻撃が増えてきていて、実際に影響を受けるケースも増えてきました。 自分が実際にやっている対策を紹介します。\n\n### 利用側での対策\n\n自分は主に次のような対策をしています。\n\n * GitHub Actionsのfull-length commit SHA Pin: pinactを使ってハッシュ固定し、zizmorでセキュリティチェック\n * pnpm 10でのLifecycle scriptsを無効化: デフォルトでオフになったので、`pnpm approve-script`で必要なパッケージのみ許可。\n * renovatebotの`minimumReleaseAge`設定: パッケージ公開後すぐにはアップデートしない\n * ni.zshでSocket Firewallと連携: パッケージインストール時に自動でスキャン\n\n\n\ntj-actions/changed-filesが侵害された件も調査していました。 SHA Pinをしていれば影響を受けなかったケースなので、SHA Pinは重要です。 `git config --global core.hooksPath`を使ってコミット時にデフォルトでpinactとzizmorを実行するようにしています。\n\n他にも細かい話は多いですが、細かい個人プロジェクトは更新をしやすくするために設定を冪等にできるようにすることを心がけています。ちゃんとしたプロジェクトはちゃんとした設定をしています。\n\n### 公開側での対策\n\ntextlint、secretlint、HonKitなどのプロジェクトでnpm Trusted Publishing(OIDC)対応を完了しました。 新規パッケージ公開時はazu/setup-npm-trusted-publishでOIDC設定をしています。 既存のnpmパッケージは`npm access set mfa=publish`を実行するスクリプトで一括設定してtokenでpublishできないようにしました。そのため、publishできるnpm tokenは全部revokeしました。 ローカルではOIDC設定をほとんど自動化するスクリプトを作って回しています。 やり方が変わっていくので冪等に設定できるという点を意識して作っています。\n\n * npm Trusted PublishingでOIDCを使ってトークンレスでCIからnpmパッケージを公開する | Web Scratch\n\n\n\nsecretlintでコミット時にシークレットをチェックし、ローカルには生tokenを置かずに1Passwordで管理しています。 GitHub Actionsのセキュリティチェックにはzizmorとactionlintを使っています。\n\n## 2025年を振り返って\n\n振り返ると3つの傾向がありました。\n\n1つ目はAI連携です。 textlintとJSer.infoへのMCPサーバー導入、AI生成テキスト検出ルール、confirm-pamによるAIエージェント安全機構と、複数プロジェクトでAI連携が進みました。 MCPはLSPと異なりエディタ拡張を作る必要がなく、ツール提供側がツールとして実装できるのが良い点です。 YAPCでも話しましたが、利用者にAI Agentが増えたことで、ツール側の責任範囲がシンプルになりました。\n\n2つ目はセキュリティです。 secretlintの新検出ルール、ni.zshのサプライチェーン攻撃対策、npm Trusted Publishing対応などを行いました。 GitHub/npm側もクラシックトークン作成の無効化やpull_request_targetのブランチ保護強化などbreaking changeな変更を入れています。 今年はセキュリティの基準が上がった年でした。\n\n3つ目は継続的なメンテナンスです。 JavaScript Primer v7.0.0でES2025に対応し、日本語で最新JavaScript仕様を学べる環境を維持しています。 また、TSKaigi 2025とYAPC::Fukuoka 2025で、継続的なメンテナンスについて発表しました。 「持続可能性を意識した設計」が今年もプロジェクト群を支え続けていますし、来年も引き続きやっていきたいです。\n\nYAPCの発表資料を作っているときにも感じましたが、こういった振り返りを書いておくと後で役立つので便利です。書くのは簡単になったけど、その土台になるデータやコンテンツはちゃんとメンテナンスして積み上げておく必要があるなと改めて思いました。",
"title": "オープンソース活動の振り返り/GitHub Sponsorsの収入まとめ @ 2025",
"updatedAt": "2025-12-31T05:10:00.000Z"
}