feat(tangled): add scm and pullrequest support#8965
Open
shanduur wants to merge 3 commits into
Open
Conversation
cc07d53 to
25aad55
Compare
Add Tangled (AT protocol git host) as an scm kind plus a tangled/pullrequest action. Pull requests are written as sh.tangled.repo.pull records on the author's PDS using an atproto app password session; patches go up as gzipped blobs. - scm clone over HTTPS, push over SSH (knot rejects HTTPS push) - reuse core lex types (tangled.org/core/api/tangled) and indigo's atclient/comatproto/syntax to avoid duplicating the schema - idempotent CreateAction: listRecords on the author DID detects open PRs for the same target repo + branch pair Signed-off-by: Mateusz Urbanek <[email protected]>
Author
|
Tested on my Homelab repo: https://tangled.org/shanduur.net/homelab |
Member
|
Thanks for the pull request, I'll try to test this in the coming days |
olblak
reviewed
Jun 2, 2026
| return "", fmt.Errorf("scm working directory is empty") | ||
| } | ||
| revRange := fmt.Sprintf("%s..%s", t.TargetBranch, t.SourceBranch) | ||
| cmd := exec.Command("git", "-C", dir, "format-patch", "--stdout", revRange) |
Member
There was a problem hiding this comment.
Could we avoid relying on this git command? As it would bring a dependency on the git command
Excepted from some autodiscovery plugin, Updatecli is a self-contained binary, and I would prefer to keep it this way.
olblak
reviewed
Jun 2, 2026
| } | ||
|
|
||
| // generateFormatPatch runs `git format-patch` between target and source branches. | ||
| func (t *Tangled) generateFormatPatch() (string, error) { |
Member
There was a problem hiding this comment.
While this sounds a nice thing, this introduce a critical dependency on the git command and could probably be remove
Signed-off-by: Olblak <[email protected]>
Member
|
@shanduur while testing this pullrequest, I notice that pullrequest is not using the Updatecli http client so I just added one commit to fix |
Comment on lines
+232
to
+243
| // Resolve once now to cache knot + repoDid; per-action PDS lookups would | ||
| // otherwise burst com.atproto.server.createSession rate limits. | ||
| { | ||
| ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) | ||
| defer cancel() | ||
| if err := t.resolveRepoRecord(ctx); err != nil { | ||
| if t.Spec.Knot == "" && t.Spec.CloneURL == "" { | ||
| return nil, fmt.Errorf("resolve repo record for %s/%s: %w", t.Spec.Owner, t.Spec.Repository, err) | ||
| } | ||
| logrus.Debugf("tangled: repo record lookup failed (continuing with explicit spec): %s", err) | ||
| } | ||
| } |
Comment on lines
+121
to
+130
| // "cloneURL" optionally overrides the URL used to clone the repository. | ||
| // | ||
| // default: | ||
| // https://<knot>/<owner>/<repository> | ||
| // | ||
| // remark: | ||
| // Tangled knots reject pushes over HTTPS. When updatecli needs to push a | ||
| // working branch, set this to an SSH URL such as | ||
| // git@<knot>:<owner>/<repository> and ensure SSH agent forwarding is | ||
| // available. |
Comment on lines
+61
to
+66
| sshHost := t.Spec.Knot | ||
| if sshHost == "knot1.tangled.sh" || sshHost == "" { | ||
| sshHost = "tangled.org" | ||
| } | ||
| return fmt.Sprintf("git@%s:%s/%s", sshHost, t.Spec.Owner, t.Spec.Repository) | ||
| } |
Comment on lines
+53
to
+65
| func New(s Spec) (*Client, error) { | ||
| key := cacheKey(s) | ||
|
|
||
| clientCacheMu.Lock() | ||
| defer clientCacheMu.Unlock() | ||
| if existing, ok := clientCache[key]; ok { | ||
| return existing, nil | ||
| } | ||
|
|
||
| c := &Client{spec: s} | ||
| clientCache[key] = c | ||
| return c, nil | ||
| } |
Comment on lines
+19
to
+42
| func (t *Tangled) inheritFromScm() { | ||
| if t.scm != nil { | ||
| _, t.SourceBranch, t.TargetBranch = t.scm.GetBranches() | ||
| t.Knot = t.scm.Spec.Knot | ||
| t.Owner = t.scm.Spec.Owner | ||
| t.Repository = t.scm.Spec.Repository | ||
| } | ||
|
|
||
| if t.spec.SourceBranch != "" { | ||
| t.SourceBranch = t.spec.SourceBranch | ||
| } | ||
| if t.spec.TargetBranch != "" { | ||
| t.TargetBranch = t.spec.TargetBranch | ||
| } | ||
| if t.spec.Knot != "" { | ||
| t.Knot = t.spec.Knot | ||
| } | ||
| if t.spec.Owner != "" { | ||
| t.Owner = t.spec.Owner | ||
| } | ||
| if t.spec.Repository != "" { | ||
| t.Repository = t.spec.Repository | ||
| } | ||
| } |
Comment on lines
+47
to
+58
| func (t *Tangled) repoOverridesScm() bool { | ||
| if t.scm == nil { | ||
| return false | ||
| } | ||
| if t.spec.Owner != "" && t.spec.Owner != t.scm.Spec.Owner { | ||
| return true | ||
| } | ||
| if t.spec.Repository != "" && t.spec.Repository != t.scm.Spec.Repository { | ||
| return true | ||
| } | ||
| return false | ||
| } |
Comment on lines
+51
to
+55
| // New returns a Client. Clients constructed with the same (PDS, identifier, | ||
| // appview) triple share an authenticated atproto session. | ||
| func New(s Spec) (*Client, error) { | ||
| key := cacheKey(s) | ||
|
|
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fix #8678
Test
To test this pull request, you can run the following commands:
Additional Information
Checklist
Tradeoff
Potential improvement
Add Tangled (AT protocol git host) as an scm kind plus a
tangled/pullrequest action. Pull requests are written as
sh.tangled.repo.pull records on the author's PDS using an atproto
app password session; patches go up as gzipped blobs.
Signed-off-by: Mateusz Urbanek [email protected]