Skip to content

Commit ff75688

Browse files
authored
Merge pull request #153 from DDMAL/ci-sync-upstream
add workflow for syncing with `rism-digital/develop` changes
2 parents 4624022 + 1c262ea commit ff75688

File tree

1 file changed

+199
-0
lines changed

1 file changed

+199
-0
lines changed
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
name: Sync with RISM Upstream
2+
3+
on:
4+
# Run automatically every Monday at 07:00 UTC (3am in Montreal)
5+
schedule:
6+
- cron: "0 7 * * 1"
7+
8+
# Allow manual triggering
9+
workflow_dispatch:
10+
inputs:
11+
force_rebase:
12+
description: "Force rebase even if no new commits detected"
13+
required: false
14+
default: false
15+
type: boolean
16+
17+
jobs:
18+
sync-upstream:
19+
runs-on: ubuntu-latest
20+
# Only run this workflow on the DDMAL/verovio repository
21+
if: github.repository == 'DDMAL/verovio'
22+
23+
steps:
24+
- name: Checkout repository
25+
uses: actions/checkout@v4
26+
with:
27+
# Fetch full history for proper rebasing
28+
fetch-depth: 0
29+
# Use a personal access token with repo permissions
30+
token: ${{ secrets.GITHUB_TOKEN }}
31+
ref: develop
32+
33+
- name: Configure Git
34+
run: |
35+
git config user.name "github-actions[bot]"
36+
git config user.email "github-actions[bot]@users.noreply.github.com"
37+
38+
- name: Add upstream remote
39+
run: |
40+
# Check if upstream remote already exists
41+
if git remote get-url upstream 2>/dev/null; then
42+
echo "Upstream remote already exists"
43+
git remote set-url upstream https://github.com/rism-digital/verovio.git
44+
else
45+
echo "Adding upstream remote"
46+
git remote add upstream https://github.com/rism-digital/verovio.git
47+
fi
48+
49+
- name: Fetch upstream changes
50+
run: |
51+
echo "Fetching upstream changes..."
52+
git fetch upstream develop
53+
54+
- name: Check for new commits
55+
id: check_commits
56+
run: |
57+
# Get the latest commit hash from upstream
58+
UPSTREAM_COMMIT=$(git rev-parse upstream/develop)
59+
60+
# Get the latest commit hash from our develop branch
61+
LOCAL_COMMIT=$(git rev-parse develop)
62+
63+
echo "Upstream commit: $UPSTREAM_COMMIT"
64+
echo "Local commit: $LOCAL_COMMIT"
65+
66+
# Check if there are new commits to sync
67+
if [ "$UPSTREAM_COMMIT" != "$LOCAL_COMMIT" ]; then
68+
echo "new_commits=true" >> $GITHUB_OUTPUT
69+
echo "New commits detected in upstream"
70+
71+
# Count the number of commits behind
72+
COMMITS_BEHIND=$(git rev-list --count develop..upstream/develop)
73+
echo "commits_behind=$COMMITS_BEHIND" >> $GITHUB_OUTPUT
74+
echo "Local branch is $COMMITS_BEHIND commits behind upstream"
75+
else
76+
echo "new_commits=false" >> $GITHUB_OUTPUT
77+
echo "No new commits in upstream"
78+
echo "commits_behind=0" >> $GITHUB_OUTPUT
79+
fi
80+
81+
- name: Check for local uncommitted changes
82+
# It's a good practice to check if the runner is in a dirty state before running a rebase
83+
if: steps.check_commits.outputs.new_commits == 'true' || github.event.inputs.force_rebase == 'true'
84+
run: |
85+
if [ -n "$(git status --porcelain)" ]; then
86+
echo "Error: Working directory has uncommitted changes"
87+
git status
88+
exit 1
89+
fi
90+
91+
- name: Rebase onto upstream
92+
if: steps.check_commits.outputs.new_commits == 'true' || github.event.inputs.force_rebase == 'true'
93+
run: |
94+
echo "Starting rebase onto upstream/develop..."
95+
96+
# Attempt to rebase
97+
if git rebase upstream/develop; then
98+
echo "✅ Rebase successful!"
99+
else
100+
echo "❌ Rebase failed due to conflicts"
101+
echo "Aborting rebase..."
102+
git rebase --abort
103+
104+
# Create an issue to notify about the conflict
105+
echo "REBASE_FAILED=true" >> $GITHUB_ENV
106+
exit 1
107+
fi
108+
109+
- name: Push rebased changes
110+
if: (steps.check_commits.outputs.new_commits == 'true' || github.event.inputs.force_rebase == 'true') && env.REBASE_FAILED != 'true'
111+
# force-with-lease is used to avoid overwriting changes that have been pushed and not yet merged to upstream
112+
run: |
113+
echo "Pushing rebased changes to origin/develop..."
114+
git push --force-with-lease origin develop
115+
116+
- name: Create issue on rebase failure
117+
if: env.REBASE_FAILED == 'true'
118+
uses: actions/github-script@v7
119+
with:
120+
script: |
121+
const title = `🚨 Verovio Upstream Sync Failed - Rebase Conflicts Detected`;
122+
const body = `## Automatic upstream sync failed in DDMAL/verovio
123+
124+
The scheduled rebase onto \`rism-digital/verovio:develop\` failed due to merge conflicts.
125+
126+
**Details:**
127+
- Repository: ${{ github.repository }}
128+
- Upstream commits to sync: ${{ steps.check_commits.outputs.commits_behind }}
129+
- Workflow run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
130+
131+
**Manual action required:**
132+
1. Go to the DDMAL/verovio repository
133+
2. Fetch the latest upstream changes: \`git fetch upstream develop\`
134+
3. Rebase manually: \`git rebase upstream/develop\`
135+
4. Resolve any conflicts
136+
5. Push the rebased branch: \`git push --force-with-lease origin develop\`
137+
138+
This issue will be automatically closed when the next successful sync occurs.`;
139+
140+
// Check if an issue already exists in DDMAL/Neon
141+
const existingIssues = await github.rest.issues.listForRepo({
142+
owner: 'DDMAL',
143+
repo: 'Neon',
144+
labels: ['verovio-upstream-sync-failure'],
145+
state: 'open'
146+
});
147+
148+
if (existingIssues.data.length === 0) {
149+
await github.rest.issues.create({
150+
owner: 'DDMAL',
151+
repo: 'Neon',
152+
title: title,
153+
body: body,
154+
labels: ['verovio-upstream-sync-failure', 'automation']
155+
});
156+
}
157+
158+
- name: Close existing sync failure issues
159+
if: (steps.check_commits.outputs.new_commits == 'true' || github.event.inputs.force_rebase == 'true') && env.REBASE_FAILED != 'true'
160+
uses: actions/github-script@v7
161+
with:
162+
script: |
163+
// Close any existing upstream sync failure issues in DDMAL/Neon
164+
const existingIssues = await github.rest.issues.listForRepo({
165+
owner: 'DDMAL',
166+
repo: 'Neon',
167+
labels: ['verovio-upstream-sync-failure'],
168+
state: 'open'
169+
});
170+
171+
for (const issue of existingIssues.data) {
172+
await github.rest.issues.createComment({
173+
owner: 'DDMAL',
174+
repo: 'Neon',
175+
issue_number: issue.number,
176+
body: '✅ Verovio upstream sync completed successfully. Closing this issue.'
177+
});
178+
179+
await github.rest.issues.update({
180+
owner: 'DDMAL',
181+
repo: 'Neon',
182+
issue_number: issue.number,
183+
state: 'closed'
184+
});
185+
}
186+
187+
- name: Summary
188+
run: |
189+
if [ "${{ steps.check_commits.outputs.new_commits }}" = "true" ] || [ "${{ github.event.inputs.force_rebase }}" = "true" ]; then
190+
if [ "$REBASE_FAILED" = "true" ]; then
191+
echo "❌ Sync failed due to rebase conflicts"
192+
echo "📝 An issue has been created for manual intervention"
193+
else
194+
echo "✅ Successfully synced ${{ steps.check_commits.outputs.commits_behind }} commits from upstream"
195+
echo "🚀 Changes pushed to develop branch"
196+
fi
197+
else
198+
echo "ℹ️ No new commits to sync"
199+
fi

0 commit comments

Comments
 (0)