Skip to content

feat: 一括更新コマンド npm run update:all を追加 - #479

Merged
keito4 merged 4 commits into
mainfrom
feat/add-update-all-command
Feb 16, 2026
Merged

feat: 一括更新コマンド npm run update:all を追加#479
keito4 merged 4 commits into
mainfrom
feat/add-update-all-command

Conversation

@keito4

@keito4 keito4 commented Feb 16, 2026

Copy link
Copy Markdown
Owner

Summary

  • npm run update:actions を追加: GitHub Actions のバージョンを最新に自動更新(gh api でリリース/タグ取得)
  • npm run update:all を追加: libs / Claude Code / Actions の3種を一括更新するオーケストレーター
  • --skip-libs, --skip-claude, --skip-actions オプションで個別スキップ可能
  • Bats テスト 22 件追加(update_actions.bats: 11, update_all.bats: 11)

Test plan

  • ShellCheck 通過
  • ESLint 通過
  • Jest 101 tests 通過
  • Bats 新規 22 tests 通過
  • npm run update:actions 単体実行で動作確認
  • npm run update:all -- --skip-libs --skip-claude で Actions のみ更新確認

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Automated GitHub Actions version update functionality
    • Combined update command to manage Actions, Code, and dependencies simultaneously
    • New npm scripts for simplified version management
  • Documentation

    • Updated guides with GitHub Actions update procedures and best practices
  • Tests

    • Added integration test coverage for new update functionality

npm/Claude Code/GitHub Actions の3種の依存関係更新を一括実行できる
`update:all` コマンドと、GitHub Actions バージョン自動更新用の
`update:actions` コマンドを追加。--skip-* オプションで個別スキップ可能。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Feb 16, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@keito4 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 22 minutes and 41 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📝 Walkthrough

Walkthrough

This PR introduces automation for updating GitHub Actions to latest SemVer versions, along with a consolidated update-all orchestration script. New documentation, Bash scripts, and integration tests support the feature, with updated command references and expanded LSP guidance throughout the repo-maintenance guide.

Changes

Cohort / File(s) Summary
Documentation
.claude/commands/README.md, .claude/commands/repo-maintenance.md, .claude/commands/update-actions.md
Added comprehensive documentation for new update-actions command, consolidated update-all workflow, and expanded LSP setup guidance. Reorganized sections to include Actions version checking alongside existing Claude Code and dependency updates.
Update Scripts
script/update-actions.sh, script/update-all.sh
Introduced two new Bash scripts: update-actions.sh (210 lines) scans/filters GitHub Actions workflow files, fetches latest SemVer tags via GitHub CLI, and applies updates while skipping non-SemVer patterns; update-all.sh (132 lines) orchestrates sequential execution of library, Claude Code, and Actions updates with configurable skip flags and aggregated status reporting.
Configuration & Package
package.json
Added two npm scripts: update:actions and update:all invoking their respective Bash implementations.
Integration Tests
test/integration/update_actions.bats, test/integration/update_all.bats
Added comprehensive test suites (251 lines total) validating script executability, shell options, skip-flag handling, semver/SHA detection, GitHub CLI integration, and orchestration behavior.

Sequence Diagram

sequenceDiagram
    participant User
    participant update-all.sh
    participant update-libraries.sh
    participant update-claude-code.sh
    participant update-actions.sh

    User->>update-all.sh: npm run update:all [--skip-*]
    activate update-all.sh
    
    alt not --skip-libs
        update-all.sh->>update-libraries.sh: Execute
        activate update-libraries.sh
        update-libraries.sh-->>update-all.sh: [OK] or [FAIL]
        deactivate update-libraries.sh
    else --skip-libs
        update-all.sh-->>update-all.sh: Record [SKIP]
    end

    alt not --skip-claude
        update-all.sh->>update-claude-code.sh: Execute
        activate update-claude-code.sh
        update-claude-code.sh-->>update-all.sh: [OK] or [FAIL]
        deactivate update-claude-code.sh
    else --skip-claude
        update-all.sh-->>update-all.sh: Record [SKIP]
    end

    alt not --skip-actions
        update-all.sh->>update-actions.sh: Execute
        activate update-actions.sh
        update-actions.sh-->>update-all.sh: [OK] or [FAIL]
        deactivate update-actions.sh
    else --skip-actions
        update-all.sh-->>update-all.sh: Record [SKIP]
    end

    update-all.sh->>User: Summary + Exit Code
    deactivate update-all.sh
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

