Skip to content

feat: add source-control status, push and pull commands - #22

Merged
Hinne1 merged 4 commits into
mainfrom
claude/source-control-push
Oct 13, 2026
Merged

Hinne1 merged 4 commits into
mainfrom
claude/source-control-push

Conversation

@Hinne1

@Hinne1 Hinne1 commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds n8nctl source-control (alias sc) for n8n's Git-backed source control, using the public API endpoints documented at https://docs.n8n.io/connect/n8n-api/source-control:

  • status [--direction push|pull] calls GET /source-control/status
  • push -m <msg> --workflow <id>... --item <type>:<id>... [--force] calls POST /source-control/push
  • pull [--force] [--auto-publish none|all|published] calls POST /source-control/pull

Design notes:

  • Push only takes explicitly named items. A push-everything option would commit other people's pending stage work to the branch prod pulls from.
  • request() now returns an *APIError that keeps the status code and raw body. The Error() text is unchanged. The source-control calls use the body for 409 responses: push returns {message, conflicts} and pull returns a bare array. In both cases the CLI lists the conflicting items and points at --force; with --json the error and the conflict list go to stdout as one JSON object.
  • A 403 names the missing scope (sourceControl:read, :push or :pull).
  • The pull body is always sent, as {} when no flags are set, because the endpoint requires one.

Testing

  • go test -race ./... passes. httptest coverage includes the push body shape, force, the empty {} pull body, pull's bare-array response, both 409 shapes, the 403 scope hint for all three calls, and unchanged APIError messages.
  • Ran against stage with a stage-only config: sc status returns API error (403): Forbidden (the API key needs the sourceControl:read scope ...). The current stage key only has sourceControl:pull (checked via GET /discover). Flag validation also checked: bad --direction, missing -m, no items, unknown --item type, bad --auto-publish.
  • Push and pull were not run live. The stage key lacks the push and read scopes. A pull rewrites instance drafts on stage and is the deploy path on prod, so it is not a safe smoke test.

Wraps the public API's /source-control endpoints. Push takes explicit
--workflow/--item targets; 409 responses list the conflicting items and
403 responses name the missing API key scope.
@Hinne1

Hinne1 commented Oct 13, 2026

Copy link
Copy Markdown
Contributor Author

/gemini review

@Hinne1

Hinne1 commented Oct 13, 2026

Copy link
Copy Markdown
Contributor Author

🔏 Readiness attested — the pr-readiness-check gate completed for PR #22 at 3b68d6be4e33260b20db5e307f91a58af5c32140 (2026-10-13T11:05:54Z). If the branch head has moved, this evidence covers the earlier state only.

Readiness summary

PR Readiness Check (#22, 3b68d6b)
Review mode INITIAL
Branch/base PASS (contains origin/main, clean, head pushed)
Local verification PASS (gofmt, go vet, go test -race ./internal/api ./internal/cmd/sourcecontrol, golangci-lint 0 issues); full suite REMOTE REQUIRED -> CI
Remote CI PASS (CI run 38385882173: lint, test; CodeQL run 38385879719) https://github.com/enthus-appdev/n8n-cli/actions/runs/38385882173 ; release.yml excluded (tag-triggered publish)
Coverage NOT REPORTED
Automated reviewers LIMITATION (n8n-cli is not enrolled in Gemini Developer Connect; /gemini review produced no response; verified via gitRepositoryLinks)
Review threads PASS (0 unresolved)
Review comments PASS (open-review-comments.sh exit 0)
Council findings SKIP (operator-waived: user asked to skip Council)
Standards review SKIP (operator-waived with Council)
Spec review SKIP (operator-waived with Council)
PR description PASS
SQL/UI evidence SKIP (CLI only)
Notes: stage smoke run of status and flag validation; push/pull not run live (stage key lacks sourceControl:read/push; pull rewrites instance drafts). Comment cleanup applied per user approval (3b68d6b).
Result: READY

@Hinne1
Hinne1 marked this pull request as ready for review October 13, 2026 11:06
@Hinne1

Hinne1 commented Oct 13, 2026

Copy link
Copy Markdown
Contributor Author

🔏 Readiness attested — the pr-readiness-check gate completed for PR #22 at d48e6e08809c3c970b8c44d9b219e8270c07195e (2026-10-13T11:19:14Z). If the branch head has moved, this evidence covers the earlier state only.

Readiness summary

PR Readiness Check (#22, d48e6e0)
Review mode FOLLOW-UP SUBSTANTIAL (delta 3b68d6b..d48e6e0: --json now prints {"error","conflicts"} on stdout for a 409; output behavior change)
Branch/base PASS (contains origin/main and the attested 3b68d6b, clean, head pushed)
Local verification PASS (go test -race ./internal/api ./internal/cmd/sourcecontrol incl. new TestConflictErrorJSON, golangci-lint 0 issues); full suite REMOTE REQUIRED -> CI
Remote CI PASS (CI run 38388896713: lint, test; CodeQL run 38388892019) https://github.com/enthus-appdev/n8n-cli/actions/runs/38388896713 ; release.yml excluded (tag-triggered publish)
Coverage NOT REPORTED
Automated reviewers LIMITATION (n8n-cli not enrolled in Gemini Developer Connect)
Review threads PASS (0 unresolved)
Review comments PASS (open-review-comments.sh exit 0)
Council findings SKIP (operator-waived: user asked to skip Council)
Standards review SKIP (operator-waived with Council)
Spec review SKIP (operator-waived with Council)
PR description PASS (updated for the JSON conflict output)
SQL/UI evidence SKIP (CLI only)
Result: READY

@Hinne1
Hinne1 merged commit 446d8a2 into main Oct 13, 2026
5 checks passed
@Hinne1
Hinne1 deleted the claude/source-control-push branch October 13, 2026 11:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant