Sync Upstream and Create PR #30
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Sync Upstream and Create PR | |
on: | |
workflow_dispatch: | |
schedule: | |
- cron: "0 0 * * *" # 매일 밤 12시 정각에 실행 | |
jobs: | |
sync: | |
runs-on: ubuntu-latest | |
permissions: | |
contents: write | |
pull-requests: write | |
steps: | |
- name: Checkout Fork | |
uses: actions/checkout@v3 | |
with: | |
repository: ${{ github.repository }} | |
token: ${{ secrets.GITHUB_TOKEN }} | |
fetch-depth: 0 | |
- name: Configure Git | |
run: | | |
git config user.name "minchodang" | |
git config user.email "[email protected]" | |
- name: Add Upstream Remote | |
run: | | |
git remote add upstream https://github.com/react-hook-form/documentation | |
git fetch upstream | |
- name: Get All Changes Except ci.yml | |
run: | | |
# upstream/master와 origin/master의 모든 변경 사항 중 .github/workflows/ci.yml 제외 | |
git diff upstream/master origin/master -- . ':(exclude).github/workflows/ci.yml' > all_changes.diff | |
if [ -s all_changes.diff ]; then | |
echo "changes=true" >> $GITHUB_ENV | |
else | |
echo "changes=false" >> $GITHUB_ENV | |
fi | |
echo "Changes detected (excluding .github/workflows/ci.yml):" | |
cat all_changes.diff | |
shell: bash | |
- name: Check Existing PRs | |
id: existing-prs | |
run: | | |
# 기존 PR 가져오기 | |
RESPONSE=$(curl -s \ | |
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ | |
-H "Accept: application/vnd.github.v3+json" \ | |
https://api.github.com/repos/${{ github.repository }}/pulls) | |
# "sync-upstream-"으로 시작하는 PR 필터링 | |
EXISTING_PR=$(echo "$RESPONSE" | jq -r '.[] | select(.head.ref | startswith("sync-upstream-")) | .head.ref' | tr '\n' ' ') | |
if [[ -n "$EXISTING_PR" ]]; then | |
echo "existing_pr=true" >> $GITHUB_ENV | |
echo "existing_pr_ref=$EXISTING_PR" >> $GITHUB_ENV | |
else | |
echo "existing_pr=false" >> $GITHUB_ENV | |
fi | |
echo "Existing PRs: $EXISTING_PR" | |
shell: bash | |
- name: Compare Changes with Each Existing PR | |
id: compare-changes | |
if: env.existing_pr == 'true' && env.changes == 'true' | |
run: | | |
ALL_EXISTING_INCLUDED=true | |
for pr_ref in ${{ env.existing_pr_ref }} | |
do | |
echo "Fetching branch: $pr_ref" | |
git fetch origin "$pr_ref:$pr_ref-branch" | |
echo "Comparing with upstream/master excluding ci.yml" | |
if ! git diff --quiet upstream/master "$pr_ref-branch" -- . ':(exclude).github/workflows/ci.yml'; then | |
ALL_EXISTING_INCLUDED=false | |
break | |
fi | |
done | |
if [ "$ALL_EXISTING_INCLUDED" = true ]; then | |
echo "diff=false" >> $GITHUB_ENV | |
else | |
echo "diff=true" >> $GITHUB_ENV | |
# 기존 PR 닫기 | |
for pr_ref in ${{ env.existing_pr_ref }} | |
do | |
PR_NUMBER=$(curl -s \ | |
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ | |
-H "Accept: application/vnd.github.v3+json" \ | |
https://api.github.com/repos/${{ github.repository }}/pulls \ | |
| jq -r '.[] | select(.head.ref=="'$pr_ref'") | .number') | |
echo "Closing PR #$PR_NUMBER" | |
curl -X PATCH \ | |
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ | |
-H "Accept: application/vnd.github.v3+json" \ | |
https://api.github.com/repos/${{ github.repository }}/pulls/$PR_NUMBER \ | |
-d '{"state":"closed"}' | |
done | |
fi | |
shell: bash | |
- name: Create Branch and Apply Changes | |
if: env.diff == 'true' || env.existing_pr == 'false' | |
run: | | |
set -x # 디버깅 로그 활성화 | |
BRANCH_NAME=sync-upstream-$(date +%Y%m%d%H%M%S) | |
git checkout -b $BRANCH_NAME origin/master | |
# upstream/master의 변경 사항 적용 (ci.yml 제외) | |
git apply all_changes.diff || { echo "Failed to apply changes"; exit 1; } | |
# 모든 변경 사항 스테이지 해제 | |
git reset | |
# 현재 스테이지된 파일 확인 | |
echo "After git reset:" | |
git status | |
# 모든 변경 사항 스테이지 | |
git add . | |
# 특정 파일 제외하고 스테이지 (재확인) | |
git reset .github/workflows/ci.yml || true | |
# 스테이지된 파일 목록 출력 | |
echo "Staged files after adding changes:" | |
git diff --cached --name-only | |
# 스테이지된 파일이 .github/workflows/ci.yml 제외한 모든 파일인지 확인 | |
STAGED_FILES=$(git diff --cached --name-only) | |
echo "Staged files:" | |
echo "$STAGED_FILES" | |
if [ -n "$(echo "$STAGED_FILES" | grep '^.github/workflows/ci.yml')" ]; then | |
echo "Error: .github/workflows/ci.yml is staged." | |
exit 1 | |
fi | |
# 커밋 | |
if ! git diff --quiet --cached; then | |
git commit -m "Sync with upstream (excluding workflows)" | |
else | |
echo "No changes to commit." | |
exit 0 | |
fi | |
# 최종 상태 확인 | |
echo "Final git status before push:" | |
git status | |
# 브랜치 푸시 | |
git push origin $BRANCH_NAME --force-with-lease | |
echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_ENV | |
shell: bash | |
- name: Create Pull Request | |
if: env.diff == 'true' || env.existing_pr == 'false' | |
run: | | |
curl -X POST \ | |
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ | |
-H "Accept: application/vnd.github.v3+json" \ | |
https://api.github.com/repos/${{ github.repository }}/pulls \ | |
-d '{ | |
"title": "Sync with upstream (excluding workflows)", | |
"body": "This PR syncs the repository with upstream changes excluding .github/workflows/ci.yml", | |
"head": "'"${{ env.BRANCH_NAME }}"'", | |
"base": "master" | |
}' | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |