Sync Upstream and Create PR #21
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: Fetch Upstream | |
run: | | |
git remote add upstream https://github.com/react-hook-form/documentation | |
git fetch upstream | |
git fetch origin | |
- name: Check for Changes | |
id: changes | |
run: | | |
# .github/workflows/ 디렉토리를 제외하고 변경 사항 확인 | |
if git diff --quiet origin/master upstream/master -- . ':(exclude).github/workflows/'; then | |
echo "changes=false" >> $GITHUB_ENV | |
else | |
echo "changes=true" >> $GITHUB_ENV | |
fi | |
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 | |
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" | |
if ! git diff --quiet upstream/master "$pr_ref-branch"; 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') | |
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 Rebase Changes | |
if: env.diff == 'true' || env.existing_pr == 'false' | |
run: | | |
BRANCH_NAME=sync-upstream-$(date +%Y%m%d%H%M%S) | |
git checkout -b $BRANCH_NAME origin/master | |
# upstream/master와 리베이스 | |
git rebase upstream/master | |
# .github/workflows/ 디렉토리 변경 사항 되돌리기 | |
git checkout origin/master -- .github/workflows/ | |
# 변경 사항이 있는지 확인하고, src 디렉토리만 스테이지 | |
if ! git diff --quiet; then | |
# src 디렉토리만 스테이지 | |
git add src/ | |
# 워크플로우 파일 제외하고 커밋 | |
git commit -m "Sync with upstream (excluding workflows)" | |
fi | |
# 브랜치 푸시 | |
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", | |
"body": "This PR syncs the fork with upstream repository", | |
"head": "'"${{ env.BRANCH_NAME }}"'", | |
"base": "master" | |
}' | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |