Skip to content

Commit 0ffe590

Browse files
committed
chore: Adding reverse sync workflow
1 parent 3b4908b commit 0ffe590

File tree

1 file changed

+267
-0
lines changed

1 file changed

+267
-0
lines changed

.github/workflows/reverse-sync.yml

Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,267 @@
1+
name: Reverse Sync
2+
3+
env:
4+
TARGET_REPO: alaudadevops/tektoncd-operator
5+
6+
on:
7+
pull_request:
8+
types: [closed]
9+
branches:
10+
- main
11+
- release-*
12+
paths:
13+
- '*'
14+
- '!README.md'
15+
16+
17+
jobs:
18+
reverse-sync:
19+
if: github.event.pull_request.merged == true
20+
runs-on: ubuntu-latest
21+
22+
steps:
23+
- name: Check if PR is from sync bot
24+
id: check_sync_bot
25+
run: |
26+
pr_author="${{ github.event.pull_request.user.login }}"
27+
pr_title="${{ github.event.pull_request.title }}"
28+
pr_base_ref="${{ github.event.pull_request.base.ref }}"
29+
pr_head_ref="${{ github.event.pull_request.head.ref }}"
30+
31+
echo "=> PR Title: $pr_title"
32+
echo "=> PR Author: $pr_author"
33+
echo "=> PR Refs: $pr_base_ref --> $pr_head_ref"
34+
# Skip if the PR is from our sync bot or has sync-related keywords
35+
if [[ "$pr_author" == "github-actions[bot]" ]] ||
36+
[[ "$pr_title" == *"Sync documentation"* ]] ||
37+
[[ "$pr_title" == *"sync-docs"* ]]; then
38+
echo "skip_sync=true" >> $GITHUB_OUTPUT
39+
echo "🤖 PR is from sync bot - skipping reverse sync"
40+
else
41+
echo "skip_sync=false" >> $GITHUB_OUTPUT
42+
echo "👥 PR is from external contributor - proceeding with reverse sync"
43+
fi
44+
45+
- name: Checkout devops-pipelines-docs repository
46+
if: steps.check_sync_bot.outputs.skip_sync == 'false'
47+
uses: actions/checkout@v4
48+
with:
49+
token: ${{ secrets.SYNC_TOKEN }}
50+
path: devops-pipelines-docs
51+
fetch-depth: 0
52+
ref: ${{ github.event.pull_request.base.ref }}
53+
54+
- name: Checkout target repository
55+
if: steps.check_sync_bot.outputs.skip_sync == 'false'
56+
uses: actions/checkout@v4
57+
with:
58+
repository: ${{env.TARGET_REPO}}
59+
token: ${{ secrets.SYNC_TOKEN }}
60+
path: target-docs
61+
fetch-depth: 0
62+
ref: ${{ github.event.pull_request.base.ref }}
63+
64+
- name: Get PR changes
65+
if: steps.check_sync_bot.outputs.skip_sync == 'false'
66+
id: get_changes
67+
run: |
68+
cd devops-pipelines-docs
69+
70+
# Get the merge commit
71+
merge_commit="${{ github.event.pull_request.merge_commit_sha }}"
72+
73+
# Get the base commit (before merge)
74+
base_commit="${{ github.event.pull_request.base.sha }}"
75+
76+
echo "merge_commit=$merge_commit" >> $GITHUB_OUTPUT
77+
echo "base_commit=$base_commit" >> $GITHUB_OUTPUT
78+
79+
# Get list of changed files in the PR
80+
git diff --name-only $base_commit $merge_commit > ../changed_files.txt
81+
82+
echo "📋 Changed files in PR:"
83+
cat ../changed_files.txt
84+
85+
# Check if any documentation files were changed
86+
if grep -E "(^docs/|^README\.md$)" ../changed_files.txt; then
87+
echo "has_doc_changes=true" >> $GITHUB_OUTPUT
88+
echo "✅ Documentation changes detected"
89+
else
90+
echo "has_doc_changes=false" >> $GITHUB_OUTPUT
91+
echo "ℹ️ No documentation changes detected"
92+
fi
93+
94+
- name: Create reverse sync branch
95+
if: steps.check_sync_bot.outputs.skip_sync == 'false' && steps.get_changes.outputs.has_doc_changes == 'true'
96+
id: create_branch
97+
run: |
98+
cd target-docs
99+
100+
# Create a unique branch name
101+
branch_name="reverse-sync/pr-${{ github.event.pull_request.number }}-$(date +%s)"
102+
echo "branch_name=$branch_name" >> $GITHUB_OUTPUT
103+
104+
git checkout -b "$branch_name"
105+
106+
# Configure git
107+
git config user.name "Documentation Sync Bot"
108+
git config user.email "[email protected]"
109+
110+
echo "📝 Created branch: $branch_name"
111+
112+
- name: Apply changes from devops-pipelines-docs
113+
if: steps.check_sync_bot.outputs.skip_sync == 'false' && steps.get_changes.outputs.has_doc_changes == 'true'
114+
run: |
115+
cd devops-pipelines-docs
116+
merge_commit="${{ steps.get_changes.outputs.merge_commit }}"
117+
base_commit="${{ steps.get_changes.outputs.base_commit }}"
118+
119+
# Create a patch with only the documentation changes
120+
git format-patch $base_commit..$merge_commit --stdout -- docs/ README.md > ../changes.patch
121+
122+
cd ../target-docs
123+
124+
# Apply the patch
125+
if [ -s ../changes.patch ]; then
126+
echo "📦 Applying changes from devops-pipelines-docs..."
127+
git apply ../changes.patch || {
128+
echo "⚠️ Patch application failed, trying manual copy..."
129+
130+
# Fallback: manual copy of changed files
131+
while IFS= read -r file; do
132+
if [[ "$file" == docs/* ]] || [[ "$file" == "README.md" ]]; then
133+
if [ -f "../devops-pipelines-docs/$file" ]; then
134+
mkdir -p "$(dirname "$file")"
135+
cp "../devops-pipelines-docs/$file" "$file"
136+
echo "✅ Copied: $file"
137+
fi
138+
fi
139+
done < ../changed_files.txt
140+
}
141+
else
142+
echo "⚠️ No patch generated, using manual copy..."
143+
144+
# Manual copy approach
145+
while IFS= read -r file; do
146+
if [[ "$file" == docs/* ]] || [[ "$file" == "README.md" ]]; then
147+
if [ -f "../devops-pipelines-docs/$file" ]; then
148+
mkdir -p "$(dirname "$file")"
149+
cp "../devops-pipelines-docs/$file" "$file"
150+
echo "✅ Copied: $file"
151+
fi
152+
fi
153+
done < ../changed_files.txt
154+
fi
155+
156+
- name: Commit changes
157+
if: steps.check_sync_bot.outputs.skip_sync == 'false' && steps.get_changes.outputs.has_doc_changes == 'true'
158+
id: commit_changes
159+
run: |
160+
cd target-docs
161+
162+
git add .
163+
164+
if git diff --staged --quiet; then
165+
echo "has_changes=false" >> $GITHUB_OUTPUT
166+
echo "ℹ️ No changes to commit"
167+
else
168+
echo "has_changes=true" >> $GITHUB_OUTPUT
169+
170+
# Create commit message with reverse sync marker
171+
cat > commit_message.txt << EOF
172+
[reverse-sync] Sync documentation changes from devops-pipelines-docs PR #${{ github.event.pull_request.number }}
173+
174+
This commit incorporates changes from external contributors to the devops-pipelines-docs repository.
175+
176+
📋 Original PR Details:
177+
- Title: ${{ github.event.pull_request.title }}
178+
- Author: ${{ github.event.pull_request.user.login }}
179+
- URL: ${{ github.event.pull_request.html_url }}
180+
- Merge commit: ${{ steps.get_changes.outputs.merge_commit }}
181+
182+
🔄 This is a reverse sync commit - it should not trigger forward sync.
183+
EOF
184+
185+
git commit -F commit_message.txt
186+
rm commit_message.txt
187+
188+
echo "✅ Changes committed successfully"
189+
fi
190+
191+
- name: Push branch and create PR
192+
if: steps.check_sync_bot.outputs.skip_sync == 'false' && steps.get_changes.outputs.has_doc_changes == 'true' && steps.commit_changes.outputs.has_changes == 'true'
193+
run: |
194+
cd target-docs
195+
branch_name="${{ steps.create_branch.outputs.branch_name }}"
196+
pr_base_ref="${{ github.event.pull_request.base.ref }}"
197+
198+
# Push the branch
199+
git push origin "$branch_name"
200+
201+
# Create PR body with proper JSON escaping
202+
pr_body=$(cat << 'EOF'
203+
### 🔄 Reverse Sync from devops-pipelines-docs
204+
205+
This PR incorporates documentation changes from external contributors to the devops-pipelines-docs repository.
206+
207+
#### Original PR Details
208+
- **Repository**: alauda/devops-pipelines-docs
209+
- **PR**: #${{ github.event.pull_request.number }} - ${{ github.event.pull_request.title }}
210+
- **Author**: @${{ github.event.pull_request.user.login }}
211+
- **URL**: ${{ github.event.pull_request.html_url }}
212+
213+
#### Changes
214+
This PR includes changes to documentation files that were contributed by external contributors to the public devops-pipelines-docs repository.
215+
216+
#### Important Notes
217+
- ⚠️ This PR contains the `[reverse-sync]` marker to prevent infinite sync loops
218+
- ✅ Once merged, this will NOT trigger a forward sync back to devops-pipelines-docs
219+
- 🔍 Please review the changes to ensure they align with internal documentation standards
220+
221+
---
222+
*This PR was automatically created by the reverse sync workflow.*
223+
EOF)
224+
225+
# Create JSON payload with proper escaping
226+
json_payload=$(jq -n \
227+
--arg title "[reverse-sync] Documentation changes from devops-pipelines-docs PR #${{ github.event.pull_request.number }}" \
228+
--arg head "$branch_name" \
229+
--arg base "$pr_base_ref" \
230+
--arg body "$pr_body" \
231+
'{title: $title, head: $head, base: $base, body: $body}')
232+
233+
# Create the PR using GitHub API
234+
curl -X POST \
235+
-H "Authorization: token ${{ secrets.SYNC_TOKEN }}" \
236+
-H "Accept: application/vnd.github.v3+json" \
237+
-H "Content-Type: application/json" \
238+
https://api.github.com/repos/${{env.TARGET_REPO}}/pulls \
239+
-d "$json_payload"
240+
241+
242+
243+
- name: Create workflow summary
244+
run: |
245+
if [ "${{ steps.check_sync_bot.outputs.skip_sync }}" == "true" ]; then
246+
echo "## 🤖 Sync Bot PR - Reverse Sync Skipped" >> $GITHUB_STEP_SUMMARY
247+
echo "" >> $GITHUB_STEP_SUMMARY
248+
echo "This PR was created by the sync bot, so reverse sync was skipped to prevent loops." >> $GITHUB_STEP_SUMMARY
249+
elif [ "${{ steps.get_changes.outputs.has_doc_changes }}" == "false" ]; then
250+
echo "## ℹ️ No Documentation Changes" >> $GITHUB_STEP_SUMMARY
251+
echo "" >> $GITHUB_STEP_SUMMARY
252+
echo "This PR didn't contain any documentation changes, so no reverse sync was needed." >> $GITHUB_STEP_SUMMARY
253+
elif [ "${{ steps.commit_changes.outputs.has_changes }}" == "false" ]; then
254+
echo "## ℹ️ No Changes to Sync" >> $GITHUB_STEP_SUMMARY
255+
echo "" >> $GITHUB_STEP_SUMMARY
256+
echo "The documentation changes were already present in target-docs." >> $GITHUB_STEP_SUMMARY
257+
else
258+
echo "## 🎉 Reverse Sync Completed" >> $GITHUB_STEP_SUMMARY
259+
echo "" >> $GITHUB_STEP_SUMMARY
260+
echo "Successfully created a PR in target-docs with the documentation changes." >> $GITHUB_STEP_SUMMARY
261+
echo "" >> $GITHUB_STEP_SUMMARY
262+
echo "### Details:" >> $GITHUB_STEP_SUMMARY
263+
echo "- **Source PR**: #${{ github.event.pull_request.number }} by @${{ github.event.pull_request.user.login }}" >> $GITHUB_STEP_SUMMARY
264+
echo "- **Branch**: ${{ steps.create_branch.outputs.branch_name }}" >> $GITHUB_STEP_SUMMARY
265+
echo "- **Base ref**: ${{ github.event.pull_request.base.ref }}" >> $GITHUB_STEP_SUMMARY
266+
echo "- **Target repository**: ${{env.TARGET_REPO}}" >> $GITHUB_STEP_SUMMARY
267+
fi

0 commit comments

Comments
 (0)