-
Notifications
You must be signed in to change notification settings - Fork 0
fix: restrict sync PR allowance to base == next draft of head #99
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -73,18 +73,31 @@ jobs: | |
| fi | ||
| fi | ||
|
|
||
| # Allow draft-to-draft sync PRs (e.g. created by | ||
| # sync-next-draft.yml to carry accepted review suggestions | ||
| # into the next draft branch). Both head and base must match | ||
| # a draft pattern. | ||
| # Allow draft-to-draft sync PRs created by sync-next-draft.yml: | ||
| # the base must be exactly the NEXT draft of the head branch | ||
| # (e.g. head 1st-draft -> base 2nd-draft). Review PRs go in the | ||
| # opposite direction (e.g. head 2nd-draft -> base 1st-draft) | ||
| # and stay blocked. | ||
| echo "::debug::Base branch: $BASE_REF" | ||
| if { [[ "$BRANCH_NAME" =~ ^[0-9]+(st|nd|rd|th)-draft$ ]] || \ | ||
| [[ "$BRANCH_NAME" =~ ^abstract-[0-9]+(st|nd|rd|th)$ ]]; } && \ | ||
| { [[ "$BASE_REF" =~ ^[0-9]+(st|nd|rd|th)-draft$ ]] || \ | ||
| [[ "$BASE_REF" =~ ^abstract-[0-9]+(st|nd|rd|th)$ ]]; }; then | ||
| ordinal() { | ||
| local n="$1" last_two last_one | ||
| last_two=$((n % 100)); last_one=$((n % 10)) | ||
| if [[ $last_two -ge 11 && $last_two -le 13 ]]; then echo "${n}th" | ||
| elif [[ $last_one -eq 1 ]]; then echo "${n}st" | ||
| elif [[ $last_one -eq 2 ]]; then echo "${n}nd" | ||
| elif [[ $last_one -eq 3 ]]; then echo "${n}rd" | ||
| else echo "${n}th"; fi | ||
| } | ||
| NEXT_OF_HEAD="" | ||
| if [[ "$BRANCH_NAME" =~ ^([0-9]+)(st|nd|rd|th)-draft$ ]]; then | ||
| NEXT_OF_HEAD="$(ordinal $((BASH_REMATCH[1] + 1)))-draft" | ||
| elif [[ "$BRANCH_NAME" =~ ^abstract-([0-9]+)(st|nd|rd|th)$ ]]; then | ||
| NEXT_OF_HEAD="abstract-$(ordinal $((BASH_REMATCH[1] + 1)))" | ||
| fi | ||
| if [ -n "$NEXT_OF_HEAD" ] && [ "$BASE_REF" = "$NEXT_OF_HEAD" ]; then | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ✨ [POSITIVE] [POSITIVE] 許可条件を「base が head の次稿と完全一致する場合のみ」に限定した修正は明確で正確です 旧実装の「両方が draft パターンであれば許可」という条件では、レビュー PR(逆方向)も誤って許可してしまうという regression を、序数計算による厳密な方向チェックで解決しています。コメントも方向性の違いを明確に説明しており、可読性・保守性が向上しています。 |
||
| { echo "is_draft=false"; echo "draft_type=sync"; } >> "$GITHUB_OUTPUT" | ||
| echo "Draft-to-draft sync PR - merge allowed" | ||
| echo "::notice::Head and base are both draft branches - sync PR" | ||
| echo "::notice::Base ($BASE_REF) is the next draft of head ($BRANCH_NAME) - sync PR" | ||
| exit 0 | ||
| fi | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -153,12 +153,14 @@ jobs: | |
| sync_pr="${pr_url##*/}" | ||
| fi | ||
|
|
||
| # The review PR of "from" is the open PR whose base is not a | ||
| # draft branch (draft-based PRs are sync PRs, also mid-chain) | ||
| # The review PR of "from" is the open PR other than the sync | ||
| # PR itself. Note: its base may also be a draft branch (review | ||
| # PRs of 2nd and later drafts are based on the previous draft), | ||
| # so we only exclude the sync target here. | ||
| local review_pr | ||
| review_pr=$(gh pr list --head "$from" --state open \ | ||
| --json number,baseRefName \ | ||
| --jq '[.[] | select(.baseRefName | test("^[0-9]+(st|nd|rd|th)-draft$|^abstract-[0-9]+(st|nd|rd|th)$") | not)][0].number // empty') | ||
| --jq "[.[] | select(.baseRefName != \"$into\")][0].number // empty") | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
変数 --jq "[.[] | select(.baseRefName != \"$into\")][0].number // empty"
--jq '[.[] | select(.baseRefName != $into)][0].number // empty' \
--arg into "$into"これにより |
||
| if [ -n "$review_pr" ]; then | ||
| gh pr comment "$review_pr" --body "受け入れた suggestion を「$into」へ自動 merge できませんでした(コンフリクト)。同期 PR #$sync_pr を開き、「Resolve conflicts」で解決してから merge してください。" | ||
| fi | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ordinal関数をインラインで定義するとサブシェル問題が発生する可能性がありますrun: |ブロック内でシェル関数を定義し、その後$(ordinal ...)のようにコマンド置換で呼び出す場合、シェルの実装によっては関数がサブシェルに引き継がれないことがあります。GitHub Actions のrun:ブロックはbash -eで実行されますが、$(...)はサブシェルを生成するため、ordinal関数が未定義になるリスクがあります。実際には bash では関数はサブシェルに継承されるため多くの場合動作しますが、より安全な実装として関数をインライン展開するか、以下のように変数に計算結果を格納する方法を検討してください:
これにより関数定義・サブシェル起動のオーバーヘッドと潜在的なスコープ問題を回避できます。