From c65fd63ac59297e72ee56f3992f2c4715d5b585c Mon Sep 17 00:00:00 2001 From: evanorti <87997759+evanorti@users.noreply.github.com> Date: Tue, 31 Mar 2026 16:21:29 -0400 Subject: [PATCH 1/4] Create check-example-sync-conflict.yml --- .../workflows/check-example-sync-conflict.yml | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 .github/workflows/check-example-sync-conflict.yml diff --git a/.github/workflows/check-example-sync-conflict.yml b/.github/workflows/check-example-sync-conflict.yml new file mode 100644 index 00000000..022827fe --- /dev/null +++ b/.github/workflows/check-example-sync-conflict.yml @@ -0,0 +1,94 @@ +name: Check for example tutorial sync conflicts + +# When a PR touches sdk/next/tutorials/example/, check if there is an open +# docs-sync PR on cosmos/example that modifies the same files. If so, post +# a warning comment so the author knows to coordinate before merging. + +on: + pull_request: + paths: + - "sdk/next/tutorials/example/**" + +jobs: + check-conflict: + name: Check for open sync PR conflict + runs-on: ubuntu-latest + permissions: + pull-requests: write + + steps: + - name: Check for conflicting sync PR on cosmos/example + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PR_NUMBER: ${{ github.event.pull_request.number }} + run: | + # Get files changed in this PR that are in the tutorials folder + THIS_PR_FILES=$(gh pr view "$PR_NUMBER" \ + --repo cosmos/docs \ + --json files \ + --jq '[.files[].path | select(startswith("sdk/next/tutorials/example/"))] | sort') + + echo "Files changed in this PR: $THIS_PR_FILES" + + if [ "$THIS_PR_FILES" = "[]" ]; then + echo "No tutorial files changed, skipping." + exit 0 + fi + + # Find any open docs-sync PRs on cosmos/example + SYNC_PR=$(gh pr list \ + --repo cosmos/example \ + --label "docs-sync" \ + --state open \ + --json number,url,headRefName \ + --jq '.[0]') + + if [ -z "$SYNC_PR" ] || [ "$SYNC_PR" = "null" ]; then + echo "No open sync PR on cosmos/example, all clear." + exit 0 + fi + + SYNC_PR_NUMBER=$(echo "$SYNC_PR" | jq -r '.number') + SYNC_PR_URL=$(echo "$SYNC_PR" | jq -r '.url') + + echo "Found open sync PR: $SYNC_PR_URL" + + # Get files changed in the sync PR (docs/ paths, map to sdk/next/tutorials/example/) + SYNC_PR_FILES=$(gh pr view "$SYNC_PR_NUMBER" \ + --repo cosmos/example \ + --json files \ + --jq '[.files[].path | select(startswith("docs/")) | sub("^docs/(?P[0-9]+-)?"; "sdk/next/tutorials/example/") | sub("\\.md$"; ".mdx")] | sort') + + echo "Files in sync PR (mapped): $SYNC_PR_FILES" + + # Find overlapping files + OVERLAP=$(jq -n \ + --argjson a "$THIS_PR_FILES" \ + --argjson b "$SYNC_PR_FILES" \ + '[$a[], $b[]] | group_by(.) | map(select(length > 1)) | map(.[0])') + + echo "Overlapping files: $OVERLAP" + + if [ "$OVERLAP" = "[]" ] || [ -z "$OVERLAP" ]; then + echo "No overlapping files, all clear." + exit 0 + fi + + # Format the overlap list for the comment + OVERLAP_LIST=$(echo "$OVERLAP" | jq -r '.[] | "- `\(.)`"') + + gh pr comment "$PR_NUMBER" \ + --repo cosmos/docs \ + --body "$(cat < Date: Tue, 31 Mar 2026 16:36:16 -0400 Subject: [PATCH 2/4] Update check-example-sync-conflict.yml --- .../workflows/check-example-sync-conflict.yml | 96 ++++++++++++------- 1 file changed, 64 insertions(+), 32 deletions(-) diff --git a/.github/workflows/check-example-sync-conflict.yml b/.github/workflows/check-example-sync-conflict.yml index 022827fe..7c887dca 100644 --- a/.github/workflows/check-example-sync-conflict.yml +++ b/.github/workflows/check-example-sync-conflict.yml @@ -1,8 +1,8 @@ name: Check for example tutorial sync conflicts -# When a PR touches sdk/next/tutorials/example/, check if there is an open -# docs-sync PR on cosmos/example that modifies the same files. If so, post -# a warning comment so the author knows to coordinate before merging. +# When a PR touches sdk/next/tutorials/example/, check if any open docs-sync +# PRs on cosmos/example modify the same files. If so, post or update a warning +# comment on this PR. on: pull_request: @@ -30,65 +30,97 @@ jobs: echo "Files changed in this PR: $THIS_PR_FILES" - if [ "$THIS_PR_FILES" = "[]" ]; then - echo "No tutorial files changed, skipping." - exit 0 - fi - - # Find any open docs-sync PRs on cosmos/example - SYNC_PR=$(gh pr list \ + # Get all open docs-sync PRs on cosmos/example + SYNC_PRS=$(gh pr list \ --repo cosmos/example \ --label "docs-sync" \ --state open \ - --json number,url,headRefName \ - --jq '.[0]') + --json number,url) - if [ -z "$SYNC_PR" ] || [ "$SYNC_PR" = "null" ]; then - echo "No open sync PR on cosmos/example, all clear." + echo "Open sync PRs: $SYNC_PRS" + + if [ "$SYNC_PRS" = "[]" ] || [ -z "$SYNC_PRS" ]; then + echo "No open sync PRs on cosmos/example, all clear." exit 0 fi - SYNC_PR_NUMBER=$(echo "$SYNC_PR" | jq -r '.number') - SYNC_PR_URL=$(echo "$SYNC_PR" | jq -r '.url') + # Collect all files from all open sync PRs, mapped to docs site paths + ALL_SYNC_FILES="[]" + SYNC_PR_URLS="" - echo "Found open sync PR: $SYNC_PR_URL" + while IFS= read -r pr; do + SYNC_PR_NUMBER=$(echo "$pr" | jq -r '.number') + SYNC_PR_URL=$(echo "$pr" | jq -r '.url') + SYNC_PR_URLS="$SYNC_PR_URLS $SYNC_PR_URL" - # Get files changed in the sync PR (docs/ paths, map to sdk/next/tutorials/example/) - SYNC_PR_FILES=$(gh pr view "$SYNC_PR_NUMBER" \ - --repo cosmos/example \ - --json files \ - --jq '[.files[].path | select(startswith("docs/")) | sub("^docs/(?P[0-9]+-)?"; "sdk/next/tutorials/example/") | sub("\\.md$"; ".mdx")] | sort') + SYNC_FILES=$(gh pr view "$SYNC_PR_NUMBER" \ + --repo cosmos/example \ + --json files \ + --jq '[.files[].path + | select(startswith("docs/")) + | sub("^docs/([0-9]+-)?"; "sdk/next/tutorials/example/") + | sub("\\.md$"; ".mdx") + ] | sort') - echo "Files in sync PR (mapped): $SYNC_PR_FILES" + ALL_SYNC_FILES=$(jq -n \ + --argjson a "$ALL_SYNC_FILES" \ + --argjson b "$SYNC_FILES" \ + '$a + $b | unique | sort') + done < <(echo "$SYNC_PRS" | jq -c '.[]') + + echo "All sync PR files (mapped): $ALL_SYNC_FILES" # Find overlapping files OVERLAP=$(jq -n \ --argjson a "$THIS_PR_FILES" \ - --argjson b "$SYNC_PR_FILES" \ + --argjson b "$ALL_SYNC_FILES" \ '[$a[], $b[]] | group_by(.) | map(select(length > 1)) | map(.[0])') echo "Overlapping files: $OVERLAP" + MARKER="" + if [ "$OVERLAP" = "[]" ] || [ -z "$OVERLAP" ]; then echo "No overlapping files, all clear." + # If a previous warning comment exists, update it to say all clear + EXISTING_COMMENT=$(gh api "repos/cosmos/docs/issues/$PR_NUMBER/comments" \ + --jq ".[] | select(.body | contains(\"$MARKER\")) | .id" | head -1) + if [ -n "$EXISTING_COMMENT" ]; then + gh api "repos/cosmos/docs/issues/comments/$EXISTING_COMMENT" \ + -X PATCH \ + -f body="$MARKER + ✅ **Sync conflict resolved** — no overlapping files with open sync PRs on \`cosmos/example\`." + fi exit 0 fi - # Format the overlap list for the comment OVERLAP_LIST=$(echo "$OVERLAP" | jq -r '.[] | "- `\(.)`"') + SYNC_PR_LINKS=$(echo "$SYNC_PR_URLS" | tr ' ' '\n' | grep -v '^$' | sed 's/^/- /') - gh pr comment "$PR_NUMBER" \ - --repo cosmos/docs \ - --body "$(cat < Date: Tue, 31 Mar 2026 16:38:37 -0400 Subject: [PATCH 3/4] Update check-example-sync-conflict.yml --- .../workflows/check-example-sync-conflict.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/check-example-sync-conflict.yml b/.github/workflows/check-example-sync-conflict.yml index 7c887dca..01ec48c7 100644 --- a/.github/workflows/check-example-sync-conflict.yml +++ b/.github/workflows/check-example-sync-conflict.yml @@ -98,18 +98,18 @@ jobs: SYNC_PR_LINKS=$(echo "$SYNC_PR_URLS" | tr ' ' '\n' | grep -v '^$' | sed 's/^/- /') COMMENT_BODY=$(cat < Date: Tue, 31 Mar 2026 16:46:27 -0400 Subject: [PATCH 4/4] Update check-example-sync-conflict.yml --- .github/workflows/check-example-sync-conflict.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/check-example-sync-conflict.yml b/.github/workflows/check-example-sync-conflict.yml index 01ec48c7..b55fb9b0 100644 --- a/.github/workflows/check-example-sync-conflict.yml +++ b/.github/workflows/check-example-sync-conflict.yml @@ -20,6 +20,7 @@ jobs: - name: Check for conflicting sync PR on cosmos/example env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + EXAMPLE_TOKEN: ${{ secrets.EXAMPLE_REPO_TOKEN }} PR_NUMBER: ${{ github.event.pull_request.number }} run: | # Get files changed in this PR that are in the tutorials folder @@ -30,8 +31,8 @@ jobs: echo "Files changed in this PR: $THIS_PR_FILES" - # Get all open docs-sync PRs on cosmos/example - SYNC_PRS=$(gh pr list \ + # Get all open docs-sync PRs on cosmos/example (use cross-repo PAT) + SYNC_PRS=$(GH_TOKEN="$EXAMPLE_TOKEN" gh pr list \ --repo cosmos/example \ --label "docs-sync" \ --state open \ @@ -53,7 +54,7 @@ jobs: SYNC_PR_URL=$(echo "$pr" | jq -r '.url') SYNC_PR_URLS="$SYNC_PR_URLS $SYNC_PR_URL" - SYNC_FILES=$(gh pr view "$SYNC_PR_NUMBER" \ + SYNC_FILES=$(GH_TOKEN="$EXAMPLE_TOKEN" gh pr view "$SYNC_PR_NUMBER" \ --repo cosmos/example \ --json files \ --jq '[.files[].path