name: Create PR from develop to master
on:
push:
branches:
- develop
# コンカレンシー制御 - 同じブランチで同時に実行されないようにする
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
create-pr:
runs-on: ubuntu-latest
if: ${{ !contains(github.event.head_commit.message, '[skip ci]') }}
permissions:
contents: write
pull-requests: write
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check branch existence
id: check-branches
run: |
# developブランチの存在を確認
if ! git rev-parse --verify origin/develop &>/dev/null; then
echo "Warning: develop branch doesn't exist. Skipping PR creation."
echo "skip=true" >> $GITHUB_OUTPUT
exit 0
fi
# masterブランチの存在を確認
if ! git rev-parse --verify origin/master &>/dev/null; then
echo "Warning: master branch doesn't exist. Skipping PR creation."
echo "skip=true" >> $GITHUB_OUTPUT
exit 0
fi
echo "skip=false" >> $GITHUB_OUTPUT
- name: Check existing PR
id: check-pr
if: steps.check-branches.outputs.skip != 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
existing_pr=$(gh pr list --base master --head develop --state open --json number -q '.[0].number')
if [ ! -z "$existing_pr" ]; then
echo "Existing PR found: #$existing_pr"
echo "skip=true" >> $GITHUB_OUTPUT
else
echo "No existing PR found"
echo "skip=false" >> $GITHUB_OUTPUT
fi
- name: Check for changes between develop and master
id: check_diff
if: steps.check-pr.outputs.skip != 'true' && steps.check-branches.outputs.skip != 'true'
run: |
# Fetch latest master and develop branches from origin
git fetch origin master develop
# Compare remote tracking branches to avoid issues with local state
changes=$(git log origin/master..origin/develop --oneline)
if [ -z "$changes" ]; then
echo "No changes detected between develop and master. Skipping PR creation."
echo "skip_pr_creation=true" >> $GITHUB_OUTPUT
else
echo "Changes detected. Proceeding with PR creation."
echo "skip_pr_creation=false" >> $GITHUB_OUTPUT
fi
- name: Create Pull Request
# Only run if branches exist, no existing PR, AND changes were detected
if: steps.check-pr.outputs.skip != 'true' && steps.check-branches.outputs.skip != 'true' && steps.check_diff.outputs.skip_pr_creation != 'true'
id: create-pr
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# コミットメッセージから変更の種類を判断
commit_message="${{ github.event.head_commit.message }}"
if [[ "$commit_message" =~ ^feat:|^feature: ]]; then
pr_title="✨ feat: Merge develop into master"
label="enhancement"
elif [[ "$commit_message" =~ ^fix: ]]; then
pr_title="🐛 fix: Merge develop into master"
label="bug"
else
pr_title="🔄 chore: Merge develop into master"
label="chore"
fi
# 変更ログを生成
set +e # エラーが発生してもスクリプトを継続
changes=$(git log origin/master..origin/develop --pretty=format:'- %s' --reverse 2>/dev/null)
exit_code=$?
set -e # エラーハンドリングを再度有効化
if [ $exit_code -ne 0 ] || [ -z "$changes" ]; then
echo "警告: developとmasterの間に変更が見つかりませんでした、またはコマンドが失敗しました"
changes="*変更履歴が見つかりませんでした*"
fi
# Use English template consistently
template_file=".github/workflow-templates/develop-to-master-pr-template-en.md"
# Check if template file exists
if [ ! -f "$template_file" ]; then
echo "Error: Template file '$template_file' not found."
echo "Using default English template."
body="## Changes\n\n${changes}\n\n---\n\n_This PR was automatically generated_"
else
# Load template and insert changes
# Ensure CHANGES variable is properly escaped for sed if it contains special characters
# Using awk might be safer for complex replacements
body=$(awk -v changes="${changes}" '{gsub(/{{CHANGES}}/, changes)}1' "$template_file")
fi
# PRを作成
set +e # エラーが発生してもスクリプトを継続
pr_result=$(gh pr create \
--base master \
--head develop \
--title "$pr_title" \
--body "$body" \
--label "auto-generated" \
--label "$label" 2>&1)
pr_status=$?
set -e # エラーハンドリングを再度有効化
if [ $pr_status -eq 0 ]; then
echo "Pull Request created successfully!"
echo "pr_url=$pr_result" >> $GITHUB_OUTPUT
echo "pr_status=success" >> $GITHUB_OUTPUT
else
echo "Pull Request creation failed: $pr_result"
echo "pr_status=failed" >> $GITHUB_OUTPUT
echo "pr_error=$pr_result" >> $GITHUB_OUTPUT
exit 1
fi