操作
Wiki » 履歴 » リビジョン 1
リビジョン 1/4
| 次 »
廣瀬 僚一, 2026/06/01 17:05
MainWP 更新履歴 Redmine 自動連携¶
概要¶
MainWP でプラグイン・テーマ・WordPress 本体を更新した際に、Redmine へ自動でチケットを作成する仕組み。
- 対象サーバー: MainWP ダッシュボードサーバー
- 方式: MU-Plugins に WordPress フックを記述し、Redmine REST API へ直接 POST
- WP Webhooks プラグインは不使用(Basic 認証・IP 制限の影響を避けるため)
ファイル構成¶
/wp-content/mu-plugins/mainwp-webhook.php ← メインファイル
/wp-content/mainwp-redmine-debug.log ← デバッグログ(確認後削除可)
設置ファイル¶
/wp-content/mu-plugins/mainwp-webhook.php¶
<?php
/**
* MainWP更新後にRedmineへ直接通知
* 設置場所: /wp-content/mu-plugins/mainwp-webhook.php
*/
define( 'REDMINE_URL', 'https://your-redmine.example.com' );
define( 'REDMINE_API_KEY', 'YOUR_REDMINE_API_KEY' );
define( 'REDMINE_PROJECT', 'wordpress-updates' );
// ===== プラグイン・テーマ・翻訳の更新後 =====
add_action( 'mainwp_install_update_actions', function( $website, $action, $data, $type ) {
if ( 'updated' !== $action ) return;
if ( ! in_array( $type, array( 'plugin', 'theme', 'trans' ) ) ) return;
$type_label = [
'plugin' => 'プラグイン',
'theme' => 'テーマ',
'trans' => '翻訳',
][ $type ] ?? $type;
$site = $website->url ?? '不明';
$datetime = ( new DateTime( 'now', new DateTimeZone( 'Asia/Tokyo' ) ) )->format( 'Y-m-d H:i:s' );
// WPバージョン取得
$site_info = json_decode( $website->site_info ?? '{}', true );
$wp_version = $site_info['wpversion'] ?? '不明';
// 更新内容を取得
$updated_data = isset( $data['updated_data'] ) ? $data['updated_data'] : array();
$details = '';
if ( is_array( $updated_data ) && ! empty( $updated_data ) ) {
foreach ( $updated_data as $item ) {
$name = $item['name'] ?? $item['slug'] ?? '不明';
$old = $item['old_version'] ?? '?';
$new = $item['version'] ?? '?';
$details .= "- {$name}: {$old} → {$new}\n";
}
}
if ( empty( $details ) ) return;
$subject = "[WP更新] {$site} / {$type_label}";
$body = "## 更新情報\n\n"
. "- **サイト:** {$site}\n"
. "- **種別:** {$type_label}\n"
. "- **WPバージョン:** {$wp_version}\n"
. "- **作業日時:** {$datetime}\n\n"
. "## 更新内容\n\n{$details}";
mainwp_post_to_redmine( $subject, $body );
}, 10, 4 );
// ===== WordPress本体の更新後 =====
add_action( 'mainwp_after_wp_update', function( $information, $website ) {
$site = $website->url ?? '不明';
$datetime = ( new DateTime( 'now', new DateTimeZone( 'Asia/Tokyo' ) ) )->format( 'Y-m-d H:i:s' );
// wp_upgradesから更新前後バージョンを取得
$wp_upgrades = json_decode( $website->wp_upgrades ?? '{}', true );
$old = $wp_upgrades['current'] ?? $information['old_version'] ?? '?';
$new = $wp_upgrades['new'] ?? $information['new_version'] ?? '?';
$subject = "[WP更新] {$site} / WordPress本体";
$body = "## 更新情報\n\n"
. "- **サイト:** {$site}\n"
. "- **種別:** WordPress本体\n"
. "- **更新前:** {$old}\n"
. "- **更新後:** {$new}\n"
. "- **作業日時:** {$datetime}\n";
mainwp_post_to_redmine( $subject, $body );
}, 10, 2 );
// ===== Redmine API へ直接POST =====
function mainwp_post_to_redmine( $subject, $body ) {
$data = [
'issue' => [
'project_id' => REDMINE_PROJECT,
'subject' => $subject,
'description' => $body,
'tracker_id' => 2,
'status_id' => 5, // 終了
'done_ratio' => 100,
]
];
$ch = curl_init( REDMINE_URL . '/issues.json' );
curl_setopt_array( $ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode( $data ),
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'X-Redmine-API-Key: ' . REDMINE_API_KEY,
],
CURLOPT_TIMEOUT => 15,
] );
$response = curl_exec( $ch );
$status = curl_getinfo( $ch, CURLINFO_HTTP_CODE );
curl_close( $ch );
// デバッグログ(確認後削除してOK)
file_put_contents(
WP_CONTENT_DIR . '/mainwp-redmine-debug.log',
date('Y-m-d H:i:s') . " status={$status} response={$response}\n",
FILE_APPEND
);
}
設定値¶
| 定数 | 説明 |
|---|---|
REDMINE_URL |
Redmine の URL(末尾スラッシュなし) |
REDMINE_API_KEY |
Redmine の個人 API キー(マイアカウント画面で確認) |
REDMINE_PROJECT |
Redmine のプロジェクト識別子 |
Redmine チケット設定¶
| 項目 | 値 | 説明 |
|---|---|---|
tracker_id |
2 |
トラッカー ID(環境に合わせて変更) |
status_id |
5 |
終了ステータス |
done_ratio |
100 |
進捗率 100% |
動作する WordPress フック¶
| フック名 | タイミング | 引数 |
|---|---|---|
mainwp_install_update_actions |
プラグイン・テーマ・翻訳の更新後 | $website, $action, $data, $type |
mainwp_after_wp_update |
WordPress 本体の更新後 | $information, $website |
バージョン情報の取得元¶
| 情報 | 取得元 |
|---|---|
| プラグイン更新前バージョン | $data['updated_data'][]['old_version'] |
| プラグイン更新後バージョン | $data['updated_data'][]['version'] |
| WP バージョン |
$website->site_info の wpversion
|
| WP 本体更新前バージョン |
$website->wp_upgrades の current
|
| WP 本体更新後バージョン |
$website->wp_upgrades の new
|
調査過程でわかったこと¶
-
mainwp_after_plugin_theme_translation_updateフックは存在するが、引数$informationが空で渡ってくるため使用不可 - バージョン情報は
$informationではなく$data['updated_data']に格納されている -
mainwp_install_update_actionsフックが正しいバージョン情報を持つ唯一のフック - WP Webhooks プラグインの無料版では
WordPress hook firedが使えない(Pro 限定) - Basic 認証・IP 制限がかかった環境では
wp_remote_postによる自サーバーへの HTTP リクエストが 401 で弾かれるため、中継 PHP ファイルを経由せず Redmine API へ直接 POST する構成が必要
デバッグログの確認¶
cat /var/www/html/wp-content/mainwp-redmine-debug.log
status=201 であれば Redmine へのチケット作成成功。確認後はログ出力コードを削除してよい。