Docs Sync → cosmos/docs #13
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Docs Sync → cosmos/docs | |
| # Runs when docs/ files change on main. | |
| # Transforms .md → .mdx and opens a PR on the docs site repo. | |
| # If a sync PR is already open, updates it instead of opening a new one. | |
| # Skip if the commit was itself produced by the sync (loop guard). | |
| on: | |
| push: | |
| branches: | |
| - main | |
| paths: | |
| - "docs/**" | |
| # Manual trigger. Needed because the push trigger only fires on docs/** changes, | |
| # so a workflow-only fix cannot re-run the sync, and a sync PR left stale by a | |
| # failed run has no way to catch up until the next docs edit. | |
| workflow_dispatch: | |
| # Serialize runs. Two overlapping runs would each check out the same revision of | |
| # the open sync branch, commit divergently, and the loser's push would be | |
| # rejected as non-fast-forward, silently dropping its update. Queue instead of | |
| # cancelling: the transform is deterministic from docs/, so the last run to | |
| # finish always produces the correct final state. | |
| concurrency: | |
| group: docs-sync | |
| cancel-in-progress: false | |
| jobs: | |
| sync: | |
| name: Sync docs to cosmos/docs | |
| runs-on: ubuntu-latest | |
| # Loop guard: skip commits that the docs-sync bot created | |
| if: "!contains(github.event.head_commit.message, '[docs-sync]')" | |
| steps: | |
| - name: Checkout example repo | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| - name: Checkout cosmos/docs | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: cosmos/docs | |
| # Fine-grained PAT with contents:write and pull-requests:write on cosmos/docs | |
| token: ${{ secrets.DOCS_REPO_TOKEN }} | |
| path: cosmos-docs | |
| persist-credentials: false | |
| # Select the target branch BEFORE transforming. If an open sync PR exists we | |
| # check its branch out while the tree is still clean, so the transform writes | |
| # directly onto that branch. Switching branches after the transform would either | |
| # abort ("local changes would be overwritten") or, via stash, conflict against | |
| # changes the branch already carries. | |
| - name: Select target branch | |
| id: target | |
| env: | |
| GH_TOKEN: ${{ secrets.DOCS_REPO_TOKEN }} | |
| run: | | |
| cd cosmos-docs | |
| EXISTING=$(gh pr list \ | |
| --repo cosmos/docs \ | |
| --label "docs-sync" \ | |
| --state open \ | |
| --json number,headRefName \ | |
| --jq '.[0]') | |
| if [ -n "$EXISTING" ]; then | |
| PR_NUMBER=$(echo "$EXISTING" | jq -r '.number') | |
| BRANCH=$(echo "$EXISTING" | jq -r '.headRefName') | |
| git fetch origin "refs/heads/${BRANCH}:refs/remotes/origin/${BRANCH}" | |
| git checkout -B "$BRANCH" "origin/${BRANCH}" | |
| echo "pr_number=$PR_NUMBER" >> "$GITHUB_OUTPUT" | |
| echo "Reusing open sync PR #$PR_NUMBER on branch $BRANCH" | |
| else | |
| BRANCH="docs-sync/example-$(date +%Y%m%d-%H%M%S)" | |
| git checkout -b "$BRANCH" | |
| echo "pr_number=" >> "$GITHUB_OUTPUT" | |
| echo "No open sync PR, will create branch $BRANCH" | |
| fi | |
| echo "branch=$BRANCH" >> "$GITHUB_OUTPUT" | |
| - name: Transform docs → Mintlify format | |
| run: | | |
| python3 scripts/docs-sync/transform.py \ | |
| --direction to-mintlify \ | |
| --input docs/ \ | |
| --output-dir cosmos-docs/sdk/next/tutorials/example/ | |
| - name: Commit, then open or update the PR on cosmos/docs | |
| env: | |
| GH_TOKEN: ${{ secrets.DOCS_REPO_TOKEN }} | |
| BRANCH: ${{ steps.target.outputs.branch }} | |
| PR_NUMBER: ${{ steps.target.outputs.pr_number }} | |
| run: | | |
| cd cosmos-docs | |
| git config user.name "docs-sync[bot]" | |
| git config user.email "docs-sync[bot]@users.noreply.github.com" | |
| git remote set-url origin "https://x-access-token:${{ secrets.DOCS_REPO_TOKEN }}@github.com/cosmos/docs.git" | |
| git add sdk/next/tutorials/example/ | |
| if git diff --cached --quiet; then | |
| echo "No doc changes to sync, nothing to commit." | |
| exit 0 | |
| fi | |
| git commit -m "docs: sync example tutorials from cosmos/example [docs-sync]" | |
| git push origin "HEAD:refs/heads/${BRANCH}" | |
| if [ -n "$PR_NUMBER" ]; then | |
| gh pr comment "$PR_NUMBER" \ | |
| --repo cosmos/docs \ | |
| --body "Sync updated: cosmos/example was updated before this PR merged. Branch has been refreshed, please re-review." | |
| echo "Updated existing PR #$PR_NUMBER" | |
| else | |
| gh pr create \ | |
| --repo cosmos/docs \ | |
| --head "$BRANCH" \ | |
| --base main \ | |
| --title "docs: sync example tutorials from cosmos/example" \ | |
| --label "docs-sync" \ | |
| --body "Auto-synced from cosmos/example. Transforms docs/*.md to sdk/next/tutorials/example/*.mdx. Do not edit these files directly, edit the source in cosmos/example and let the sync bot update them." | |
| echo "Opened a new sync PR on branch $BRANCH" | |
| fi |