Skip to content

Commit d860e7e

Browse files
authored
Merge pull request #295 from apollographql/conflict/main-into-develop-pr-
Sync main → develop (resolve conflicts)
2 parents cc7b99a + 9c78e1e commit d860e7e

File tree

11 files changed

+559
-211
lines changed

11 files changed

+559
-211
lines changed

.github/renovate.json5

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
{
2-
$schema: "https://docs.renovatebot.com/renovate-schema.json",
2+
extends: [
3+
"github>apollographql/renovate-config-apollo-open-source:default.json5",
4+
"github>Turbo87/renovate-config//rust/updateToolchain",
5+
],
36
packageRules: [
47
{
58
enabled: false,
69
matchPackageNames: ["*"],
710
},
811
],
12+
// Automating Nix upgrades is currently in beta and opt-in only.
13+
// https://docs.renovatebot.com/modules/manager/nix/
14+
nix: {
15+
enabled: true,
16+
},
917
vulnerabilityAlerts: {
1018
enabled: true,
1119
},

.github/workflows/sync-develop.yml

Lines changed: 106 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -48,69 +48,143 @@ jobs:
4848
HEAD_BRANCH: ${{ (github.event_name == 'workflow_dispatch' && inputs.head_branch) || 'main' }}
4949
BASE_BRANCH: ${{ (github.event_name == 'workflow_dispatch' && inputs.base_branch) || 'develop' }}
5050
SOURCE_PR: ${{ (github.event_name == 'pull_request' && github.event.pull_request.number) || inputs.source_pr_number || '' }}
51+
GH_TOKEN: ${{ secrets.GH_PAT }}
5152

5253
steps:
5354
- uses: actions/checkout@v4
5455
with:
5556
fetch-depth: 0
57+
token: ${{ secrets.GH_PAT }}
58+
59+
- name: Configure git author
60+
run: |
61+
git config --local user.name "Apollo Bot"
62+
git config --local user.email "[email protected]"
5663
5764
# Generate branch name from PR# when available, otherwise use first 7 commit SHA characters
5865
- name: Compute branch/name metadata
5966
id: meta
6067
run: |
61-
if [ -n "${SOURCE_PR}" ]; then
62-
echo "branch=sync/${HEAD_BRANCH}-into-${BASE_BRANCH}-pr-${SOURCE_PR}" >> $GITHUB_OUTPUT
63-
echo "title=Sync ${HEAD_BRANCH} → ${BASE_BRANCH} (PR #${SOURCE_PR})" >> $GITHUB_OUTPUT
64-
echo "body=Auto-opened to merge \`${HEAD_BRANCH}\` into \`${BASE_BRANCH}\`. Source PR: #${SOURCE_PR}." >> $GITHUB_OUTPUT
65-
else
66-
short_sha=${GITHUB_SHA::7}
67-
echo "branch=sync/${HEAD_BRANCH}-into-${BASE_BRANCH}-${short_sha}" >> $GITHUB_OUTPUT
68-
echo "title=Sync ${HEAD_BRANCH} → ${BASE_BRANCH} (${short_sha})" >> $GITHUB_OUTPUT
69-
echo "body=Auto-opened to merge \`${HEAD_BRANCH}\` into \`${BASE_BRANCH}\` at \`${GITHUB_SHA}\`." >> $GITHUB_OUTPUT
70-
fi
68+
pr=${{ github.event.pull_request.number }}
69+
echo "sync_branch=sync/main-into-develop-pr-${pr}" >> $GITHUB_OUTPUT
70+
echo "title_sync=Sync main → develop (PR #${pr})" >> $GITHUB_OUTPUT
71+
echo "body_sync=Auto-opened after merging \`${{ github.event.pull_request.head.ref }}\` into \`main\`. Source PR: #${pr}." >> $GITHUB_OUTPUT
72+
echo "conflict_branch=conflict/main-into-develop-pr-${pr}" >> $GITHUB_OUTPUT
73+
echo "title_conflict=Sync main → develop (resolve conflicts)" >> $GITHUB_OUTPUT
74+
echo "body_conflict=Opened from a copy of \`main\` so conflicts can be resolved without pushing to a protected branch." >> $GITHUB_OUTPUT
7175
7276
# Short-lived sync branch from develop and merge main into it (do NOT rebase)
7377
# use +e to stop errors from short-circuiting the script
7478
- name: Prepare sync branch
7579
id: prep
7680
run: |
81+
set -e
7782
git fetch origin "${BASE_BRANCH}" "${HEAD_BRANCH}"
78-
git switch -c "${{ steps.meta.outputs.branch }}" "origin/${BASE_BRANCH}"
83+
git switch -c "${{ steps.meta.outputs.sync_branch }}" "origin/${BASE_BRANCH}"
7984
set +e
8085
git merge --no-ff "origin/${HEAD_BRANCH}"
8186
rc=$?
8287
set -e
8388
git add -A || true
8489
git commit -m "WIP: merge ${HEAD_BRANCH} into ${BASE_BRANCH} via ${{ steps.meta.outputs.branch }}" || true
8590
git push origin HEAD
91+
92+
right=$(git rev-list --count --right-only "origin/${BASE_BRANCH}...HEAD")
93+
8694
echo "merge_status=$rc" >> "$GITHUB_OUTPUT"
95+
echo "sync_right=$right" >> "$GITHUB_OUTPUT"
96+
echo "Merge exit=$rc, sync branch ahead-by=$right"
8797
88-
# Open the PR targeting develop
89-
- name: Open PR to develop
90-
id: syncpr
91-
uses: peter-evans/create-pull-request@v6
92-
with:
93-
branch: ${{ steps.meta.outputs.branch }}
94-
base: ${{ env.BASE_BRANCH }}
95-
title: ${{ steps.meta.outputs.title }}
96-
body: |
97-
${{ steps.meta.outputs.body }}
98+
# If no merge conflicts and there are changes, open the PR targeting develop
99+
- name: Open clean PR to develop
100+
id: sync_pr
101+
if: ${{ steps.prep.outputs.merge_status == '0' && steps.prep.outputs.sync_right != '0' }}
102+
run: |
103+
# Avoid duplicate PRs
104+
existing=$(gh pr list --base "${BASE_BRANCH}" --head "${{ steps.meta.outputs.sync_branch }}" --state open --json number --jq '.[0].number' || true)
105+
if [ -n "$existing" ] && [ "$existing" != "null" ]; then
106+
echo "pr_number=$existing" >> "$GITHUB_OUTPUT"
107+
url=$(gh pr view "$existing" --json url --jq .url)
108+
echo "pr_url=$url" >> "$GITHUB_OUTPUT"
109+
exit 0
110+
fi
98111
99-
Merge status: ${{ steps.prep.outputs.merge_status == '0' && 'clean ✅' || 'conflicts ❗' }}
100-
labels: ${{ steps.prep.outputs.merge_status == '0' && 'back-merge,automation' || 'back-merge,automation,conflicts' }}
112+
gh pr create \
113+
--base "${BASE_BRANCH}" \
114+
--head "${{ steps.meta.outputs.sync_branch }}" \
115+
--title "${{ steps.meta.outputs.sync_title }}" \
116+
--body "${{ steps.meta.outputs.sync_body }} (created via gh CLI)" \
117+
--label back-merge \
118+
--label automation
119+
120+
# Emit outputs for later steps
121+
gh pr view --base "${BASE_BRANCH}" --head "${{ steps.meta.outputs.sync_branch }}" \
122+
--json number,url | jq -r '"pr_number=\(.number)\npr_url=\(.url)"' >> "$GITHUB_OUTPUT"
123+
124+
# If the merge hit conflicts, open a DIRECT PR: HEAD_BRANCH -> BASE_BRANCH so conflicts can be resolved prior to merge
125+
- name: Open conflict PR
126+
id: conflict_pr
127+
if: ${{ steps.prep.outputs.merge_status != '0' }}
128+
run: |
129+
set -e
130+
git fetch origin "${HEAD_BRANCH}" "${BASE_BRANCH}"
131+
132+
git switch -c "${{ steps.meta.outputs.conflict_branch }}" "origin/${HEAD_BRANCH}"
133+
git push -u origin HEAD
134+
135+
# Skip if no diff between conflict branch and base (should be unlikely)
136+
right=$(git rev-list --right-only --count "origin/${BASE_BRANCH}...origin/${{ steps.meta.outputs.conflict_branch }}")
137+
if [ "$right" -eq 0 ]; then
138+
echo "No diff between ${HEAD_BRANCH} and ${BASE_BRANCH}; nothing to open."
139+
exit 0
140+
fi
141+
142+
# Reuse existing open PR if present
143+
existing=$(gh pr list --base "${BASE_BRANCH}" --head "${{ steps.meta.outputs.conflict_branch }}" --state open --json number --jq '.[0].number' || true)
144+
if [ -n "$existing" ] && [ "$existing" != "null" ]; then
145+
echo "pr_number=$existing" >> "$GITHUB_OUTPUT"
146+
url=$(gh pr view "$existing" --json url --jq .url)
147+
echo "pr_url=$url" >> "$GITHUB_OUTPUT"
148+
exit 0
149+
fi
150+
151+
gh pr create \
152+
--base "${BASE_BRANCH}" \
153+
--head "${{ steps.meta.outputs.conflict_branch }}" \
154+
--title "${{ steps.meta.outputs.title_conflict }}" \
155+
--body "${{ steps.meta.outputs.body_conflict }}" \
156+
--label back-merge \
157+
--label automation \
158+
--label conflicts
159+
160+
gh pr view --base "${BASE_BRANCH}" --head "${{ steps.meta.outputs.conflict_branch }}" \
161+
--json number,url | jq -r '"pr_number=\(.number)\npr_url=\(.url)"' >> "$GITHUB_OUTPUT"
101162
102163
# Comment back on the ORIGINAL merged PR with a link to the sync PR
103164
- name: Comment on source PR with sync PR link
104-
if: github.event_name == 'pull_request' && steps.syncpr.outputs.pull-request-number != ''
165+
if: ${{ env.SOURCE_PR != '' && (steps.sync_pr.outputs.pr_number != '' || steps.conflict_pr.outputs.pr_number != '') }}
105166
uses: actions/github-script@v7
106167
with:
107168
script: |
169+
const owner = context.repo.owner;
170+
const repo = context.repo.repo;
108171
const issue_number = Number(process.env.SOURCE_PR);
109-
const syncUrl = `${{ toJson(steps.syncpr.outputs['pull-request-url']) }}`.replace(/^"|"$/g, '');
110-
const body = `Opened sync PR **${process.env.HEAD_BRANCH} → ${process.env.BASE_BRANCH}**: ${syncUrl}`;
111-
await github.rest.issues.createComment({
112-
owner: context.repo.owner,
113-
repo: context.repo.repo,
114-
issue_number,
115-
body,
116-
});
172+
173+
const hadConflicts = '${{ steps.prep.outputs.merge_status }}' !== '0';
174+
const syncUrl = '${{ steps.sync_pr.outputs.pr_url || steps.conflict_pr.outputs.pr_url }}';
175+
const head = process.env.HEAD_BRANCH;
176+
const base = process.env.BASE_BRANCH;
177+
178+
const status = hadConflicts ? 'conflicts ❗' : 'clean ✅';
179+
const note = hadConflicts
180+
? 'Opened from a copy of main so conflicts can be resolved safely.'
181+
: 'Opened from a sync branch created off develop.';
182+
183+
const body = [
184+
`Opened sync PR **${head} → ${base}**: ${syncUrl}`,
185+
``,
186+
`Merge status: **${status}**`,
187+
note
188+
].join('\n');
189+
190+
await github.rest.issues.createComment({ owner, repo, issue_number, body });

.github/workflows/verify-changeset.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ on:
44
branches-ignore:
55
- main
66
- release/**
7+
- conflict/*
8+
- sync/*
79
paths-ignore:
810
- '.github/**'
911
- '.cargo/**'
@@ -17,7 +19,7 @@ on:
1719

1820
jobs:
1921
verify-changeset:
20-
if: ${{ !contains(github.event.pull_request.labels.*.name, 'skip-changeset') }}
22+
if: ${{ !contains(github.event.pull_request.labels.*.name, 'skip-changeset') && !startsWith(github.head_ref, 'sync/') && !startsWith(github.head_ref, 'conflict/') }}
2123
name: Verify
2224
runs-on: ubuntu-24.04
2325
permissions:

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file.
44

55
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
# [0.7.3] - 2025-08-25
8+
9+
## 🐛 Fixes
10+
11+
### fix: generate openAI-compatible json schemas for list types - @DaleSeo PR #272
12+
13+
The MCP server is generating JSON schemas that don't match OpenAI's function calling specification. It puts `oneOf` at the array level instead of using `items` to define the JSON schemas for the GraphQL list types. While some other LLMs are more flexible about this, it technically violates the [JSON Schema specification](https://json-schema.org/understanding-json-schema/reference/array) that OpenAI strictly follows.
14+
15+
This PR updates the list type handling logic to move `oneOf` inside `items` for GraphQL list types.
16+
717
# [0.7.2] - 2025-08-19
818

919
## 🚀 Features

Cargo.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ members = [
88

99
[workspace.package]
1010
authors = ["Apollo <[email protected]>"]
11-
version = "0.7.2"
11+
version = "0.7.3"
1212

1313
[workspace.dependencies]
1414
apollo-compiler = "1.27.0"

crates/apollo-mcp-server/src/graphql.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ mod test {
187187
"extensions": {
188188
"clientLibrary": {
189189
"name":"mcp",
190-
"version":"0.7.2"
190+
"version":"0.7.3"
191191
}
192192
},
193193
"operationName":"mock_operation"
@@ -233,7 +233,7 @@ mod test {
233233
},
234234
"clientLibrary": {
235235
"name":"mcp",
236-
"version":"0.7.2"
236+
"version":"0.7.3"
237237
}
238238
},
239239
})

0 commit comments

Comments
 (0)