forked from 21st-dev/1code
-
Notifications
You must be signed in to change notification settings - Fork 1
195 lines (168 loc) · 7.12 KB
/
sync-fork.yml
File metadata and controls
195 lines (168 loc) · 7.12 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
name: Sync Fork with Upstream Main
on:
schedule:
# Check upstream main every 6 hours
- cron: "0 */6 * * *"
workflow_dispatch:
inputs:
force_build:
description: "Force build even if no upstream changes"
type: boolean
default: false
jobs:
check-upstream:
runs-on: ubuntu-latest
outputs:
has_upstream_changes: ${{ steps.check.outputs.has_upstream_changes }}
latest_upstream_sha: ${{ steps.check.outputs.latest_upstream_sha }}
should_release: ${{ steps.check.outputs.should_release }}
latest_release_tag: ${{ steps.check.outputs.latest_release_tag }}
steps:
- name: Checkout fork
uses: actions/checkout@v4
- name: Check upstream main for new commits
id: check
run: |
git remote add upstream https://github.com/21st-dev/1code.git || true
git fetch --no-tags upstream main
UPSTREAM_SHA=$(git rev-parse upstream/main)
CURRENT_SHA=$(git rev-parse HEAD)
echo "Upstream main SHA: $UPSTREAM_SHA"
echo "Current fork SHA: $CURRENT_SHA"
echo "latest_upstream_sha=$UPSTREAM_SHA" >> $GITHUB_OUTPUT
LATEST_TAG=$(curl -fsSL \
-H "Authorization: Bearer ${{ github.token }}" \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/21st-dev/1code/releases/latest | jq -r '.tag_name // empty')
if [ -z "$LATEST_TAG" ]; then
echo "::error::Could not determine latest upstream release tag from GitHub API."
exit 1
fi
CURRENT_TAG=""
if [ -f ".last-released-upstream-tag" ]; then
CURRENT_TAG=$(cat .last-released-upstream-tag)
fi
echo "Upstream latest release tag: ${LATEST_TAG:-<none>}"
echo "Last released upstream tag in fork: ${CURRENT_TAG:-<none>}"
echo "latest_release_tag=$LATEST_TAG" >> $GITHUB_OUTPUT
if [ "${{ github.event.inputs.force_build }}" == "true" ]; then
echo "Force build requested"
echo "has_upstream_changes=true" >> $GITHUB_OUTPUT
echo "should_release=true" >> $GITHUB_OUTPUT
elif git merge-base --is-ancestor "$UPSTREAM_SHA" "$CURRENT_SHA"; then
echo "Already up to date with upstream/main"
echo "has_upstream_changes=false" >> $GITHUB_OUTPUT
if [ -n "$LATEST_TAG" ] && [ "$LATEST_TAG" != "$CURRENT_TAG" ]; then
echo "New upstream release tag detected"
echo "should_release=true" >> $GITHUB_OUTPUT
else
echo "No new upstream release tag"
echo "should_release=false" >> $GITHUB_OUTPUT
fi
else
echo "Upstream has new commits to sync"
echo "has_upstream_changes=true" >> $GITHUB_OUTPUT
if [ -n "$LATEST_TAG" ] && [ "$LATEST_TAG" != "$CURRENT_TAG" ]; then
echo "New upstream release tag detected"
echo "should_release=true" >> $GITHUB_OUTPUT
else
echo "No new upstream release tag"
echo "should_release=false" >> $GITHUB_OUTPUT
fi
fi
sync-and-build:
needs: check-upstream
if: needs.check-upstream.outputs.has_upstream_changes == 'true'
runs-on: ubuntu-latest
outputs:
sync_success: ${{ steps.sync.outputs.sync_success }}
steps:
- name: Checkout fork
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Configure Git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Add upstream and sync
id: sync
run: |
git remote add upstream https://github.com/21st-dev/1code.git || true
git fetch upstream main
# Try to merge upstream changes
if git merge upstream/main --no-edit; then
echo "Merge successful"
echo "sync_success=true" >> $GITHUB_OUTPUT
else
echo "Merge conflict detected — attempting auto-resolution"
# For conflicted files, prefer our fork's version for fork-specific
# files (README.md) and upstream's version for everything else
CONFLICTED=$(git diff --name-only --diff-filter=U)
RESOLVED=true
for file in $CONFLICTED; do
case "$file" in
README.md)
echo " $file → keeping fork version"
git checkout --ours "$file"
git add "$file"
;;
*)
echo " $file → taking upstream version"
git checkout --theirs "$file"
git add "$file"
;;
esac
done
if $RESOLVED; then
git commit --no-edit
echo "Merge conflicts auto-resolved"
echo "sync_success=true" >> $GITHUB_OUTPUT
else
echo "::warning::Could not auto-resolve merge conflicts."
git merge --abort
echo "sync_success=false" >> $GITHUB_OUTPUT
exit 0
fi
fi
- name: Update last synced version
if: steps.sync.outputs.sync_success == 'true'
run: |
echo "${{ needs.check-upstream.outputs.latest_upstream_sha }}" > .last-synced-version
git add .last-synced-version
git commit -m "Sync with upstream ${{ needs.check-upstream.outputs.latest_upstream_sha }}" || true
- name: Push changes
if: steps.sync.outputs.sync_success == 'true'
run: git push origin main
trigger-build:
needs: [check-upstream, sync-and-build]
if: needs.check-upstream.outputs.should_release == 'true' && (needs['sync-and-build'].result == 'skipped' || needs['sync-and-build'].outputs.sync_success == 'true')
uses: ./.github/workflows/build-release.yml
with:
release_version: ${{ needs.check-upstream.outputs.latest_release_tag }}
secrets: inherit
mark-release-tag:
needs: [check-upstream, trigger-build]
if: needs.trigger-build.result == 'success' && needs.check-upstream.outputs.latest_release_tag != ''
runs-on: ubuntu-latest
steps:
- name: Checkout fork
uses: actions/checkout@v4
with:
ref: main
token: ${{ secrets.GITHUB_TOKEN }}
- name: Configure Git
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
- name: Pull latest (sync-and-build may have pushed)
run: git pull --rebase origin main
- name: Update last released upstream tag marker
run: |
echo "${{ needs.check-upstream.outputs.latest_release_tag }}" > .last-released-upstream-tag
git add .last-released-upstream-tag
git commit -m "Mark upstream release ${{ needs.check-upstream.outputs.latest_release_tag }} as built" || true
- name: Push tag marker
run: git push origin main