-
Notifications
You must be signed in to change notification settings - Fork 83
453 lines (369 loc) · 19.1 KB
/
update-dependencies.yml
File metadata and controls
453 lines (369 loc) · 19.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
name: Update Intercom SDK Dependencies
on:
schedule:
# Run daily at 9 AM UTC
- cron: '0 9 * * *'
workflow_dispatch:
jobs:
update-dependencies:
runs-on: macos-latest
permissions:
contents: write
pull-requests: write
issues: read
actions: read
steps:
- name: 🔍 Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: ⚙️ Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22.14.0'
- name: 📦 Enable Corepack and install dependencies
run: |
corepack enable
yarn install --immutable
- name: 🔍 Get current dependency versions
id: current-versions
run: |
# Extract current iOS version from podspec
IOS_VERSION=$(grep -E "s\.dependency.*Intercom" intercom-react-native.podspec | sed -E "s/.*'([^']+)'.*/\1/" | sed 's/~> //')
# Extract current Android version from build.gradle
ANDROID_VERSION=$(grep -E "io\.intercom\.android:intercom-sdk:" android/build.gradle | head -1 | sed -E "s/.*:([^']+)'.*/\1/")
echo "📱 Current iOS SDK: $IOS_VERSION"
echo "🤖 Current Android SDK: $ANDROID_VERSION"
echo "ios_version=$IOS_VERSION" >> $GITHUB_OUTPUT
echo "android_version=$ANDROID_VERSION" >> $GITHUB_OUTPUT
- name: 🚀 Get latest SDK releases
id: latest-versions
run: |
echo "🔄 Fetching latest releases..."
# Get iOS release
IOS_RELEASE=$(curl -s https://api.github.com/repos/intercom/intercom-ios/releases/latest)
IOS_VERSION=$(echo "$IOS_RELEASE" | jq -r '.tag_name // "null"')
IOS_CHANGELOG=$(echo "$IOS_RELEASE" | jq -r '.body // "No changelog available"')
# Get Android release
ANDROID_RELEASE=$(curl -s https://api.github.com/repos/intercom/intercom-android/releases/latest)
ANDROID_VERSION=$(echo "$ANDROID_RELEASE" | jq -r '.tag_name // "null"')
ANDROID_CHANGELOG=$(echo "$ANDROID_RELEASE" | jq -r '.body // "No changelog available"')
echo "📱 Latest iOS SDK: $IOS_VERSION"
echo "🤖 Latest Android SDK: $ANDROID_VERSION"
echo "ios_version=$IOS_VERSION" >> $GITHUB_OUTPUT
echo "android_version=$ANDROID_VERSION" >> $GITHUB_OUTPUT
echo "ios_changelog<<EOF" >> $GITHUB_OUTPUT
echo "$IOS_CHANGELOG" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
echo "android_changelog<<EOF" >> $GITHUB_OUTPUT
echo "$ANDROID_CHANGELOG" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: 🧮 Analyze update requirements
id: update-analysis
run: |
CURRENT_IOS="${{ steps.current-versions.outputs.ios_version }}"
LATEST_IOS="${{ steps.latest-versions.outputs.ios_version }}"
CURRENT_ANDROID="${{ steps.current-versions.outputs.android_version }}"
LATEST_ANDROID="${{ steps.latest-versions.outputs.android_version }}"
echo "📊 Version Analysis:"
echo " iOS: $CURRENT_IOS → $LATEST_IOS"
echo " Android: $CURRENT_ANDROID → $LATEST_ANDROID"
# Determine updates needed
IOS_NEEDS_UPDATE=false
ANDROID_NEEDS_UPDATE=false
OVERALL_UPDATE_NEEDED=false
# Check iOS
if [ "$LATEST_IOS" != "null" ] && [ -n "$LATEST_IOS" ]; then
CURRENT_IOS_CLEAN=$(echo "$CURRENT_IOS" | sed 's/^v//')
LATEST_IOS_CLEAN=$(echo "$LATEST_IOS" | sed 's/^v//')
if [ "$CURRENT_IOS_CLEAN" != "$LATEST_IOS_CLEAN" ]; then
IOS_NEEDS_UPDATE=true
OVERALL_UPDATE_NEEDED=true
echo "✅ iOS update needed: $CURRENT_IOS_CLEAN → $LATEST_IOS_CLEAN"
else
echo "ℹ️ iOS already up to date"
fi
else
echo "⚠️ No iOS release available - skipping"
LATEST_IOS_CLEAN="null"
fi
# Check Android
if [ "$LATEST_ANDROID" != "null" ] && [ -n "$LATEST_ANDROID" ]; then
CURRENT_ANDROID_CLEAN=$(echo "$CURRENT_ANDROID" | sed 's/^v//')
LATEST_ANDROID_CLEAN=$(echo "$LATEST_ANDROID" | sed 's/^v//')
if [ "$CURRENT_ANDROID_CLEAN" != "$LATEST_ANDROID_CLEAN" ]; then
ANDROID_NEEDS_UPDATE=true
OVERALL_UPDATE_NEEDED=true
echo "✅ Android update needed: $CURRENT_ANDROID_CLEAN → $LATEST_ANDROID_CLEAN"
else
echo "ℹ️ Android already up to date"
fi
else
echo "⚠️ No Android release available - skipping"
LATEST_ANDROID_CLEAN="null"
fi
# Output results
echo "ios_needs_update=$IOS_NEEDS_UPDATE" >> $GITHUB_OUTPUT
echo "android_needs_update=$ANDROID_NEEDS_UPDATE" >> $GITHUB_OUTPUT
echo "overall_update_needed=$OVERALL_UPDATE_NEEDED" >> $GITHUB_OUTPUT
echo "ios_new_version=${LATEST_IOS_CLEAN:-null}" >> $GITHUB_OUTPUT
echo "android_new_version=${LATEST_ANDROID_CLEAN:-null}" >> $GITHUB_OUTPUT
if [ "$OVERALL_UPDATE_NEEDED" = false ]; then
echo "🎯 No updates needed - workflow will exit cleanly"
fi
- name: 🔍 Check existing PRs
if: steps.update-analysis.outputs.overall_update_needed == 'true'
id: pr-analysis
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
TARGET_IOS="${{ steps.update-analysis.outputs.ios_new_version }}"
TARGET_ANDROID="${{ steps.update-analysis.outputs.android_new_version }}"
IOS_NEEDS_UPDATE="${{ steps.update-analysis.outputs.ios_needs_update }}"
ANDROID_NEEDS_UPDATE="${{ steps.update-analysis.outputs.android_needs_update }}"
echo "🔍 Checking for existing dependency PRs..."
echo " Target: iOS=$TARGET_IOS, Android=$TARGET_ANDROID"
# Find existing PRs
EXISTING_PRS=$(gh pr list --state open --search "update Intercom SDK dependencies" --json number,title,headRefName 2>/dev/null || echo "[]")
if [ "$EXISTING_PRS" = "[]" ] || [ "$(echo "$EXISTING_PRS" | jq 'length')" -eq 0 ]; then
echo "✅ No existing PRs found - proceeding with update"
echo "should_create_pr=true" >> $GITHUB_OUTPUT
exit 0
fi
echo "📋 Found existing dependency PRs:"
echo "$EXISTING_PRS" | jq -r '.[] | " PR #\(.number): \(.title)"'
SHOULD_CREATE_PR=true
# Analyze each existing PR
for pr_data in $(echo "$EXISTING_PRS" | jq -r '.[] | @base64'); do
PR_INFO=$(echo "$pr_data" | base64 --decode)
PR_NUMBER=$(echo "$PR_INFO" | jq -r '.number')
PR_TITLE=$(echo "$PR_INFO" | jq -r '.title')
PR_BRANCH=$(echo "$PR_INFO" | jq -r '.headRefName')
echo "🔍 Analyzing PR #$PR_NUMBER: $PR_TITLE"
# Check if this PR already targets our exact versions
IOS_MATCHES=true
ANDROID_MATCHES=true
if [ "$IOS_NEEDS_UPDATE" = "true" ]; then
if echo "$PR_TITLE" | grep -q "iOS:.*→"; then
EXISTING_IOS_TARGET=$(echo "$PR_TITLE" | sed -n 's/.*iOS:[^→]*→ *\([^,)]*\).*/\1/p' | tr -d ' ')
if [ "$EXISTING_IOS_TARGET" != "$TARGET_IOS" ]; then
IOS_MATCHES=false
echo " 📱 iOS version mismatch: PR has $EXISTING_IOS_TARGET, need $TARGET_IOS"
fi
else
IOS_MATCHES=false
fi
fi
if [ "$ANDROID_NEEDS_UPDATE" = "true" ]; then
if echo "$PR_TITLE" | grep -q "Android:.*→"; then
EXISTING_ANDROID_TARGET=$(echo "$PR_TITLE" | sed -n 's/.*Android:[^→]*→ *\([^,)]*\).*/\1/p' | tr -d ' ')
if [ "$EXISTING_ANDROID_TARGET" != "$TARGET_ANDROID" ]; then
ANDROID_MATCHES=false
echo " 🤖 Android version mismatch: PR has $EXISTING_ANDROID_TARGET, need $TARGET_ANDROID"
fi
else
ANDROID_MATCHES=false
fi
fi
# Decision logic
if [ "$IOS_MATCHES" = true ] && [ "$ANDROID_MATCHES" = true ]; then
echo " 🎯 PR #$PR_NUMBER already targets correct versions - no action needed"
SHOULD_CREATE_PR=false
break
else
echo " 🗑️ Closing outdated PR #$PR_NUMBER"
gh pr close "$PR_NUMBER" --comment "Closing this PR as newer SDK versions are available. A new PR will be created with the latest versions." || true
if [ "$PR_BRANCH" != "null" ] && [ "$PR_BRANCH" != "main" ]; then
echo " 🗑️ Deleting branch: $PR_BRANCH"
git push origin --delete "$PR_BRANCH" 2>/dev/null || true
fi
fi
done
echo "should_create_pr=$SHOULD_CREATE_PR" >> $GITHUB_OUTPUT
if [ "$SHOULD_CREATE_PR" = true ]; then
echo "🚀 Ready to create new PR"
else
echo "⏭️ Skipping PR creation - existing PR is current"
fi
- name: 🔧 Setup Ruby for CocoaPods
if: steps.update-analysis.outputs.overall_update_needed == 'true' && steps.pr-analysis.outputs.should_create_pr == 'true'
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: 🛠️ Create update branch
if: steps.update-analysis.outputs.overall_update_needed == 'true' && steps.pr-analysis.outputs.should_create_pr == 'true'
id: create-branch
run: |
# Configure git
git config --global user.name 'github-actions[bot]'
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
# Create unique branch
BRANCH_NAME="update-intercom-sdks-$(date +%Y%m%d-%H%M%S)"
git checkout -b "$BRANCH_NAME"
echo "🌿 Created branch: $BRANCH_NAME"
echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT
- name: 📝 Update dependency files
if: steps.update-analysis.outputs.overall_update_needed == 'true' && steps.pr-analysis.outputs.should_create_pr == 'true'
id: update-files
run: |
CHANGES=""
PR_TITLE_PARTS=""
# Update iOS if needed
if [ "${{ steps.update-analysis.outputs.ios_needs_update }}" = "true" ]; then
NEW_IOS="${{ steps.update-analysis.outputs.ios_new_version }}"
OLD_IOS="${{ steps.current-versions.outputs.ios_version }}"
echo "📱 Updating iOS SDK: $OLD_IOS → $NEW_IOS"
sed -i '' "s/s\.dependency \"Intercom\", '~> [^']*'/s.dependency \"Intercom\", '~> $NEW_IOS'/" intercom-react-native.podspec
CHANGES="$CHANGES\\n- Updated iOS SDK from $OLD_IOS to $NEW_IOS"
PR_TITLE_PARTS="iOS: $OLD_IOS → $NEW_IOS"
git add intercom-react-native.podspec
fi
# Update Android if needed
if [ "${{ steps.update-analysis.outputs.android_needs_update }}" = "true" ]; then
NEW_ANDROID="${{ steps.update-analysis.outputs.android_new_version }}"
OLD_ANDROID="${{ steps.current-versions.outputs.android_version }}"
echo "🤖 Updating Android SDK: $OLD_ANDROID → $NEW_ANDROID"
sed -i '' "s/io\.intercom\.android:intercom-sdk:[^']*/io.intercom.android:intercom-sdk:$NEW_ANDROID/" android/build.gradle
sed -i '' "s/io\.intercom\.android:intercom-sdk-ui:[^']*/io.intercom.android:intercom-sdk-ui:$NEW_ANDROID/" android/build.gradle
CHANGES="$CHANGES\\n- Updated Android SDK from $OLD_ANDROID to $NEW_ANDROID"
if [ -n "$PR_TITLE_PARTS" ]; then
PR_TITLE_PARTS="$PR_TITLE_PARTS, Android: $OLD_ANDROID → $NEW_ANDROID"
else
PR_TITLE_PARTS="Android: $OLD_ANDROID → $NEW_ANDROID"
fi
git add android/build.gradle
fi
# Determine version bump type using semver script
echo "📈 Analyzing version bump requirements..."
VERSION_BUMP_TYPE=$(node semver.js analyze \
"${{ steps.current-versions.outputs.ios_version }}" \
"${{ steps.update-analysis.outputs.ios_new_version }}" \
"${{ steps.current-versions.outputs.android_version }}" \
"${{ steps.update-analysis.outputs.android_new_version }}")
# Get current version and increment using semver script
echo "📈 Applying $VERSION_BUMP_TYPE version bump..."
CURRENT_VERSION=$(node semver.js current)
NEW_VERSION=$(node semver.js inc "$CURRENT_VERSION" "$VERSION_BUMP_TYPE")
# Update package.json version using semver script
node semver.js update "$NEW_VERSION"
echo "📈 Version bumped ($VERSION_BUMP_TYPE): $CURRENT_VERSION → $NEW_VERSION"
git add package.json semver.js
# Update yarn.lock
echo "📦 Installing dependencies to update lockfile..."
yarn install --immutable
git add yarn.lock
# find pnpm-lock.yaml in examples and if present run pnpm install
PNPM_EXAMPLE_DIRS=$(find examples -name "pnpm-lock.yaml" -exec dirname {} \; | head -5)
for dir in $PNPM_EXAMPLE_DIRS; do
echo "📦 Installing dependencies to update lockfile..."
cd "$dir"
corepack install
corepack enable
pnpm install
git add pnpm-lock.yaml
cd - > /dev/null
done
CHANGES="$CHANGES\\n- Bumped version from $CURRENT_VERSION to $NEW_VERSION ($VERSION_BUMP_TYPE)"
# Store for next steps
echo "changes<<EOF" >> $GITHUB_OUTPUT
echo -e "$CHANGES" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
echo "pr_title_parts=$PR_TITLE_PARTS" >> $GITHUB_OUTPUT
- name: 📦 Update iOS Example Pod Dependencies
if: steps.update-analysis.outputs.overall_update_needed == 'true' && steps.pr-analysis.outputs.should_create_pr == 'true' && steps.update-analysis.outputs.ios_needs_update == 'true'
run: |
# Find iOS example directories with Podfiles excluding node_modules
IOS_EXAMPLE_DIRS=$(find examples -name "Podfile" -exec dirname {} \; | grep -E "(ios|example)" | grep -v "node_modules" | head -5)
for dir in $IOS_EXAMPLE_DIRS; do
bundle install || echo "Gemfile not found in $dir"
if [ -f "$dir/Podfile" ]; then
echo "📱 Updating pods in $dir"
cd "$dir"
bundle exec pod install --repo-update || pod install --repo-update || pod update Intercom || echo "Pod install failed in $dir"
cd - > /dev/null
# Add any updated Podfile.lock files
git add "$dir/Podfile.lock" 2>/dev/null || true
fi
done
- name: 💾 Commit and push changes
if: steps.update-analysis.outputs.overall_update_needed == 'true' && steps.pr-analysis.outputs.should_create_pr == 'true'
run: |
# Check if we have changes to commit
if git diff --cached --quiet; then
echo "❌ No changes to commit - this should not happen!"
exit 1
fi
echo "💾 Committing changes..."
git commit -m "chore: update Intercom SDK dependencies (${{ steps.update-files.outputs.pr_title_parts }})
${{ steps.update-files.outputs.changes }}
- Updated lockfiles and example projects"
echo "🚀 Pushing branch: ${{ steps.create-branch.outputs.branch_name }}"
git push origin "${{ steps.create-branch.outputs.branch_name }}"
- name: 🎯 Create Pull Request
if: steps.update-analysis.outputs.overall_update_needed == 'true' && steps.pr-analysis.outputs.should_create_pr == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "🎯 Creating pull request..."
# Build PR description
cat > pr_body.md << 'EOF'
## 🔄 Automated Intercom SDK Dependency Update
This PR updates the Intercom SDK dependencies to their latest versions.
### 📋 Changes Made:
${{ steps.update-files.outputs.changes }}
### 📚 Release Notes:
EOF
# Add iOS release notes if updated
if [ "${{ steps.update-analysis.outputs.ios_needs_update }}" = "true" ]; then
cat >> pr_body.md << 'EOF'
#### 📱 iOS SDK ${{ steps.update-analysis.outputs.ios_new_version }}
[View Release Notes](https://github.com/intercom/intercom-ios/releases/tag/${{ steps.latest-versions.outputs.ios_version }})
```
${{ steps.latest-versions.outputs.ios_changelog }}
```
EOF
fi
# Add Android release notes if updated
if [ "${{ steps.update-analysis.outputs.android_needs_update }}" = "true" ]; then
cat >> pr_body.md << 'EOF'
#### 🤖 Android SDK ${{ steps.update-analysis.outputs.android_new_version }}
[View Release Notes](https://github.com/intercom/intercom-android/releases/tag/${{ steps.latest-versions.outputs.android_version }})
```
${{ steps.latest-versions.outputs.android_changelog }}
```
EOF
fi
cat >> pr_body.md << 'EOF'
---
🤖 This PR was automatically created by the [Update Dependencies workflow](.github/workflows/update-dependencies.yml).
EOF
# Create PR
if gh pr create \
--title "chore: update Intercom SDK dependencies (${{ steps.update-files.outputs.pr_title_parts }})" \
--body-file pr_body.md \
--head "${{ steps.create-branch.outputs.branch_name }}" \
--base "main"; then
echo "✅ Pull request created successfully!"
else
echo "❌ Failed to create pull request"
echo "📋 Branch pushed: ${{ steps.create-branch.outputs.branch_name }}"
echo "📋 Title: chore: update Intercom SDK dependencies (${{ steps.update-files.outputs.pr_title_parts }})"
exit 1
fi
- name: 📊 Summary
if: always()
run: |
echo "## 📊 Workflow Summary"
if [ "${{ steps.update-analysis.outputs.overall_update_needed }}" != "true" ]; then
echo "ℹ️ No dependency updates needed - all SDKs are current"
echo " 📱 iOS: ${{ steps.current-versions.outputs.ios_version }}"
echo " 🤖 Android: ${{ steps.current-versions.outputs.android_version }}"
elif [ "${{ steps.pr-analysis.outputs.should_create_pr }}" != "true" ]; then
echo "⏭️ Updates available but existing PR already covers latest versions"
elif [ "${{ job.status }}" = "success" ]; then
echo "✅ Successfully created dependency update PR!"
echo " 📋 Title: chore: update Intercom SDK dependencies (${{ steps.update-files.outputs.pr_title_parts }})"
echo " 🌿 Branch: ${{ steps.create-branch.outputs.branch_name }}"
else
echo "❌ Workflow failed - check logs above"
fi