Skip to content

Commit 9630b90

Browse files
committed
refactor: PR作成ロジックを改善し、差分チェックを追加
1 parent a3ef78d commit 9630b90

File tree

1 file changed

+78
-18
lines changed

1 file changed

+78
-18
lines changed

.github/workflows/prepare-release.yml

Lines changed: 78 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -179,26 +179,86 @@ jobs:
179179
echo "pr_body=自動生成された **正式リリース** 準備 PR です。" >> $GITHUB_OUTPUT
180180
fi
181181
182-
- name: Create PR
182+
- name: Check diff with base
183183
if: ${{ github.event.inputs.dry_run == 'false' && steps.push.outputs.branch != '' }}
184-
uses: peter-evans/create-pull-request@v6
184+
id: diff
185+
run: |
186+
BASE='${{ steps.target.outputs.base }}'
187+
HEAD_BR='${{ steps.push.outputs.branch }}'
188+
set -e
189+
echo "Fetching full history for reliable diff..."
190+
git fetch origin "$BASE" --depth=0 || true
191+
git fetch origin "$HEAD_BR" --depth=0 || true
192+
# Ensure we have refs
193+
git rev-parse "origin/$BASE" >/dev/null
194+
git rev-parse "$HEAD_BR" >/dev/null
195+
196+
# Primary commit ahead count (commits reachable from HEAD_BR not in base)
197+
AHEAD=$(git rev-list --right-only --count "origin/$BASE...$HEAD_BR" || echo 0)
198+
echo "ahead_commits=$AHEAD" >> $GITHUB_OUTPUT
199+
200+
# Secondary: file diff check (handles rewritten history / same commit count but content changes)
201+
if git diff --quiet "origin/$BASE...$HEAD_BR"; then
202+
FILE_DIFF=0
203+
else
204+
FILE_DIFF=1
205+
fi
206+
echo "file_diff=$FILE_DIFF" >> $GITHUB_OUTPUT
207+
208+
# Tertiary: changed pubspec / changelog specifically (release related)
209+
if git diff --name-only "origin/$BASE...$HEAD_BR" | grep -E '^(pubspec.yaml|CHANGELOG.md)$' >/dev/null; then
210+
REL_FILES_CHANGED=1
211+
else
212+
REL_FILES_CHANGED=0
213+
fi
214+
echo "release_files_changed=$REL_FILES_CHANGED" >> $GITHUB_OUTPUT
215+
216+
if [ "$AHEAD" -gt 0 ] || [ "$FILE_DIFF" -eq 1 ] || [ "$REL_FILES_CHANGED" -eq 1 ]; then
217+
echo "different=true" >> $GITHUB_OUTPUT
218+
echo "Diff detected (ahead=$AHEAD file_diff=$FILE_DIFF release_files=$REL_FILES_CHANGED)"
219+
else
220+
echo "different=false" >> $GITHUB_OUTPUT
221+
echo "No diff between $HEAD_BR and $BASE. PR will be skipped."
222+
echo "(ahead=$AHEAD file_diff=$FILE_DIFF release_files=$REL_FILES_CHANGED)"
223+
fi
224+
225+
- name: Create / Reuse PR (github-script)
226+
if: ${{ github.event.inputs.dry_run == 'false' && steps.push.outputs.branch != '' && steps.diff.outputs.different == 'true' }}
227+
uses: actions/github-script@v7
228+
id: create_pr
185229
with:
186-
token: ${{ secrets.GITHUB_TOKEN }}
187-
branch: ${{ steps.push.outputs.branch }}
188-
base: ${{ steps.target.outputs.base }}
189-
title: "chore(release): v${{ steps.next.outputs.value }}"
190-
body: |
191-
${{ steps.target.outputs.pr_body }}
192-
193-
- 元ブランチ: dev
194-
- 次バージョン: v${{ steps.next.outputs.value }}
195-
- CHANGELOG は placeholder を含む場合があります。必要に応じて編集してください。
196-
197-
**【重要】**
198-
- **正式リリース (main向け)**: マージ後、`publish-release` ワークフローがタグと GitHub Release を作成します。
199-
- **プレリリース (dev向け)**: マージ後、タグやリリースは作成されません。バージョン番号のみ取り込みます。
200-
labels: release
201-
draft: false
230+
github-token: ${{ secrets.GITHUB_TOKEN }}
231+
script: |
232+
const next = process.env.NEXT_VERSION = `${{ steps.next.outputs.value }}`;
233+
const head = `${{ steps.push.outputs.branch }}`; // already pushed 'release/vX.Y.Z'
234+
const base = `${{ steps.target.outputs.base }}`;
235+
const prTitle = `chore(release): v${{ steps.next.outputs.value }}`;
236+
const body = (
237+
`${{ steps.target.outputs.pr_body }}\n\n` +
238+
`- 元ブランチ: dev\n` +
239+
`- 次バージョン: v${{ steps.next.outputs.value }}\n` +
240+
`- CHANGELOG は placeholder を含む場合があります。必要に応じて編集してください。\n\n` +
241+
`**【重要】**\n` +
242+
`- **正式リリース (main向け)**: マージ後、publish-release ワークフローがタグと GitHub Release を作成します。\n` +
243+
`- **プレリリース (dev向け)**: マージ後、タグやリリースは作成されません。バージョン番号のみ取り込みます。`
244+
).trim();
245+
246+
const {owner, repo} = context.repo;
247+
// Check existing open PR from head -> base
248+
const existing = await github.rest.pulls.list({owner, repo, state: 'open', head: `${owner}:${head}`});
249+
if (existing.data.length > 0) {
250+
core.info(`Existing PR found: ${existing.data[0].html_url}`);
251+
core.setOutput('url', existing.data[0].html_url);
252+
return;
253+
}
254+
// Create new PR
255+
const pr = await github.rest.pulls.create({owner, repo, head, base, title: prTitle, body});
256+
core.info(`Created PR: ${pr.data.html_url}`);
257+
core.setOutput('url', pr.data.html_url);
258+
259+
- name: Skip note (no diff)
260+
if: ${{ github.event.inputs.dry_run == 'false' && steps.push.outputs.branch != '' && steps.diff.outputs.different == 'false' }}
261+
run: echo "Base と release ブランチに差分が無いため PR 作成をスキップしました。"
202262

203263
- name: Dry run note
204264
if: ${{ github.event.inputs.dry_run == 'true' }}

0 commit comments

Comments
 (0)