released

Poem

🐰 Actions flowing like carrots in spring,
Updates bundled with a hop and a swing!
SemVer tags dance, while SHAs do stay,
One script to rule them all—hip hooray! 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 53.85% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Merge Conflict Detection ⚠️ Warning ❌ Merge conflicts detected (5 files):

⚔️ .claude/commands/README.md (content)
⚔️ .claude/commands/repo-maintenance.md (content)
⚔️ .devcontainer/Dockerfile (content)
⚔️ npm/global.json (content)
⚔️ package.json (content)

These conflicts must be resolved before merging into main.
Resolve conflicts locally and push changes to this branch.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'feat: 一括更新コマンド npm run update:all を追加' accurately and specifically summarizes the main change: adding a bulk update command npm run update:all.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/add-update-all-command

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@keito4

keito4 commented Feb 16, 2026

Copy link
Copy Markdown
Owner Author

🔍 AI Code Review (Local Hook)

Models: Codex (default) / Gemini (default)

🤖 Codex Review

指摘事項

  • script/update-actions.sh:179-183 sed -i '' は BSD sed 専用で、GNU sed(Linux)ではエラーになります。CI や Linux 環境で実行すると更新処理が即失敗するため、実行環境に依存してスクリプトが動作しない不具合です。sed -i の分岐(BSD/GNU判定)か perl -pi -e などの移植性の高い方法に置き換える必要があります。

判定: patch is incorrect
理由: 追加された更新スクリプトが一般的な Linux 環境で動作せず、実行時に確実に失敗するため。
信頼度: 0.37


⚠️ 修正が必要です

上記のレビューで問題が指摘されています。修正してからマージしてください。


🤖 Generated by post_pr_ai_review.py hook

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7d4ceb4cb5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread script/update-actions.sh
# 全ワークフローファイルで置換
escaped_action=$(escape_sed "$full_action")
for wf in "${workflow_files[@]}"; do
sed -i '' "s|\(uses:.*\)${escaped_action}@${current_ref}|\1${escaped_action}@${new_ref}|g" "$wf"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Use portable sed in-place syntax for workflow rewrites

