Skip to content

Commit

Permalink
create-project-issue: handle user project boards (#21)
Browse files Browse the repository at this point in the history
Signed-off-by: Paul Meyer <49727155+katexochen@users.noreply.github.com>
  • Loading branch information
katexochen committed Apr 11, 2023
1 parent 5c503ac commit 9b9a934
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 11 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ and a path to a JSON document of metadata. The metadata file looks like this:

```json
{
"organization": "<your org>",
"organization": "<org>",
"user": "<login>",
"projectNumber": 42,
"issueTitle": "<your issue title>",
"assignees": [
Expand All @@ -25,6 +26,9 @@ and a path to a JSON document of metadata. The metadata file looks like this:
}
```

Notice that either `organization` or `user`, and `projectNumber` as well
as `issueTitle` are required fields.

The project number is part of the URL of your target project board.

![GitHub project board URL](assets/project-url.png)
Expand Down
29 changes: 24 additions & 5 deletions internal/cmd/clientv4.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,42 @@ func (c *githubV4Client) QueryUser(ctx context.Context, username string) (*User,
return &q.User, nil
}

func (c *githubV4Client) QueryProject(ctx context.Context, org string, projectNumber int) (*Project, error) {
func (c *githubV4Client) QueryProject(ctx context.Context, owner string, isOrg bool, projectNumber int) (*Project, error) {
if isOrg {
var q struct {
Organization struct {
ProjectV2 Project `graphql:"projectV2(number: $number)"`
} `graphql:"organization(login: $org)"`
}

variables := map[string]interface{}{
"number": githubv4.Int(projectNumber),
"org": githubv4.String(owner),
}

if err := c.client.Query(ctx, &q, variables); err != nil {
return nil, err
}

return &q.Organization.ProjectV2, nil
}

var q struct {
Organization struct {
User struct {
ProjectV2 Project `graphql:"projectV2(number: $number)"`
} `graphql:"organization(login: $org)"`
} `graphql:"user(login: $user)"`
}

variables := map[string]interface{}{
"number": githubv4.Int(projectNumber),
"org": githubv4.String(org),
"user": githubv4.String(owner),
}

if err := c.client.Query(ctx, &q, variables); err != nil {
return nil, err
}

return &q.Organization.ProjectV2, nil
return &q.User.ProjectV2, nil
}

func (c *githubV4Client) AddProjectV2DraftIssue(ctx context.Context, input githubv4.AddProjectV2DraftIssueInput,
Expand Down
19 changes: 14 additions & 5 deletions internal/cmd/projectissue.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,11 @@ func NewCreateProjectIssueCmd() *cobra.Command {
}

type metadata struct {
Organization string // required
ProjectNumber int // required
Organization string // or User required
User string // or Organization required
owner string

ProjectNumber int // required

IssueTitle string
Assignees []string
Expand Down Expand Up @@ -53,7 +56,8 @@ func createProjectIssue(cmd *cobra.Command, _ []string) error {
c := newGithubV4Client(cmd.Context(), token, log)

c.logger.Debugf("searching project %s/%d", flags.Metadata.Organization, flags.Metadata.ProjectNumber)
project, err := c.QueryProject(cmd.Context(), flags.Metadata.Organization, flags.Metadata.ProjectNumber)
isOrg := flags.Metadata.Organization != ""
project, err := c.QueryProject(cmd.Context(), flags.Metadata.owner, isOrg, flags.Metadata.ProjectNumber)
if err != nil {
return fmt.Errorf("querying project: %w", err)
}
Expand Down Expand Up @@ -116,9 +120,14 @@ func parseCreateProjectIssueFlags(cmd *cobra.Command) (createProjectIssueFlags,
if err := json.Unmarshal(metadataBytes, &metadata); err != nil {
return createProjectIssueFlags{}, err
}
if metadata.Organization == "" {
return createProjectIssueFlags{}, errors.New("validating metadata fields: organization is required")
if metadata.Organization != "" {
metadata.owner = metadata.Organization
} else if metadata.User != "" {
metadata.owner = metadata.User
} else {
return createProjectIssueFlags{}, errors.New("validating metadata fields: organization or user is required")
}

if metadata.ProjectNumber == 0 {
return createProjectIssueFlags{}, errors.New("validating metadata fields: project number is required")
}
Expand Down

0 comments on commit 9b9a934

Please sign in to comment.