Skip to content

Commit

Permalink
feat: implement github connector
Browse files Browse the repository at this point in the history
fix:  linear connector: create issue operation
  • Loading branch information
jaymesC committed Nov 7, 2024
1 parent 335574f commit bd62d33
Show file tree
Hide file tree
Showing 10 changed files with 974 additions and 1 deletion.
2 changes: 2 additions & 0 deletions connectors.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/wakflo/extensions/internal/connectors/flexport"
"github.com/wakflo/extensions/internal/connectors/freshdesk"
"github.com/wakflo/extensions/internal/connectors/freshworkscrm"
"github.com/wakflo/extensions/internal/connectors/github"
googledocs "github.com/wakflo/extensions/internal/connectors/google_docs"
googlesheets "github.com/wakflo/extensions/internal/connectors/google_sheets"
"github.com/wakflo/extensions/internal/connectors/googlecalendar"
Expand Down Expand Up @@ -110,6 +111,7 @@ func RegisterConnectors() []*sdk.ConnectorPlugin {
monday.NewConnector, // Monday.com
zoom.NewConnector, // Zoom
flexport.NewConnector, // Flexport
github.NewConnector, // Github
}

// 🛑Do-Not-Edit
Expand Down
38 changes: 38 additions & 0 deletions internal/connectors/github/lib.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright 2022-present Wakflo
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package github

import (
sdk "github.com/wakflo/go-sdk/connector"
)

func NewConnector() (*sdk.ConnectorPlugin, error) {
return sdk.CreateConnector(&sdk.CreateConnectorArgs{
Name: "Github",
Description: "Developer platform that allows developers to create, store, manage and share their code",
Logo: "mdi:github",
Version: "0.0.1",
Group: sdk.ConnectorGroupApps,
Authors: []string{"Wakflo <integrations@wakflo.com>"},
Triggers: []sdk.ITrigger{},
Operations: []sdk.IOperation{
NewCreateIssueOperation(),
NewGetIssueInfoOperation(),
NewCreateIssueCommentOperation(),
NewLockIssueOperation(),
NewUnlockIssueOperation(),
},
})
}
26 changes: 26 additions & 0 deletions internal/connectors/github/model.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package github

type Response struct {
Data Data `json:"data"`
}

// Data contains the node information
type Data struct {
Node Node `json:"node"`
}

// Node contains assignable users information
type Node struct {
AssignableUsers AssignableUsers `json:"assignableUsers"`
}

// AssignableUsers contains a slice of user nodes
type AssignableUsers struct {
Nodes []User `json:"nodes"`
}

