@@ -17,93 +17,161 @@ jobs:
1717 name : Merge main into preview
1818 runs-on : ubuntu-latest
1919 steps :
20+ - name : Generate GitHub App Token
21+ id : app-token
22+ uses : actions/create-github-app-token@v1
23+ with :
24+ app-id : ${{ vars.APP_ID }}
25+ private-key : ${{ secrets.APP_PRIVATE_KEY }}
26+
2027 - name : Checkout preview
2128 uses : actions/checkout@v6
2229 with :
2330 ref : preview
2431 fetch-depth : 0
32+ token : ${{ steps.app-token.outputs.token }}
2533
2634 - name : Configure git
2735 run : |
2836 git config --global user.name "github-actions[bot]"
2937 git config --global user.email "github-actions[bot]@users.noreply.github.com"
3038
31- - name : Merge main into preview
32- id : merge
39+ - name : Check if sync needed
40+ id : check
3341 run : |
3442 git fetch origin main
3543 MAIN_SHA=$(git rev-parse origin/main)
3644 MERGE_BASE=$(git merge-base HEAD origin/main)
3745
3846 if [[ "$MAIN_SHA" == "$MERGE_BASE" ]]; then
3947 echo "✅ preview already contains all of main"
40- echo "status=up-to-date" >> $GITHUB_OUTPUT
41- exit 0
48+ echo "needed=false" >> $GITHUB_OUTPUT
49+ else
50+ echo "needed=true" >> $GITHUB_OUTPUT
4251 fi
4352
44- echo "ℹ️ Merging main into preview..."
53+ - name : Skip if already synced
54+ if : steps.check.outputs.needed == 'false'
55+ run : echo "Nothing to sync."
56+
57+ - name : Merge main into preview
58+ if : steps.check.outputs.needed == 'true'
59+ id : merge
60+ run : |
61+ # Save preview's version before merge so we can restore it after
62+ PREVIEW_VERSION=$(node -p "require('./package.json').version")
63+ echo "preview_version=$PREVIEW_VERSION" >> $GITHUB_OUTPUT
4564
4665 if git merge origin/main --no-edit -m "chore: merge main into preview"; then
47- git push origin preview
48- echo "✅ main merged into preview and pushed"
49- echo "status=merged" >> $GITHUB_OUTPUT
66+ echo "status=clean" >> $GITHUB_OUTPUT
5067 else
51- git merge --abort
52- echo "status=conflict" >> $GITHUB_OUTPUT
68+ # preview carries a higher version string than main (e.g. 1.0.0-preview.X vs 0.13.X).
69+ # This means package.json/package-lock.json almost always conflict on the version field.
70+ # Accept main's content here; the version is restored in the next step.
71+ for f in package.json package-lock.json; do
72+ if git diff --name-only --diff-filter=U | grep -qx "$f"; then
73+ git checkout --theirs "$f"
74+ git add "$f"
75+ echo " ↳ resolved $f conflict (accepted main, will restore version)"
76+ fi
77+ done
78+
79+ # Check if all conflicts are now resolved
80+ if [[ -z "$(git diff --name-only --diff-filter=U)" ]]; then
81+ git commit --no-edit -m "chore: merge main into preview"
82+ echo "status=clean" >> $GITHUB_OUTPUT
83+ else
84+ echo "status=conflict" >> $GITHUB_OUTPUT
85+ fi
5386 fi
5487
55- - name : Get original commit author
56- if : steps.merge.outputs.status == 'conflict'
57- id : author
88+ - name : Restore preview-owned files
89+ if : steps.merge.outputs.status == 'clean'
5890 run : |
59- AUTHOR=$(git log origin/main -1 --format='%an')
60- GH_USER=$(git log origin/main -1 --format='%ae' | grep -oP '.*(?=@users\.noreply\.github\.com)' || echo "")
61- if [[ -z "$GH_USER" ]]; then
62- # Try to get GitHub username from the commit
63- GH_USER=$(gh api "/repos/${{ github.repository }}/commits/$(git rev-parse origin/main)" --jq '.author.login // empty' 2>/dev/null || echo "")
91+ # These files are auto-generated during preview releases and must not
92+ # be overwritten by main's versions (schema-check CI will reject changes
93+ # to schemas/, and CHANGELOG.md tracks preview releases separately).
94+ PREVIEW_HEAD=$(git rev-parse HEAD^1)
95+ for f in schemas/agentcore.schema.v1.json CHANGELOG.md; do
96+ if git show "$PREVIEW_HEAD:$f" > /dev/null 2>&1; then
97+ git show "$PREVIEW_HEAD:$f" > "$f"
98+ git add "$f"
99+ echo " ↳ restored preview's $f"
100+ fi
101+ done
102+ if ! git diff --cached --quiet; then
103+ git commit -m "chore: restore preview-owned files (schema, changelog)"
64104 fi
65- echo "name=$AUTHOR" >> $GITHUB_OUTPUT
66- echo "gh_user=$GH_USER" >> $GITHUB_OUTPUT
67- env :
68- GH_TOKEN : ${{ github.token }}
105+
106+ - name : Restore preview version and push
107+ if : steps.merge.outputs.status == 'clean'
108+ run : |
109+ PREVIEW_VERSION="${{ steps.merge.outputs.preview_version }}"
110+ CURRENT_VERSION=$(node -p "require('./package.json').version")
111+
112+ if [[ "$CURRENT_VERSION" != "$PREVIEW_VERSION" ]]; then
113+ PREVIEW_VERSION="$PREVIEW_VERSION" node -e "
114+ const fs = require('fs');
115+ const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
116+ pkg.version = process.env.PREVIEW_VERSION;
117+ fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
118+ "
119+ if [[ -f package-lock.json ]]; then
120+ PREVIEW_VERSION="$PREVIEW_VERSION" node -e "
121+ const fs = require('fs');
122+ const lock = JSON.parse(fs.readFileSync('package-lock.json', 'utf8'));
123+ lock.version = process.env.PREVIEW_VERSION;
124+ if (lock.packages && lock.packages['']) {
125+ lock.packages[''].version = process.env.PREVIEW_VERSION;
126+ }
127+ fs.writeFileSync('package-lock.json', JSON.stringify(lock, null, 2) + '\n');
128+ "
129+ fi
130+ git add package.json
131+ [[ -f package-lock.json ]] && git add package-lock.json
132+ git commit -m "chore: restore preview version ($PREVIEW_VERSION)"
133+ fi
134+
135+ git push origin HEAD:preview
136+ echo "✅ main merged into preview and pushed"
69137
70138 - name : Create PR for conflict resolution
71139 if : steps.merge.outputs.status == 'conflict'
72140 env :
73- GH_TOKEN : ${{ github.token }}
74- AUTHOR_NAME : ${{ steps.author.outputs.name }}
75- AUTHOR_GH : ${{ steps.author.outputs.gh_user }}
141+ GH_TOKEN : ${{ steps.app-token.outputs.token }}
76142 run : |
77- BRANCH="sync-preview/merge-main-$(date +%Y%m%d-%H%M%S)"
78-
79- # Check if there's already an open sync PR
80- EXISTING=$(gh pr list --base preview --search "sync-preview: merge main into preview" --state open --json number --jq 'length')
81- if [[ "$EXISTING" != "0" ]]; then
143+ # Check if there's already an open sync PR (match by branch prefix, not title search)
144+ COUNT=$(gh pr list --base preview --state open --json headRefName \
145+ --jq '[.[] | select(.headRefName | startswith("sync-preview/"))] | length')
146+ if [[ "$COUNT" != "0" ]]; then
82147 echo "ℹ️ Sync PR already open — skipping duplicate."
83148 exit 0
84149 fi
85150
86- # Create a branch from preview with the conflict markers
151+ # Abort the failed merge and redo on a branch for the PR
152+ git merge --abort
153+
154+ BRANCH="sync-preview/merge-main-$(date +%Y%m%d-%H%M%S)"
87155 git checkout -b "$BRANCH"
88- git merge origin/main --no-edit -m "chore: merge main into preview" || true
156+ git merge origin/main --no-edit -m "chore: merge main into preview (conflicts need resolution) " || true
89157 git add -A
90158 git commit --no-edit -m "chore: merge main into preview (conflicts need resolution)" || true
91159 git push origin "$BRANCH"
92160
93- # Build mention string
161+ GH_USER=$(gh api "/repos/${{ github.repository }}/commits/$(git rev-parse origin/main)" --jq '.author.login // empty' 2>/dev/null || echo "")
94162 MENTION=""
95- if [[ -n "$AUTHOR_GH " ]]; then
96- MENTION="cc @${AUTHOR_GH }"
163+ if [[ -n "$GH_USER " ]]; then
164+ MENTION="cc @${GH_USER }"
97165 fi
98166
99167 gh pr create \
100168 --base preview \
101169 --head "$BRANCH" \
102- --title "sync-preview: merge main into preview" \
170+ --title "sync-preview: merge main into preview (conflicts) " \
103171 --body "$(cat <<BODY
104- The automated sync-preview workflow could not cleanly merge \`main\` into \`preview\`.
172+ The automated sync could not cleanly merge \`main\` into \`preview\`.
105173
106- **This PR contains the merge with conflict markers.** To resolve:
174+ **This PR contains conflict markers.** To resolve:
107175
108176 1. Check out this branch locally:
109177 \`\`\`bash
@@ -116,8 +184,6 @@ jobs:
116184 3. Keep preview-specific values (package version, preview tests, etc.) — accept main's changes for everything else.
117185 4. Commit and push, then merge this PR.
118186
119- This must be resolved before the next coordinated release.
120-
121187 ${MENTION}
122188
123189 _Opened automatically by the sync-preview workflow._
0 commit comments