api-sync #76
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: API Sync | |
| on: | |
| repository_dispatch: | |
| types: [api-sync] | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| id-token: write | |
| jobs: | |
| sync: | |
| name: Sync CLI with API changes | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: latest | |
| - name: Fetch API sync data | |
| run: | | |
| mkdir -p /tmp/api-sync | |
| git fetch origin api-sync-data | |
| git show origin/api-sync-data:.api-sync/changelog.md > /tmp/api-sync/changelog.md | |
| echo "=== Changelog ===" | |
| cat /tmp/api-sync/changelog.md | |
| - name: Check for existing api-sync PR | |
| id: check-pr | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| PR_NUMBER=$(gh pr list --head api-sync --json number --jq '.[0].number // empty') | |
| if [ -n "$PR_NUMBER" ]; then | |
| echo "existing_pr=$PR_NUMBER" >> $GITHUB_OUTPUT | |
| echo "Found existing api-sync PR: #$PR_NUMBER" | |
| else | |
| echo "existing_pr=" >> $GITHUB_OUTPUT | |
| echo "No existing api-sync PR found" | |
| fi | |
| - name: Create or checkout api-sync branch | |
| run: | | |
| git fetch origin api-sync 2>/dev/null || true | |
| if git rev-parse --verify origin/api-sync >/dev/null 2>&1; then | |
| git checkout api-sync | |
| git reset --hard origin/main | |
| else | |
| git checkout -b api-sync | |
| fi | |
| - name: Install dependencies | |
| run: bun install --frozen-lockfile | |
| - name: Apply changes with Claude Code | |
| uses: anthropics/claude-code-action@v1 | |
| with: | |
| claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} | |
| claude_args: '--model claude-sonnet-4-6 --allowedTools "Bash(*),Read,Edit,Write,Glob,Grep"' | |
| prompt: | | |
| You are updating this CLI to match BlindPay API changes. | |
| Read CLAUDE.md in this repo first — it describes the file | |
| layout, command naming conventions, output patterns, and the | |
| decision rules for translating API changes into CLI changes. | |
| The changelog is at /tmp/api-sync/changelog.md. It is the | |
| authoritative list of API changes since the last sync. | |
| Process: | |
| 1. Read CLAUDE.md thoroughly. | |
| 2. Read /tmp/api-sync/changelog.md. | |
| 3. For each change, apply the decision rules in CLAUDE.md | |
| (section "Sync workflow conventions"). Skip changes that | |
| don't map to any CLI surface — silence is fine. | |
| 4. Implement the chosen changes: | |
| - New commands: add the action function to | |
| src/commands/resources.ts and wire it into | |
| src/index.ts under the right group banner. | |
| - New flags: add to the option list in src/index.ts and | |
| pass through to the action in src/commands/resources.ts. | |
| - Removed endpoints: remove the command and the action. | |
| - Enum changes: only update help text in src/index.ts. | |
| - Dynamic / arbitrary-object request bodies (e.g. | |
| `Record<string, any>` or `z.record(z.string(), | |
| z.any())`): do NOT ship the command with an empty | |
| `{}` body and a TODO. Accept the body as a single | |
| `--body <json>` flag, parse with `JSON.parse`, and | |
| call `exitWithError` on a parse failure. Use | |
| `--body` (not `--response`, `--payload`, etc.) for | |
| consistency across commands. See the | |
| "Dynamic request bodies" section in CLAUDE.md for | |
| the exact pattern. | |
| - Do NOT leave `// TODO(api-sync):` markers in shipped | |
| commands. Use the JSON-string fallback above instead | |
| of TODOs. TODOs are only acceptable for low-signal | |
| cleanups (e.g. column tuning). | |
| 5. Update src/__tests__/resources.test.ts to match. For every | |
| action you added: add at least one happy-path test | |
| asserting the URL, method, and body. For every action you | |
| modified: update the existing test's expected body/URL. | |
| For every action you removed: remove its test. Follow the | |
| existing pattern (setupTestEnv/teardownTestEnv, lastCall(), | |
| mockResponse.body). See the "Testing" section of CLAUDE.md. | |
| **Place new tests inside the existing `describe(...)` | |
| block that matches the command's top-level CLI group** — | |
| a `receivers submit_rfi` test goes in | |
| `describe('Receivers', ...)`, not in a new | |
| `describe('RFI', ...)`. Only create a new describe block | |
| when introducing a brand-new top-level CLI group. | |
| 6. Bump the `version` field in package.json (patch for | |
| additive changes, minor if anything was removed). | |
| CLI_VERSION is derived from package.json at build time — | |
| do not edit src/utils/constants.ts for version bumps. | |
| 7. Run `bun run typecheck`, `bun run lint:fix`, and | |
| `bun run test`. Fix any errors until all three are clean. | |
| 8. Do NOT touch .github/workflows/. | |
| 9. Do NOT create commits — leave changes in the working tree. | |
| If a change is ambiguous, leave a TODO comment with | |
| `// TODO(api-sync):` so a human reviewer can address it. | |
| - name: Commit and push | |
| id: commit | |
| run: | | |
| git remote set-url origin "https://x-access-token:${{ secrets.SDK_SYNC_PAT }}@github.com/${{ github.repository }}.git" | |
| git checkout -- .github/workflows/ 2>/dev/null || true | |
| git add -A | |
| git reset HEAD .github/workflows/ 2>/dev/null || true | |
| if git diff --staged --quiet; then | |
| echo "No changes to commit" | |
| echo "has_changes=false" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| echo "has_changes=true" >> $GITHUB_OUTPUT | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| git commit -m "feat: sync CLI with API changes" | |
| git push --force-with-lease origin api-sync | |
| - name: Create or update PR | |
| if: steps.commit.outputs.has_changes == 'true' | |
| env: | |
| GH_TOKEN: ${{ secrets.SDK_SYNC_PAT }} | |
| run: | | |
| EXISTING_PR="${{ steps.check-pr.outputs.existing_pr }}" | |
| if [ -n "$EXISTING_PR" ]; then | |
| echo "Updating existing PR #$EXISTING_PR" | |
| gh pr comment "$EXISTING_PR" --body "Updated with latest API changes." | |
| else | |
| gh pr create \ | |
| --title "feat: sync CLI with API changes" \ | |
| --body "Automated CLI update from API changes." \ | |
| --base main \ | |
| --head api-sync \ | |
| --label api-sync | |
| fi |