The rewrite loop calls sed -i '' ..., which is BSD/macOS-specific; on GNU sed (used in typical Linux CI/devcontainer runs), -i is documented as -i[SUFFIX], so passing a separate empty argument makes sed treat the substitution as an input filename and fail (sed: can't read ...). This means update-actions.sh exits as soon as it hits an action that needs updating, so npm run update:actions (and the update:all step) cannot perform updates in Linux environments.

Useful? React with 👍 / 👎.

@claude

claude Bot commented Feb 16, 2026

Copy link
Copy Markdown
Contributor

PR レビュー: 一括更新コマンド npm run update:all

総合評価: ✅ 優秀

全体的に非常に高品質な実装です。コード規約、エラーハンドリング、テストカバレッジのすべてが優れています。


✅ 良い点

1. 堅牢なエラーハンドリング

  • set -euo pipefail による厳格なエラー処理
  • set +e / set -e による個別ステップの失敗分離(update-all.sh:62-65, 80-84, 100-103)
  • 各ステップの終了コードを記録し、最終サマリで一括報告

2. 包括的なテストカバレッジ

  • 22個の新規Batsテストで全ロジックを検証
  • 関数単位の動作検証(is_sha_pin, is_semver_tag, normalize_tag)
  • エッジケース対応(v prefix有無、SHA/branch/major-onlyのスキップ)

3. 優れたユーザビリティ

  • カラー出力による視認性向上
  • --skip-* オプションによる柔軟な実行制御
  • 詳細なサマリ表示(更新/スキップを明確に区別)

4. セキュリティ配慮

  • sed メタ文字エスケープ(update-actions.sh:34-36)
  • GitHub API経由でのバージョン取得(信頼できるソース)
  • ローカルアクション(./)や docker:// のスキップ

5. 保守性の高い設計

  • 重複処理の排除(processed_actions連想配列)
  • 明確な関数分割(単一責任原則)
  • コメントによる意図の明示化

🔍 改善提案(Critical ではない)

1. macOS固有のsed構文(update-actions.sh:182)

現在 sed -i '' ... はmacOS専用の構文です。Linux環境での動作を保証するため、OS検出による分岐処理を検討してください。

2. Rate Limit対策の検討

全アクションに対して即座に gh api を実行するため、アクション数が多い場合にAPIレート制限に達する可能性があります。429エラー検出とリトライ処理の追加を検討してください。


🧪 テスト実行結果の確認

Test planの未完了項目:

  • npm run update:actions 単体実行で動作確認
  • npm run update:all -- --skip-libs --skip-claude で Actions のみ更新確認

マージ前にこれらの実行ログを確認することをお勧めします。


🔐 セキュリティ: ✅ 問題なし

  • 外部入力の適切なエスケープ
  • 信頼できるAPI(GitHub)のみ使用
  • 資格情報の漏洩リスクなし

🎯 結論: マージ推奨 ✅

この実装は以下の点で優れています:

  1. ✅ CLAUDE.mdの品質基準を満たしている
  2. ✅ 包括的なテストカバレッジ(22個の新規テスト)
  3. ✅ 全CIチェック通過
  4. ✅ エラーハンドリングが堅牢
  5. ✅ セキュリティリスクなし

改善提案は全てオプショナルであり、現状でも十分にプロダクション品質です。


レビュー済み by Claude Sonnet 4.5 | 日付: 2026-02-16

github-actions Bot and others added 2 commits February 16, 2026 17:14
- .claude/commands/update-actions.md を新規作成
- README.md の Quick Reference と Scripts テーブルに追加
- repo-maintenance.md に GitHub Actions 更新ステップ (2.5) を追加

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
update-claude-code と update-actions を Development Environment から
独立した Updates セクションに移動し、update:all の使い方を追加。
Quick Reference テーブルのカテゴリ構造と整合性を確保。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@claude

claude Bot commented Feb 16, 2026

Copy link
Copy Markdown
Contributor

PR Review: npm run update:all 一括更新コマンド追加

このPRを詳細にレビューしました。全体的に高品質な実装です。


✅ 良い点

1. 堅牢なエラーハンドリング

  • set -euo pipefail による厳格なエラー処理
  • gh コマンドの存在チェック (update-actions.sh:26-29)
  • 各ステップの exit code を個別に捕捉 (update-all.sh:62-73, 81-92, 100-111)

2. 適切なバージョン判定ロジック

  • SemVer タグの判定が正確 (^v?[0-9]+.[0-9]+(.[0-9]+)?$)
  • SHA ピンニング (40文字hex) を正しくスキップ
  • メジャータグ固定 (v1, v3) やブランチ固定 (main, master) を適切に除外

3. v prefix 正規化の実装

  • 現在のタグの v prefix 有無に合わせて最新タグを調整 (update-actions.sh:75-90)
  • 既存の命名規則を維持

4. 重複排除の実装

  • processed_actions 連想配列で同一アクション+バージョンの重複処理を防止 (update-actions.sh:155-159)

5. 包括的なテストカバレッジ

  • Bats テスト 22 件追加 (update_actions.bats: 11, update_all.bats: 11)
  • 境界値テスト、オプション解析、エラーハンドリングをカバー

6. ユーザビリティ

  • カラー出力による視認性向上
  • --skip-* オプションによる柔軟な実行制御
  • 更新サマリの表示

⚠️ 改善提案

1. macOS 依存の sed -i オプション (重要度: 高)

問題箇所: update-actions.sh:182

sed -i のオプションが macOS 専用になっています。Linux では動作しません。

修正案 (クロスプラットフォーム対応):

if [[ "$(uname)" == "Darwin" ]]; then
  sed -i '' "s|..." "$wf"
else
  sed -i "s|..." "$wf"
fi

または一時ファイル使用:

sed "s|..." "$wf" > "${wf}.tmp" && mv "${wf}.tmp" "$wf"

2. API レート制限への対応 (重要度: 中)

問題箇所: update-actions.sh:51-72

多数のアクションがある場合、gh api 呼び出しが連続すると GitHub API のレート制限に到達する可能性があります。

改善案:

  • エラー時に 403 応答をチェックし、レート制限の警告を表示
  • 処理済みの owner/repo をキャッシュして同一リポジトリへの重複APIコールを削減

3. sed エスケープの不完全性 (重要度: 中)

問題箇所: update-actions.sh:34-36

アクション名に ] や & が含まれる場合のエスケープが不足しています。

4. サブパス抽出の edge case (重要度: 低)

