11name : Check for new MySQL Shell releases
22
3+ # このワークフローは以下を行います:
4+ # 1. MySQL Shellの最新リリースタグを検出
5+ # 2. 現在のDockerイメージのバージョンと比較
6+ # 3. 更新が必要な場合は自動的にPRを作成
7+
8+ # このワークフローは以下を行います:
9+ # 1. MySQL Shellの最新リリースタグを検出
10+ # 2. 現在のDockerイメージのバージョンと比較
11+ # 3. 更新が必要な場合は自動的にPRを作成
12+
313on :
414 schedule :
515 # 毎日 UTC 3時17分に実行 (ランダムな時刻で負荷分散)
616 - cron : ' 17 3 * * *'
717 workflow_dispatch : # 手動実行も可能にする
18+ inputs :
19+ dry_run :
20+ description : ' 実際のPRを作成せずにテスト実行'
21+ required : false
22+ default : false
23+ type : boolean
24+ innovation_version :
25+ description : ' テスト用の強制Innovation版バージョン(例:9.3.0)'
26+ required : false
27+ type : string
28+ lts_version :
29+ description : ' テスト用の強制LTS版バージョン(例:8.4.5)'
30+ required : false
31+ type : string
32+ inputs :
33+ dry_run :
34+ description : ' 実際のPRを作成せずにテスト実行'
35+ required : false
36+ default : false
37+ type : boolean
38+ innovation_version :
39+ description : ' テスト用の強制Innovation版バージョン(例:9.3.0)'
40+ required : false
41+ type : string
42+ lts_version :
43+ description : ' テスト用の強制LTS版バージョン(例:8.4.5)'
44+ required : false
45+ type : string
846
947jobs :
1048 check-release :
1149 runs-on : ubuntu-latest
50+ # ジョブの概要説明
51+ name : Check and update MySQL Shell versions
1252 steps :
53+ # ステップ1: リポジトリの取得
1354 - name : Checkout repository
1455 uses : actions/checkout@v4
1556 with :
1657 # プルリクエスト作成のためにトークンが必要
17- token : ${{ secrets.GITHUB_TOKEN }} # または PAT
58+ token : ${{ secrets.GITHUB_TOKEN }}
1859
1960 - name : Get current versions
2061 id : current_versions
@@ -51,25 +92,44 @@ jobs:
5192 INNOVATION_MAJOR="${{ steps.current_versions.outputs.INNOVATION_MAJOR_VERSION }}"
5293 LTS_MAJOR="${{ steps.current_versions.outputs.LTS_MAJOR_VERSION }}"
5394
54- API_RESPONSE=$(curl -s -H "Accept: application/vnd.github+json" https://api.github.com/repos/mysql/mysql-shell/tags)
55-
56- if [[ -z "$API_RESPONSE" ]] || [[ "$API_RESPONSE" == *"rate limit"* ]]; then
57- echo "::error::Failed to fetch data from GitHub API or rate limit exceeded"
58- exit 1
95+ # テスト用の手動指定バージョンがあれば使用する
96+ if [[ "${{ github.event_name }}" == "workflow_dispatch" && -n "${{ github.event.inputs.innovation_version }}" ]]; then
97+ LATEST_INNOVATION="${{ github.event.inputs.innovation_version }}"
98+ echo "Using manually specified Innovation version: $LATEST_INNOVATION"
99+ else
100+ # GitHub APIからのフェッチを試みる
101+ API_RESPONSE=$(curl -s -H "Accept: application/vnd.github+json" \
102+ -H "X-GitHub-Api-Version: 2022-11-28" \
103+ -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
104+ "https://api.github.com/repos/mysql/mysql-shell/tags?per_page=100")
105+
106+ if [[ -z "$API_RESPONSE" ]] || [[ "$API_RESPONSE" == *"rate limit"* ]] || [[ "$API_RESPONSE" == *"Bad credentials"* ]]; then
107+ echo "::error::Failed to fetch data from GitHub API: $(echo "$API_RESPONSE" | grep -o '"message":"[^"]*"' || echo 'Unknown error')"
108+ exit 1
109+ fi
110+
111+ # 正規表現パターンを動的に構築
112+ INNOVATION_PATTERN="^${INNOVATION_MAJOR}\\.\\d+\\.\\d+$"
113+
114+ LATEST_INNOVATION=$(echo "$API_RESPONSE" | jq -r --arg pattern "$INNOVATION_PATTERN" '[.[] | select(.name | test($pattern))][0].name')
115+ fi
116+
117+ # LTSバージョンの取得(手動指定またはAPI)
118+ if [[ "${{ github.event_name }}" == "workflow_dispatch" && -n "${{ github.event.inputs.lts_version }}" ]]; then
119+ LATEST_LTS="${{ github.event.inputs.lts_version }}"
120+ echo "Using manually specified LTS version: $LATEST_LTS"
121+ else
122+ # APIレスポンスを再利用
123+ LTS_PATTERN="^${LTS_MAJOR}\\.\\d+\\.\\d+$"
124+ LATEST_LTS=$(echo "$API_RESPONSE" | jq -r --arg pattern "$LTS_PATTERN" '[.[] | select(.name | test($pattern))][0].name')
59125 fi
60126
61- # 正規表現パターンを動的に構築
62- INNOVATION_PATTERN="^${INNOVATION_MAJOR}\\.\\d+\\.\\d+$"
63- LTS_PATTERN="^${LTS_MAJOR}\\.\\d+\\.\\d+$"
64-
65- LATEST_INNOVATION=$(echo "$API_RESPONSE" | jq -r --arg pattern "$INNOVATION_PATTERN" '[.[] | select(.name | test($pattern))][0].name')
66- LATEST_LTS=$(echo "$API_RESPONSE" | jq -r --arg pattern "$LTS_PATTERN" '[.[] | select(.name | test($pattern))][0].name')
67-
127+ # 結果の検証
68128 if [[ -z "$LATEST_INNOVATION" ]] || [[ "$LATEST_INNOVATION" == "null" ]] || [[ -z "$LATEST_LTS" ]] || [[ "$LATEST_LTS" == "null" ]]; then
69129 echo "::warning::Failed to find matching versions. Using hardcoded patterns as fallback."
70130 # フォールバック: ハードコードされたバージョンパターン
71- LATEST_INNOVATION=$(echo "$API_RESPONSE" | jq -r '[.[] | select(.name | test("^9\\.\\d+\\.\\d+$"))][0].name')
72- LATEST_LTS=$(echo "$API_RESPONSE" | jq -r '[.[] | select(.name | test("^8\\.\\d+\\.\\d+$"))][0].name')
131+ LATEST_INNOVATION=${LATEST_INNOVATION:-$ (echo "$API_RESPONSE" | jq -r '[.[] | select(.name | test("^9\\.\\d+\\.\\d+$"))][0].name')}
132+ LATEST_LTS=${LATEST_LTS:-$ (echo "$API_RESPONSE" | jq -r '[.[] | select(.name | test("^8\\.\\d+\\.\\d+$"))][0].name')}
73133 fi
74134
75135 echo "LATEST_INNOVATION=${LATEST_INNOVATION}" >> $GITHUB_OUTPUT
@@ -80,6 +140,12 @@ jobs:
80140 - name : Check versions
81141 id : check_versions
82142 run : |
143+ # バージョン比較ユーティリティ関数
144+ version_gt() {
145+ # $1 > $2 の場合に0を返す
146+ test "$(echo "$1 $2" | tr " " "\n" | sort -V | head -n 1)" != "$1"
147+ }
148+
83149 CURRENT_INNOVATION="${{ steps.current_versions.outputs.CURRENT_INNOVATION }}"
84150 LATEST_INNOVATION="${{ steps.latest_tags.outputs.LATEST_INNOVATION }}"
85151 CURRENT_LTS="${{ steps.current_versions.outputs.CURRENT_LTS }}"
@@ -88,22 +154,44 @@ jobs:
88154 INNOVATION_UPDATE_NEEDED="false"
89155 LTS_UPDATE_NEEDED="false"
90156
157+ # Innovation バージョンのチェック
91158 if [[ -z "$LATEST_INNOVATION" ]] || [[ "$LATEST_INNOVATION" == "null" ]]; then
92159 echo "::warning::No valid Innovation version found in API response"
93160 elif [[ "$CURRENT_INNOVATION" != "$LATEST_INNOVATION" ]]; then
94- echo "Update needed for Innovation: $CURRENT_INNOVATION -> $LATEST_INNOVATION"
95- INNOVATION_UPDATE_NEEDED="true"
161+ if version_gt "$LATEST_INNOVATION" "$CURRENT_INNOVATION"; then
162+ echo "Update needed for Innovation: $CURRENT_INNOVATION -> $LATEST_INNOVATION (newer version available)"
163+ INNOVATION_UPDATE_NEEDED="true"
164+ else
165+ echo "::warning::Latest Innovation version ($LATEST_INNOVATION) is older than current ($CURRENT_INNOVATION). Skipping update."
166+ fi
96167 else
97- echo "Innovation is up-to-date."
168+ echo "Innovation is up-to-date at version $CURRENT_INNOVATION ."
98169 fi
99170
171+ # LTS バージョンのチェック
100172 if [[ -z "$LATEST_LTS" ]] || [[ "$LATEST_LTS" == "null" ]]; then
101173 echo "::warning::No valid LTS version found in API response"
102174 elif [[ "$CURRENT_LTS" != "$LATEST_LTS" ]]; then
103- echo "Update needed for LTS: $CURRENT_LTS -> $LATEST_LTS"
104- LTS_UPDATE_NEEDED="true"
175+ if version_gt "$LATEST_LTS" "$CURRENT_LTS"; then
176+ echo "Update needed for LTS: $CURRENT_LTS -> $LATEST_LTS (newer version available)"
177+ LTS_UPDATE_NEEDED="true"
178+ else
179+ echo "::warning::Latest LTS version ($LATEST_LTS) is older than current ($CURRENT_LTS). Skipping update."
180+ fi
105181 else
106- echo "LTS is up-to-date."
182+ echo "LTS is up-to-date at version $CURRENT_LTS."
183+ fi
184+
185+ # テストモードでは常に更新が必要であると報告
186+ if [[ "${{ github.event_name }}" == "workflow_dispatch" && "${{ github.event.inputs.dry_run }}" == "true" ]]; then
187+ if [[ -n "${{ github.event.inputs.innovation_version }}" ]]; then
188+ echo "::notice::テストモード: Innovation更新をテスト実行します"
189+ INNOVATION_UPDATE_NEEDED="true"
190+ fi
191+ if [[ -n "${{ github.event.inputs.lts_version }}" ]]; then
192+ echo "::notice::テストモード: LTS更新をテスト実行します"
193+ LTS_UPDATE_NEEDED="true"
194+ fi
107195 fi
108196
109197 echo "INNOVATION_UPDATE_NEEDED=${INNOVATION_UPDATE_NEEDED}" >> $GITHUB_OUTPUT
@@ -117,12 +205,22 @@ jobs:
117205 LATEST_INNOVATION : ${{ steps.latest_tags.outputs.LATEST_INNOVATION }}
118206 CURRENT_LTS : ${{ steps.current_versions.outputs.CURRENT_LTS }}
119207 LATEST_LTS : ${{ steps.latest_tags.outputs.LATEST_LTS }}
208+ DRY_RUN : ${{ github.event.inputs.dry_run == 'true' }}
120209 run : |
210+ # dry runモードを確認
211+ if [[ "$DRY_RUN" == "true" ]]; then
212+ echo "::notice::dry runモードで実行しています。実際の変更は行いません。"
213+ fi
214+
121215 # ブランチ作成
122216 BRANCH_NAME="bot/update-mysql-shell-$(date +%Y%m%d%H%M%S)"
123- git config --global user.name 'github-actions[bot]'
124- git config --global user.email 'github-actions[bot]@users.noreply.github.com'
125- git checkout -b $BRANCH_NAME
217+ if [[ "$DRY_RUN" != "true" ]]; then
218+ git config --global user.name 'github-actions[bot]'
219+ git config --global user.email 'github-actions[bot]@users.noreply.github.com'
220+ git checkout -b $BRANCH_NAME
221+ else
222+ echo "dry run: git checkout -b $BRANCH_NAME"
223+ fi
126224
127225 PR_BODY="Automated update for MySQL Shell versions.\n\n"
128226
@@ -135,32 +233,81 @@ jobs:
135233 local minor_version=$(echo "$new_version" | cut -d. -f2)
136234 local short_version="${major_version}.${minor_version}"
137235
138- echo "Updating $type to $new_version..."
236+ echo "Updating $type to $new_version (major.minor: $short_version) ..."
139237
140238 # Dockerfile の更新
141- sed -i "s/^ARG MYSQL_SHELL_VERSION=.*/ARG MYSQL_SHELL_VERSION=$new_version/" docker/$type/Dockerfile
142-
143- # マークダウンファイルの更新
144- sed -i "s/MySQL Shell ${current_version}/MySQL Shell ${new_version}/g" Repository.md
145- sed -i "s/snickerjp\/docker-mysql-shell:${current_version}/snickerjp\/docker-mysql-shell:${new_version}/g" Repository.md
239+ if [[ "$DRY_RUN" != "true" ]]; then
240+ sed -i "s/^ARG MYSQL_SHELL_VERSION=.*/ARG MYSQL_SHELL_VERSION=$new_version/" docker/$type/Dockerfile || {
241+ echo "::warning::Failed to update version in docker/$type/Dockerfile, but continuing..."
242+ }
243+ else
244+ echo "dry run: docker/$type/Dockerfile 内の ARG MYSQL_SHELL_VERSION=$current_version を $new_version に更新"
245+ fi
146246
147247 # README.md の更新
148248 if [[ "$type" == "innovation" ]]; then
149- sed -i "s/Innovation Series ([0-9]\\.[0-9]\\.[x0-9])/Innovation Series (${major_version}.${minor_version}.x)/g" README.md
150- sed -i "s/snickerjp\/docker-mysql-shell:${major_version}\\.[0-9]/snickerjp\/docker-mysql-shell:${short_version}/g" README.md
249+ local match_pattern="Innovation Series ([0-9]\\.[0-9]\\.[x0-9])"
250+ local replace_value="Innovation Series (${major_version}.${minor_version}.x)"
251+ local tag_pattern="snickerjp\/docker-mysql-shell:${major_version}\\.[0-9]"
252+ local tag_replace="snickerjp\/docker-mysql-shell:${short_version}"
253+
254+ if [[ "$DRY_RUN" != "true" ]]; then
255+ # 各sedコマンドを個別にエラーハンドリング
256+ sed -i "s/$match_pattern/$replace_value/g" README.md || {
257+ echo "::warning::Failed to update Innovation Series version in README.md, but continuing..."
258+ }
259+
260+ sed -i "s/$tag_pattern/$tag_replace/g" README.md || {
261+ echo "::warning::Failed to update Innovation image tag in README.md, but continuing..."
262+ }
263+ else
264+ echo "dry run: README.md 内の '$match_pattern' を '$replace_value' に更新"
265+ echo "dry run: README.md 内の '$tag_pattern' を '$tag_replace' に更新"
266+ fi
151267 else
152- sed -i "s/LTS Series ([0-9]\\.[0-9]\\.[x0-9])/LTS Series (${major_version}.${minor_version}.x)/g" README.md
153- sed -i "s/snickerjp\/docker-mysql-shell:${major_version}\\.[0-9]/snickerjp\/docker-mysql-shell:${short_version}/g" README.md
268+ local match_pattern="LTS Series ([0-9]\\.[0-9]\\.[x0-9])"
269+ local replace_value="LTS Series (${major_version}.${minor_version}.x)"
270+ local tag_pattern="snickerjp\/docker-mysql-shell:${major_version}\\.[0-9]"
271+ local tag_replace="snickerjp\/docker-mysql-shell:${short_version}"
272+
273+ if [[ "$DRY_RUN" != "true" ]]; then
274+ sed -i "s/$match_pattern/$replace_value/g" README.md || {
275+ echo "::warning::Failed to update LTS Series version in README.md, but continuing..."
276+ }
277+
278+ sed -i "s/$tag_pattern/$tag_replace/g" README.md || {
279+ echo "::warning::Failed to update LTS image tag in README.md, but continuing..."
280+ }
281+ else
282+ echo "dry run: README.md 内の '$match_pattern' を '$replace_value' に更新"
283+ echo "dry run: README.md 内の '$tag_pattern' を '$tag_replace' に更新"
284+ fi
154285 fi
155286
156287 # GitHub Actions ワークフローファイルの更新
288+ local workflow_pattern="version: ${major_version}\\.[0-9]"
289+ local workflow_replace="version: ${short_version}"
157290 for workflow in .github/workflows/docker-*.yml; do
158291 if [[ -f "$workflow" ]]; then
159- sed -i "s/version: ${major_version}\\.[0-9]/version: ${short_version}/g" "$workflow"
292+ if [[ "$DRY_RUN" != "true" ]]; then
293+ sed -i "s/$workflow_pattern/$workflow_replace/g" "$workflow" || {
294+ echo "::warning::Failed to update version in $workflow, but continuing..."
295+ }
296+ else
297+ echo "dry run: $workflow 内の '$workflow_pattern' を '$workflow_replace' に更新"
298+ fi
160299 fi
161300 done
162301
302+ # PR本文に変更内容を追加
163303 PR_BODY+="* **${type^}:** ${current_version} -> ${new_version}\n"
304+
305+ # 更新が成功したか確認(少なくともDockerfileは必須)- ドライランでは実行しない
306+ if [[ "$DRY_RUN" != "true" ]]; then
307+ if ! grep -q "ARG MYSQL_SHELL_VERSION=$new_version" docker/$type/Dockerfile; then
308+ echo "::warning::Version update in docker/$type/Dockerfile might have failed, but we'll continue..."
309+ fi
310+ fi
164311 }
165312
166313 # Innovation の更新
@@ -180,27 +327,50 @@ jobs:
180327 exit 0
181328 fi
182329
183- git add $changed_files
184- git commit -m "Update MySQL Shell versions (Innovation: $LATEST_INNOVATION, LTS: $LATEST_LTS)"
185-
186- # エラーハンドリング付きでプッシュ
187- if ! git push origin $BRANCH_NAME; then
188- echo "::error::Failed to push changes to GitHub"
189- exit 1
190- fi
330+ # ファイルの変更をチェック
331+ echo "Changed files:"
332+ for file in $changed_files; do
333+ echo "- $file"
334+ done
191335
192- # プルリクエストを作成
193- if ! gh pr create \
194- --base develop \
195- --head $BRANCH_NAME \
196- --title "Update MySQL Shell versions (Innovation: $LATEST_INNOVATION, LTS: $LATEST_LTS)" \
197- --body "$PR_BODY"; then
198- echo "::error::Failed to create Pull Request"
199- exit 1
336+ # すべての変更をステージング
337+ if [[ "$DRY_RUN" != "true" ]]; then
338+ git add $changed_files
339+ git commit -m "Update MySQL Shell versions (Innovation: $LATEST_INNOVATION, LTS: $LATEST_LTS)"
340+
341+ # エラーハンドリング付きでプッシュ
342+ if ! git push origin $BRANCH_NAME; then
343+ echo "::error::Failed to push changes to GitHub"
344+ exit 1
345+ fi
346+
347+ # プルリクエストを作成
348+ if ! gh pr create \
349+ --base develop \
350+ --head $BRANCH_NAME \
351+ --title "Update MySQL Shell versions (Innovation: $LATEST_INNOVATION, LTS: $LATEST_LTS)" \
352+ --body "$PR_BODY"; then
353+ echo "::error::Failed to create Pull Request"
354+ exit 1
355+ fi
356+
357+ echo "Pull request created successfully!"
358+ else
359+ echo "dry run: 以下のファイルが変更されます:"
360+ for file in $changed_files; do
361+ echo "- $file"
362+ done
363+ echo "dry run: コミットメッセージ: Update MySQL Shell versions (Innovation: $LATEST_INNOVATION, LTS: $LATEST_LTS)"
364+ echo "dry run: PR作成: タイトル: Update MySQL Shell versions (Innovation: $LATEST_INNOVATION, LTS: $LATEST_LTS)"
365+ echo "dry run: PR本文:"
366+ echo -e "$PR_BODY"
367+ echo "dry run終了: 実際の変更は行われていません。"
200368 fi
201-
202- echo "Pull request created successfully!"
203369
370+ # ステップ6: 更新不要の場合の通知
204371 - name : No update needed
205372 if : steps.check_versions.outputs.INNOVATION_UPDATE_NEEDED == 'false' && steps.check_versions.outputs.LTS_UPDATE_NEEDED == 'false'
206- run : echo "No new MySQL Shell versions found. All versions are up to date."
373+ run : |
374+ echo "::notice::No new MySQL Shell versions found. All versions are up to date."
375+ echo "Current Innovation: ${{ steps.current_versions.outputs.CURRENT_INNOVATION }}"
376+ echo "Current LTS: ${{ steps.current_versions.outputs.CURRENT_LTS }}"
0 commit comments