// User represents each user with login and ID
type User struct {
Login string `json:"login"`
ID string `json:"id"`
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// Copyright 2022-present Wakflo
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package github

import (
"errors"
"fmt"

"github.com/wakflo/go-sdk/autoform"
sdk "github.com/wakflo/go-sdk/connector"
sdkcore "github.com/wakflo/go-sdk/core"
)

type createIssueCommentOperationProps struct {
Repository string `json:"repository"`
Body string `json:"body"`
IssueNumber string `json:"issue_number"`
}

type CreateIssueCommentOperation struct {
options *sdk.OperationInfo
}

func NewCreateIssueCommentOperation() *CreateIssueCommentOperation {
return &CreateIssueCommentOperation{
options: &sdk.OperationInfo{
Name: "Create comment on a issue",
Description: "Adds a comment to the specified issue (also works with pull requests)",
RequireAuth: true,
Auth: sharedAuth,
Input: map[string]*sdkcore.AutoFormSchema{
"repository": getRepositoryInput(),
"issue_number": getIssuesInput(),
"body": autoform.NewLongTextField().
SetDisplayName("Comment").
SetDescription("Issue comment").
Build(),
},
ErrorSettings: sdkcore.StepErrorSettings{
ContinueOnError: false,
RetryOnError: false,
},
},
}
}

func (c *CreateIssueCommentOperation) Run(ctx *sdk.RunContext) (sdk.JSON, error) {
input, err := sdk.InputToTypeSafely[createIssueCommentOperationProps](ctx)
if err != nil {
return nil, err
}

mutation := fmt.Sprintf(`
mutation {
addComment(input: { subjectId: "%s", body: "%s" }) {
commentEdge {
node {
id
body
createdAt
}
}
}
}`, input.IssueNumber, input.Body)

response, err := githubGQL(ctx.Auth.AccessToken, mutation)
if err != nil {
return nil, errors.New("error making graphQL request")
}

issue, ok := response["data"].(map[string]interface{})["addComment"].(map[string]interface{})["commentEdge"].(map[string]interface{})
if !ok {
return nil, errors.New("failed to extract issue from response")
}

return issue, nil
}

func (c *GetIssueInfoOperation) Test(ctx *sdk.RunContext) (sdk.JSON, error) {
return c.Run(ctx)
}

func (c *GetIssueInfoOperation) GetInfo() *sdk.OperationInfo {
return c.options
}
117 changes: 117 additions & 0 deletions internal/connectors/github/operation_create_issue.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// Copyright 2022-present Wakflo
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package github

import (
"fmt"
"log"
"strings"

"github.com/wakflo/go-sdk/autoform"
sdk "github.com/wakflo/go-sdk/connector"
sdkcore "github.com/wakflo/go-sdk/core"
)

type createIssueOperationProps struct {
Repository string `json:"repository"`
Title string `json:"title"`
Body string `json:"body"`
Labels string `json:"labels"`
}

type CreateIssueOperation struct {
options *sdk.OperationInfo
}

func NewCreateIssueOperation() *CreateIssueOperation {
return &CreateIssueOperation{
options: &sdk.OperationInfo{
Name: "Create Issue",
Description: "Create an issue",
RequireAuth: true,
Auth: sharedAuth,
Input: map[string]*sdkcore.AutoFormSchema{
"repository": getRepositoryInput(),
"title": autoform.NewShortTextField().
SetDisplayName("Issue Name").
SetDescription("The issue name").
SetRequired(true).
Build(),
"body": autoform.NewLongTextField().
SetDisplayName("Description").
SetDescription("Issue description").
Build(),
"labels": getLabelInput(),
},
ErrorSettings: sdkcore.StepErrorSettings{
ContinueOnError: false,
RetryOnError: false,
},
},
}
}

func (c *CreateIssueOperation) Run(ctx *sdk.RunContext) (sdk.JSON, error) {
input, err := sdk.InputToTypeSafely[createIssueOperationProps](ctx)
if err != nil {
return nil, err
}

// Create a map to store fields conditionally
fields := make(map[string]string)
fields["title"] = fmt.Sprintf(`"%s"`, input.Title)
fields["repositoryId"] = fmt.Sprintf(`"%s"`, input.Repository)

if input.Body != "" {
fields["body"] = fmt.Sprintf(`"%s"`, input.Body)
}

if input.Labels != "" {
fields["labelIds"] = fmt.Sprintf(`"%s"`, input.Labels)
}

fieldStrings := make([]string, 0, len(fields))
for key, value := range fields {
fieldStrings = append(fieldStrings, fmt.Sprintf("%s: %s", key, value))
}

mutation := fmt.Sprintf(`
mutation CreateNewIssue {
createIssue(input: {
%s
}) {
issue {
id
title
url
}
}
}`, strings.Join(fieldStrings, "\n"))

response, err := githubGQL(ctx.Auth.AccessToken, mutation)
if err != nil {
log.Fatalf("Error making GraphQL request: %v", err)
}

return response, nil
}

func (c *CreateIssueOperation) Test(ctx *sdk.RunContext) (sdk.JSON, error) {
return c.Run(ctx)
}

func (c *CreateIssueOperation) GetInfo() *sdk.OperationInfo {
return c.options
}
Loading

0 comments on commit bd62d33

Please sign in to comment.