問題箇所: update-actions.sh:146-152

slash_count が 0 の場合 (不正な形式) のハンドリングがありません。

5. Test Plan の未完了項目

PR の Test Plan に以下のチェックボックスが未チェック:

  • npm run update:actions 単体実行で動作確認
  • npm run update:all -- --skip-libs --skip-claude で Actions のみ更新確認

推奨: CI が通過していても、手動での動作確認を実施してチェックを完了させることをお勧めします。


🔒 セキュリティ

  • ✅ 認証情報の漏洩リスクなし
  • ✅ コマンドインジェクションのリスクは低い (変数のクォート適切)
  • ✅ SHA ピンニングの保持 (セキュリティ重視のプロジェクトへの配慮)

📈 パフォーマンス

  • ⚠️ 多数のアクションがある場合、API コールが多くなる可能性
  • ✅ 重複排除により無駄な処理は削減済み
  • ✅ || true によるエラー時の継続処理で、一部失敗しても全体が止まらない

📚 ドキュメント

  • ✅ .claude/commands/update-actions.md の追加
  • ✅ README.md への Quick Reference 追加
  • ✅ repo-maintenance.md への統合
  • 優れたドキュメント構成

🎯 総評

評価: 8.5/10

この PR は全体的に高品質で、以下の点が特に優れています:

  • エラーハンドリングの徹底
  • 包括的なテストカバレッジ
  • ユーザビリティへの配慮

マージ判断:

  • Critical Issue: sed -i の macOS 依存性は Linux 環境で動作しないため、修正が必須
  • その他の改善提案は Nice-to-have

推奨アクション:

  1. sed -i のクロスプラットフォーム対応を実装
  2. 修正後、DevContainer 環境 (Linux) で動作確認
  3. Test Plan の未完了項目を確認
  4. その後マージ

📋 チェックリスト

  • ✅ コード品質: 高
  • ✅ ベストプラクティス: 準拠
  • ⚠️ 互換性: sed の macOS 依存
  • ✅ テストカバレッジ: 包括的
  • ✅ セキュリティ: 問題なし
  • ✅ ドキュメント: 充実

優れた実装をありがとうございます! sed -i の問題を修正すれば、すぐにマージ可能な状態です。

🤖 Generated by Claude Sonnet 4.5

- actions/setup-node: v6.1.0 → v6.2.0
- zaproxy/action-baseline: v0.14.0 → v0.15.0

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In @.claude/commands/README.md:
- Around line 483-503: The two fenced code blocks showing the commands
"/update-claude-code" and the block containing "/update-actions\nnpm run
update:actions" are missing language specifiers; update those three backticks to
use "bash" (i.e., change ``` to ```bash) so they match other examples and
satisfy markdownlint MD040, making sure to update both the single-line
"/update-claude-code" block and the two-line "/update-actions" block.

In `@script/update-actions.sh`:
- Around line 34-36: The escape_sed function currently fails to escape the sed
replacement metacharacter '&', so update the function (escape_sed) to also
escape '&' in its character class used by sed (i.e., include & inside the
bracket expression alongside . [ \ / * ^ $ ) so any '&' in the input is
backslash-escaped before being passed to sed; keep the same approach of printf
'%s' "$1" | sed 's/.../\\&/g' but add '&' to the set of characters to be
escaped.
- Around line 63-69: The current fallback uses the gh API call
"repos/${owner_repo}/tags?per_page=1" to set the variable tag which returns the
most recently created tag (not the highest SemVer) and can cause downgrades;
update the fallback in script/update-actions.sh to fetch multiple tags (e.g.,
increase per_page and handle pagination) and select the highest SemVer name
rather than the first returned value—collect tag names from the gh api response,
filter/normalize versions (variable tag), and pick the max using a SemVer-aware
comparator (e.g., sort -V or a semver library) before echoing and returning.
- Around line 179-183: The sed invocation using "sed -i ''" is macOS-only and
breaks on GNU/Linux; update the loop that uses escaped_action, workflow_files,
current_ref, and new_ref to perform a portable in-place replace (e.g., write
sed's output to a temp file and then mv it back) instead of relying on the
BSD-specific "-i ''" flag so the script works on both macOS and Linux CI
environments.
🧹 Nitpick comments (3)
script/update-actions.sh (1)

92-96: find | tr '\n' '\0' is less robust than find -print0.

Using tr '\n' '\0' breaks on filenames containing literal newlines (admittedly unlikely for workflow files). The standard idiom is find ... -print0:

♻️ Proposed fix
 workflow_files=()
 while IFS= read -r -d '' file; do
   workflow_files+=("$file")
-done < <(find "${WORKFLOWS_DIR}" -name '*.yml' -o -name '*.yaml' | tr '\n' '\0')
+done < <(find "${WORKFLOWS_DIR}" \( -name '*.yml' -o -name '*.yaml' \) -print0)
test/integration/update_all.bats (2)

23-84: Skip-flag tests exercise a copy of the logic, not the actual script.

The --skip-* tests create standalone scripts that reimplement the option-parsing loop from update-all.sh. If the real script's parsing changes (e.g., renaming a flag, switching to getopts), these tests will still pass. Consider sourcing or directly running update-all.sh --help / update-all.sh --skip-libs --skip-claude --skip-actions (with the sub-scripts stubbed out) to test the actual code path.


13-15: Most tests are grep-based structural checks rather than behavioral tests.

Tests like "has set -euo pipefail" or "contains step_results" verify that certain strings exist in the source file, not that the script behaves correctly. This provides minimal regression protection. Consider adding at least one end-to-end test that runs update-all.sh with all three steps skipped (which should succeed quickly without external dependencies) and asserts on the output/exit code.

Also applies to: 86-107

Comment on lines +483 to +503
**Usage**:

```
/update-claude-code
```

#### `update-actions.md`

**Purpose**: Update GitHub Actions to the latest versions
**Features**:

- `.github/workflows/` 配下の全ワークフローファイルをスキャン
- SemVer タグのアクションを最新バージョンに更新
- メジャータグ固定・SHA ピンニング・ブランチ固定はスキップ

**Usage**:

```
/update-actions
npm run update:actions
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add language specifiers to fenced code blocks (markdownlint MD040).

The code blocks at lines 485 and 500 are missing language identifiers, which is flagged by markdownlint. Other code blocks in this file consistently use bash — these should match.

♻️ Proposed fix
 **Usage**:

-```
+```bash
 /update-claude-code

```diff
-```
+```bash
 /update-actions
 npm run update:actions
</details>

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 markdownlint-cli2 (0.20.0)</summary>

[warning] 485-485: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

---

[warning] 500-500: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

</details>

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

In @.claude/commands/README.md around lines 483 - 503, The two fenced code
blocks showing the commands "/update-claude-code" and the block containing
"/update-actions\nnpm run update:actions" are missing language specifiers;
update those three backticks to use "bash" (i.e., change tobash) so they
match other examples and satisfy markdownlint MD040, making sure to update both
the single-line "/update-claude-code" block and the two-line "/update-actions"
block.


</details>

<!-- fingerprinting:phantom:medusa:phoenix -->

<!-- This is an auto-generated comment by CodeRabbit -->

Comment thread script/update-actions.sh
Comment on lines +34 to +36
escape_sed() {
printf '%s' "$1" | sed 's/[.[\/*^$]/\\&/g'
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

escape_sed omits &, which is a sed replacement metacharacter.

The & character in a sed replacement string expands to the entire matched text. While unlikely to appear in a GitHub Action name, adding it to the character class makes the function correct in general.

🛡️ Proposed fix
 escape_sed() {
-  printf '%s' "$1" | sed 's/[.[\/*^$]/\\&/g'
+  printf '%s' "$1" | sed 's/[&.[\/*^$]/\\&/g'
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
escape_sed() {
printf '%s' "$1" | sed 's/[.[\/*^$]/\\&/g'
}
escape_sed() {
printf '%s' "$1" | sed 's/[&.[\/*^$]/\\&/g'
}
🤖 Prompt for AI Agents
In `@script/update-actions.sh` around lines 34 - 36, The escape_sed function
currently fails to escape the sed replacement metacharacter '&', so update the
function (escape_sed) to also escape '&' in its character class used by sed
(i.e., include & inside the bracket expression alongside . [ \ / * ^ $ ) so any
'&' in the input is backslash-escaped before being passed to sed; keep the same
approach of printf '%s' "$1" | sed 's/.../\\&/g' but add '&' to the set of
characters to be escaped.

Comment thread script/update-actions.sh
Comment on lines +63 to +69
# フォールバック: 最新タグを取得
tag=$(gh api "repos/${owner_repo}/tags?per_page=1" --jq '.[0].name' 2>/dev/null) || true

if [[ -n "$tag" ]]; then
echo "$tag"
return 0
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Tags fallback may return a non-latest SemVer tag.

The /tags?per_page=1 endpoint returns the most recently created tag, not the highest SemVer version. If a maintainer back-ports a fix to an older major version (e.g., pushes v3.1.1 after v4.0.0 already exists), this fallback would return v3.1.1 and potentially downgrade an action.

Consider sorting tags by SemVer or fetching more tags and selecting the highest:

🔧 Proposed improvement
   # フォールバック: 最新タグを取得
-  tag=$(gh api "repos/${owner_repo}/tags?per_page=1" --jq '.[0].name' 2>/dev/null) || true
+  tag=$(gh api "repos/${owner_repo}/tags?per_page=100" --jq '[.[].name | select(test("^v?[0-9]+\\.[0-9]+\\.[0-9]+$"))] | sort_by(split(".") | map(ltrimstr("v") | tonumber)) | last' 2>/dev/null) || true
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# フォールバック: 最新タグを取得
tag=$(gh api "repos/${owner_repo}/tags?per_page=1" --jq '.[0].name' 2>/dev/null) || true
if [[ -n "$tag" ]]; then
echo "$tag"
return 0
fi
# フォールバック: 最新タグを取得
tag=$(gh api "repos/${owner_repo}/tags?per_page=100" --jq '[.[].name | select(test("^v?[0-9]+\\.[0-9]+\\.[0-9]+$"))] | sort_by(split(".") | map(ltrimstr("v") | tonumber)) | last' 2>/dev/null) || true
if [[ -n "$tag" ]]; then
echo "$tag"
return 0
fi
🤖 Prompt for AI Agents
In `@script/update-actions.sh` around lines 63 - 69, The current fallback uses the
gh API call "repos/${owner_repo}/tags?per_page=1" to set the variable tag which
returns the most recently created tag (not the highest SemVer) and can cause
downgrades; update the fallback in script/update-actions.sh to fetch multiple
tags (e.g., increase per_page and handle pagination) and select the highest
SemVer name rather than the first returned value—collect tag names from the gh
api response, filter/normalize versions (variable tag), and pick the max using a
SemVer-aware comparator (e.g., sort -V or a semver library) before echoing and
returning.

Comment thread script/update-actions.sh
Comment on lines +179 to +183
# 全ワークフローファイルで置換
escaped_action=$(escape_sed "$full_action")
for wf in "${workflow_files[@]}"; do
sed -i '' "s|\(uses:.*\)${escaped_action}@${current_ref}|\1${escaped_action}@${new_ref}|g" "$wf"
done

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

sed -i '' is BSD-only and will fail on GNU/Linux (including CI).

As flagged in the PR comments, sed -i '' is macOS/BSD-specific syntax. On GNU sed (Linux), -i requires the extension to be part of the same argument (e.g., sed -i'') or omitted entirely (sed -i). Passing '' as a separate argument causes GNU sed to misinterpret it as the script.

Use a portable alternative:

🐛 Proposed fix — portable in-place sed
       # 全ワークフローファイルで置換
       escaped_action=$(escape_sed "$full_action")
       for wf in "${workflow_files[@]}"; do
-        sed -i '' "s|\(uses:.*\)${escaped_action}@${current_ref}|\1${escaped_action}@${new_ref}|g" "$wf"
+        if sed --version 2>/dev/null | grep -q 'GNU'; then
+          sed -i "s|\(uses:.*\)${escaped_action}@${current_ref}|\1${escaped_action}@${new_ref}|g" "$wf"
+        else
+          sed -i '' "s|\(uses:.*\)${escaped_action}@${current_ref}|\1${escaped_action}@${new_ref}|g" "$wf"
+        fi
       done

Alternatively, a single-line portable approach that works on both:

-        sed -i '' "s|\(uses:.*\)${escaped_action}@${current_ref}|\1${escaped_action}@${new_ref}|g" "$wf"
+        perl -pi -e "s|\Quses:.*?\E\Q${full_action}\E\@\Q${current_ref}\E|uses: ${full_action}\@${new_ref}|g" "$wf"

Or the common temp-file idiom:

-        sed -i '' "s|\(uses:.*\)${escaped_action}@${current_ref}|\1${escaped_action}@${new_ref}|g" "$wf"
+        sed "s|\(uses:.*\)${escaped_action}@${current_ref}|\1${escaped_action}@${new_ref}|g" "$wf" > "${wf}.tmp" && mv "${wf}.tmp" "$wf"
🤖 Prompt for AI Agents
In `@script/update-actions.sh` around lines 179 - 183, The sed invocation using
"sed -i ''" is macOS-only and breaks on GNU/Linux; update the loop that uses
escaped_action, workflow_files, current_ref, and new_ref to perform a portable
in-place replace (e.g., write sed's output to a temp file and then mv it back)
instead of relying on the BSD-specific "-i ''" flag so the script works on both
macOS and Linux CI environments.

@claude

claude Bot commented Feb 16, 2026

Copy link
Copy Markdown
Contributor

PR Review - #479

📋 概要

GitHub Actions の自動バージョン更新機能と、全依存関係を一括更新する統合コマンドの追加です。CI は全て通過しており、22 件の新規テストも追加されています。


✅ Good Points

1. コード品質

  • エラーハンドリング: set -euo pipefail が適切に使用されている (script/update-actions.sh:7, script/update-all.sh:7)
  • ロバスト性:
    • get_latest_tag 関数でリリース取得失敗時のフォールバック処理 (script/update-actions.sh:56-71)
    • 各ステップの結果を記録し、失敗時も継続実行 (script/update-all.sh:62-110)
  • 重複排除: processed_actions 連想配列で同一アクション+バージョンの重複処理を防止 (script/update-actions.sh:106-159)

2. 機能設計

  • 適切なスキップロジック:
    • SHA ピンニング (script/update-actions.sh:127-129)
    • メジャータグ固定 (script/update-actions.sh:132-134)
    • ブランチ固定 (script/update-actions.sh:137-139)
    • ローカル/Docker アクション (script/update-actions.sh:122-124)
  • v prefix 正規化: 既存タグの形式を保持する賢い処理 (script/update-actions.sh:75-90)
  • 柔軟な更新制御: --skip-* オプションで個別スキップ可能 (script/update-all.sh:28-47)

3. テストカバレッジ

  • 22 件の新規テスト: update_actions.bats (11件) + update_all.bats (11件)
  • ロジック検証:
    • SHA/メジャータグ/SemVer の判定ロジック (test/integration/update_actions.bats:27-89)
    • v prefix 正規化 (test/integration/update_actions.bats:103-132)
    • オプション解析 (test/integration/update_all.bats:23-83)

4. ドキュメント

  • 包括的なドキュメント: .claude/commands/update-actions.md で使用方法、判定ロジック、必須コマンドを明記
  • README 更新: Quick Reference テーブルと Scripts テーブルに新規コマンドを追加
  • repo-maintenance 統合: 保守コマンドに GitHub Actions 更新ステップを追加

🔍 Potential Issues & Suggestions

1. 🟡 Portability Issue (Medium)

問題: sed -i '' が macOS 専用構文

# script/update-actions.sh:182
sed -i '' "s|\(uses:.*\)${escaped_action}@${current_ref}|\1${escaped_action}@${new_ref}|g" "$wf"

影響: Linux 環境 (CI/CD, DevContainer) で実行するとエラー

推奨対応:

# OS 判定で分岐
if [[ "$(uname)" == "Darwin" ]]; then
  sed -i '' "s|pattern|replacement|g" "$file"
else
  sed -i "s|pattern|replacement|g" "$file"
fi

または

# 一時ファイル経由で OS 非依存に
sed "s|pattern|replacement|g" "$file" > "${file}.tmp" && mv "${file}.tmp" "$file"

2. 🟡 Rate Limit Risk (Medium)

問題: 大量のアクションを処理する際、GitHub API のレート制限に抵触する可能性

# script/update-actions.sh:162
latest_tag=$(get_latest_tag "$local_owner_repo") || true

推奨対応:

  • レート制限チェック追加
  • バッチ処理時の遅延挿入
# レート制限確認
rate_remaining=$(gh api rate_limit --jq '.rate.remaining')
if [[ $rate_remaining -lt 10 ]]; then
  log_warn "GitHub API レート制限が近づいています (残り: $rate_remaining)"
  sleep 60
fi

3. 🟢 Documentation Clarity (Low)

問題: update:all の実行順序が重要だが、明示されていない

推奨追加:

## 実行順序

1. npm 依存関係更新 (update:libs)
2. Claude Code 更新 (update:claude)
3. GitHub Actions 更新 (update:actions)

※ 各ステップは独立実行され、一部失敗しても後続ステップは継続されます

4. 🟢 Test Enhancement (Low)

問題: 実際の GitHub Actions ファイルを使用した E2E テストがない

推奨追加:

@test "update-actions.sh updates actual workflow files" {
  # テンプレートファイルをコピーしてテスト
  cp "${REPO_ROOT}/.github/workflows/templates/unified-ci.yml" "${TEST_TEMP_DIR}/test.yml"
  
  # 意図的に古いバージョンに変更
  sed -i "s|actions/setup-node@v6.2.0|actions/setup-node@v6.1.0|g" "${TEST_TEMP_DIR}/test.yml"
  
  # update-actions.sh 実行
  # ...
  
  # 更新されたことを確認
  grep -q "actions/setup-node@v6.2.0" "${TEST_TEMP_DIR}/test.yml"
}

🔐 Security Considerations

✅ Good

  • 資格情報なし: スクリプトはハードコードされた認証情報を含まない
  • gh CLI 使用: GitHub API への安全なアクセス
  • 入力検証: 不明なオプション検出 (script/update-all.sh:43-46)

⚠️ Considerations

  • gh 認証: スクリプト実行前に gh auth status で認証確認が推奨
  • sed 実行: エスケープ処理 (escape_sed) で悪意ある入力対策済み

📊 Performance Considerations

潜在的なボトルネック

  1. API 呼び出し: アクション数 × ワークフローファイル数に比例
  2. ファイル I/O: 全ワークフローファイルを複数回走査

パフォーマンス影響

  • 小規模リポジトリ (5-10 アクション): ~10-20 秒
  • 大規模リポジトリ (50+ アクション): ~2-5 分 (API レート制限次第)

📝 Test Plan Review

✅ 完了済み

  • ShellCheck 通過
  • ESLint 通過
  • Jest 101 tests 通過
  • Bats 新規 22 tests 通過

⏳ 未完了 (PR 本文より)

  • npm run update:actions 単体実行で動作確認
  • npm run update:all -- --skip-libs --skip-claude で Actions のみ更新確認

推奨: マージ前に実際の環境で上記 2 点を手動実行し、動作確認結果をコメント追加


🎯 Overall Assessment

カテゴリ 評価 コメント
コード品質 ⭐⭐⭐⭐⭐ エラーハンドリング、ロバスト性、可読性が優秀
テストカバレッジ ⭐⭐⭐⭐☆ ロジック検証は十分だが、E2E テスト追加で完璧に
ドキュメント ⭐⭐⭐⭐⭐ 包括的で分かりやすい
セキュリティ ⭐⭐⭐⭐☆ 問題なし、認証確認追加で万全
パフォーマンス ⭐⭐⭐⭐☆ レート制限対策追加で改善可能
総合評価 ⭐⭐⭐⭐☆ 優秀な実装。sed -i の portability 修正のみ必須対応

🚀 Recommendation

Approve with Suggestions

必須対応 (Blocking)

  1. sed -i '' の portability 修正 → Linux/macOS 両対応に

推奨対応 (Non-blocking)

  1. GitHub API レート制限チェック追加
  2. 実行順序のドキュメント明記
  3. E2E テスト追加
  4. gh auth status 前提条件の明記

📌 Additional Notes

CI/CD Integration

このコマンドは .github/workflows/update-libraries.yml に統合される予定でしょうか?統合する場合:

  • スケジュール実行 (週次/月次)
  • 自動 PR 作成
  • レビュアー自動アサイン

を検討すると良いでしょう。

Conventional Commits

コミットメッセージが feat: で始まっており、semantic-release でマイナーバージョンがリリースされます。想定通りかと思いますが、確認推奨です。


素晴らしい実装です!特に:

  • 包括的なスキップロジック
  • v prefix 正規化の賢い処理
  • 失敗時も継続実行する orchestrator 設計

が秀逸です。sed -i の修正後、安心してマージできる品質です 👍

🤖 Generated with Claude Code

@keito4
keito4 merged commit bf1e6d7 into main Feb 16, 2026
18 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 1.75.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

released リリース済み

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant