mirror of
https://github.com/MichaelMure/git-bug.git
synced 2024-12-15 02:01:43 +03:00
Merge pull request #166 from MichaelMure/github-exporter
[Bridge] GitHub exporter
This commit is contained in:
commit
f4d4b2f413
4
Gopkg.lock
generated
4
Gopkg.lock
generated
@ -214,11 +214,11 @@
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:a1562fb3021983f533a27d02ebf36f1bc1ab327660d611d6e948970b54087792"
|
||||
digest = "1:2befa342040f385b214cfd400887b584d5eba4e4b25a0ebaea839ddb0d59c586"
|
||||
name = "github.com/shurcooL/githubv4"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "b5f70540eee0ebfb6a27b52fc5b131be76415539"
|
||||
revision = "068505affed7d8555196a48eb3e0ed43410aa8e8"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
|
36
README.md
36
README.md
@ -116,23 +116,31 @@ The web UI interact with the backend through a GraphQL API. The schema is availa
|
||||
|
||||
### Importer implementations
|
||||
|
||||
| | Github | Launchpad |
|
||||
| ----------------------------------------------- | :----------------: | :----------------: |
|
||||
| **incremental**<br/>(can import more than once) | :heavy_check_mark: | :x: |
|
||||
| **with resume**<br/>(download only new data) | :x: | :x: |
|
||||
| **identities** | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| identities update | :x: | :x: |
|
||||
| **bug** | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| comments | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| comment editions | :heavy_check_mark: | :x: |
|
||||
| labels | :heavy_check_mark: | :x: |
|
||||
| status | :heavy_check_mark: | :x: |
|
||||
| title edition | :heavy_check_mark: | :x: |
|
||||
| **automated test suite** | :x: | :x: |
|
||||
| | Github | Launchpad |
|
||||
| --- | --- | --- |
|
||||
| **incremental**<br/>(can import more than once) | :heavy_check_mark: | :x: |
|
||||
| **with resume**<br/>(download only new data) | :x: | :x: |
|
||||
| **identities** | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| identities update | :x: | :x: |
|
||||
| **bug** | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| comments | :heavy_check_mark: | :heavy_check_mark: |
|
||||
| comment editions | :heavy_check_mark: | :x: |
|
||||
| labels | :heavy_check_mark: | :x: |
|
||||
| status | :heavy_check_mark: | :x: |
|
||||
| title edition | :heavy_check_mark: | :x: |
|
||||
| **automated test suite** | :heavy_check_mark: | :x: |
|
||||
|
||||
### Exporter implementations
|
||||
|
||||
Todo !
|
||||
| | Github | Launchpad |
|
||||
| --- | --- | --- |
|
||||
| **bug** | :heavy_check_mark: | :x: |
|
||||
| comments | :heavy_check_mark: | :x: |
|
||||
| comment editions | :heavy_check_mark: | :x: |
|
||||
| labels | :heavy_check_mark: | :x: |
|
||||
| status | :heavy_check_mark: | :x: |
|
||||
| title edition | :heavy_check_mark: | :x: |
|
||||
| **automated test suite** | :heavy_check_mark: | :x: |
|
||||
|
||||
## Internals
|
||||
|
||||
|
@ -297,20 +297,20 @@ func (b *Bridge) ImportAll(since time.Time) error {
|
||||
return importer.ImportAll(b.repo, since)
|
||||
}
|
||||
|
||||
func (b *Bridge) ExportAll(since time.Time) error {
|
||||
func (b *Bridge) ExportAll(since time.Time) (<-chan ExportResult, error) {
|
||||
exporter := b.getExporter()
|
||||
if exporter == nil {
|
||||
return ErrExportNotSupported
|
||||
return nil, ErrExportNotSupported
|
||||
}
|
||||
|
||||
err := b.ensureConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = b.ensureInit()
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return exporter.ExportAll(b.repo, since)
|
||||
|
101
bridge/core/export.go
Normal file
101
bridge/core/export.go
Normal file
@ -0,0 +1,101 @@
|
||||
package core
|
||||
|
||||
import "fmt"
|
||||
|
||||
type ExportEvent int
|
||||
|
||||
const (
|
||||
_ ExportEvent = iota
|
||||
ExportEventBug
|
||||
ExportEventComment
|
||||
ExportEventCommentEdition
|
||||
ExportEventStatusChange
|
||||
ExportEventTitleEdition
|
||||
ExportEventLabelChange
|
||||
ExportEventNothing
|
||||
)
|
||||
|
||||
type ExportResult struct {
|
||||
Err error
|
||||
Event ExportEvent
|
||||
ID string
|
||||
Reason string
|
||||
}
|
||||
|
||||
func (er ExportResult) String() string {
|
||||
switch er.Event {
|
||||
case ExportEventBug:
|
||||
return "new issue"
|
||||
case ExportEventComment:
|
||||
return "new comment"
|
||||
case ExportEventCommentEdition:
|
||||
return "updated comment"
|
||||
case ExportEventStatusChange:
|
||||
return "changed status"
|
||||
case ExportEventTitleEdition:
|
||||
return "changed title"
|
||||
case ExportEventLabelChange:
|
||||
return "changed label"
|
||||
case ExportEventNothing:
|
||||
return fmt.Sprintf("no event: %v", er.Reason)
|
||||
default:
|
||||
panic("unknown export result")
|
||||
}
|
||||
}
|
||||
|
||||
func NewExportError(err error, reason string) ExportResult {
|
||||
return ExportResult{
|
||||
Err: err,
|
||||
Reason: reason,
|
||||
}
|
||||
}
|
||||
|
||||
func NewExportNothing(id string, reason string) ExportResult {
|
||||
return ExportResult{
|
||||
ID: id,
|
||||
Reason: reason,
|
||||
Event: ExportEventNothing,
|
||||
}
|
||||
}
|
||||
|
||||
func NewExportBug(id string) ExportResult {
|
||||
return ExportResult{
|
||||
ID: id,
|
||||
Event: ExportEventBug,
|
||||
}
|
||||
}
|
||||
|
||||
func NewExportComment(id string) ExportResult {
|
||||
return ExportResult{
|
||||
ID: id,
|
||||
Event: ExportEventComment,
|
||||
}
|
||||
}
|
||||
|
||||
func NewExportCommentEdition(id string) ExportResult {
|
||||
return ExportResult{
|
||||
ID: id,
|
||||
Event: ExportEventCommentEdition,
|
||||
}
|
||||
}
|
||||
|
||||
func NewExportStatusChange(id string) ExportResult {
|
||||
return ExportResult{
|
||||
ID: id,
|
||||
Event: ExportEventStatusChange,
|
||||
}
|
||||
}
|
||||
|
||||
func NewExportLabelChange(id string) ExportResult {
|
||||
return ExportResult{
|
||||
ID: id,
|
||||
Event: ExportEventLabelChange,
|
||||
}
|
||||
}
|
||||
|
||||
func NewExportTitleEdition(id string) ExportResult {
|
||||
return ExportResult{
|
||||
ID: id,
|
||||
Event: ExportEventTitleEdition,
|
||||
}
|
||||
}
|
@ -34,5 +34,5 @@ type Importer interface {
|
||||
|
||||
type Exporter interface {
|
||||
Init(conf Configuration) error
|
||||
ExportAll(repo *cache.RepoCache, since time.Time) error
|
||||
ExportAll(repo *cache.RepoCache, since time.Time) (<-chan ExportResult, error)
|
||||
}
|
||||
|
795
bridge/github/export.go
Normal file
795
bridge/github/export.go
Normal file
@ -0,0 +1,795 @@
|
||||
package github
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/shurcooL/githubv4"
|
||||
|
||||
"github.com/MichaelMure/git-bug/bridge/core"
|
||||
"github.com/MichaelMure/git-bug/bug"
|
||||
"github.com/MichaelMure/git-bug/cache"
|
||||
"github.com/MichaelMure/git-bug/util/git"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrMissingIdentityToken = errors.New("missing identity token")
|
||||
)
|
||||
|
||||
// githubExporter implement the Exporter interface
|
||||
type githubExporter struct {
|
||||
conf core.Configuration
|
||||
|
||||
// cache identities clients
|
||||
identityClient map[string]*githubv4.Client
|
||||
|
||||
// map identities with their tokens
|
||||
identityToken map[string]string
|
||||
|
||||
// github repository ID
|
||||
repositoryID string
|
||||
|
||||
// cache identifiers used to speed up exporting operations
|
||||
// cleared for each bug
|
||||
cachedOperationIDs map[string]string
|
||||
|
||||
// cache labels used to speed up exporting labels events
|
||||
cachedLabels map[string]string
|
||||
}
|
||||
|
||||
// Init .
|
||||
func (ge *githubExporter) Init(conf core.Configuration) error {
|
||||
ge.conf = conf
|
||||
//TODO: initialize with multiple tokens
|
||||
ge.identityToken = make(map[string]string)
|
||||
ge.identityClient = make(map[string]*githubv4.Client)
|
||||
ge.cachedOperationIDs = make(map[string]string)
|
||||
ge.cachedLabels = make(map[string]string)
|
||||
return nil
|
||||
}
|
||||
|
||||
// getIdentityClient return a githubv4 API client configured with the access token of the given identity.
|
||||
// if no client were found it will initialize it from the known tokens map and cache it for next use
|
||||
func (ge *githubExporter) getIdentityClient(id string) (*githubv4.Client, error) {
|
||||
client, ok := ge.identityClient[id]
|
||||
if ok {
|
||||
return client, nil
|
||||
}
|
||||
|
||||
// get token
|
||||
token, ok := ge.identityToken[id]
|
||||
if !ok {
|
||||
return nil, ErrMissingIdentityToken
|
||||
}
|
||||
|
||||
// create client
|
||||
client = buildClient(token)
|
||||
// cache client
|
||||
ge.identityClient[id] = client
|
||||
|
||||
return client, nil
|
||||
}
|
||||
|
||||
// ExportAll export all event made by the current user to Github
|
||||
func (ge *githubExporter) ExportAll(repo *cache.RepoCache, since time.Time) (<-chan core.ExportResult, error) {
|
||||
out := make(chan core.ExportResult)
|
||||
|
||||
user, err := repo.GetUserIdentity()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ge.identityToken[user.Id()] = ge.conf[keyToken]
|
||||
|
||||
// get repository node id
|
||||
ge.repositoryID, err = getRepositoryNodeID(
|
||||
ge.conf[keyOwner],
|
||||
ge.conf[keyProject],
|
||||
ge.conf[keyToken],
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
go func() {
|
||||
defer close(out)
|
||||
|
||||
var allIdentitiesIds []string
|
||||
for id := range ge.identityToken {
|
||||
allIdentitiesIds = append(allIdentitiesIds, id)
|
||||
}
|
||||
|
||||
allBugsIds := repo.AllBugsIds()
|
||||
|
||||
for _, id := range allBugsIds {
|
||||
b, err := repo.ResolveBug(id)
|
||||
if err != nil {
|
||||
out <- core.NewExportError(err, id)
|
||||
return
|
||||
}
|
||||
|
||||
snapshot := b.Snapshot()
|
||||
|
||||
// ignore issues created before since date
|
||||
// TODO: compare the Lamport time instead of using the unix time
|
||||
if snapshot.CreatedAt.Before(since) {
|
||||
out <- core.NewExportNothing(b.Id(), "bug created before the since date")
|
||||
continue
|
||||
}
|
||||
|
||||
if snapshot.HasAnyActor(allIdentitiesIds...) {
|
||||
// try to export the bug and it associated events
|
||||
ge.exportBug(b, since, out)
|
||||
} else {
|
||||
out <- core.NewExportNothing(id, "not an actor")
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// exportBug publish bugs and related events
|
||||
func (ge *githubExporter) exportBug(b *cache.BugCache, since time.Time, out chan<- core.ExportResult) {
|
||||
snapshot := b.Snapshot()
|
||||
|
||||
var bugGithubID string
|
||||
var bugGithubURL string
|
||||
var bugCreationHash string
|
||||
|
||||
// Special case:
|
||||
// if a user try to export a bug that is not already exported to Github (or imported
|
||||
// from Github) and we do not have the token of the bug author, there is nothing we can do.
|
||||
|
||||
// first operation is always createOp
|
||||
createOp := snapshot.Operations[0].(*bug.CreateOperation)
|
||||
author := snapshot.Author
|
||||
|
||||
// skip bug if origin is not allowed
|
||||
origin, ok := snapshot.GetCreateMetadata(keyOrigin)
|
||||
if ok && origin != target {
|
||||
out <- core.NewExportNothing(b.Id(), fmt.Sprintf("issue tagged with origin: %s", origin))
|
||||
return
|
||||
}
|
||||
|
||||
// get github bug ID
|
||||
githubID, ok := snapshot.GetCreateMetadata(keyGithubId)
|
||||
if ok {
|
||||
githubURL, ok := snapshot.GetCreateMetadata(keyGithubUrl)
|
||||
if !ok {
|
||||
// if we find github ID, github URL must be found too
|
||||
err := fmt.Errorf("expected to find github issue URL")
|
||||
out <- core.NewExportError(err, b.Id())
|
||||
}
|
||||
|
||||
// extract owner and project
|
||||
owner, project, err := splitURL(githubURL)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("bad project url: %v", err)
|
||||
out <- core.NewExportError(err, b.Id())
|
||||
return
|
||||
}
|
||||
|
||||
// ignore issue comming from other repositories
|
||||
if owner != ge.conf[keyOwner] && project != ge.conf[keyProject] {
|
||||
out <- core.NewExportNothing(b.Id(), fmt.Sprintf("skipping issue from url:%s", githubURL))
|
||||
return
|
||||
}
|
||||
|
||||
out <- core.NewExportNothing(b.Id(), "bug already exported")
|
||||
// will be used to mark operation related to a bug as exported
|
||||
bugGithubID = githubID
|
||||
bugGithubURL = githubURL
|
||||
|
||||
} else {
|
||||
// check that we have a token for operation author
|
||||
client, err := ge.getIdentityClient(author.Id())
|
||||
if err != nil {
|
||||
// if bug is still not exported and we do not have the author stop the execution
|
||||
out <- core.NewExportNothing(b.Id(), fmt.Sprintf("missing author token"))
|
||||
return
|
||||
}
|
||||
|
||||
// create bug
|
||||
id, url, err := createGithubIssue(client, ge.repositoryID, createOp.Title, createOp.Message)
|
||||
if err != nil {
|
||||
err := errors.Wrap(err, "exporting github issue")
|
||||
out <- core.NewExportError(err, b.Id())
|
||||
return
|
||||
}
|
||||
|
||||
out <- core.NewExportBug(b.Id())
|
||||
|
||||
hash, err := createOp.Hash()
|
||||
if err != nil {
|
||||
err := errors.Wrap(err, "comment hash")
|
||||
out <- core.NewExportError(err, b.Id())
|
||||
return
|
||||
}
|
||||
|
||||
// mark bug creation operation as exported
|
||||
if err := markOperationAsExported(b, hash, id, url); err != nil {
|
||||
err := errors.Wrap(err, "marking operation as exported")
|
||||
out <- core.NewExportError(err, b.Id())
|
||||
return
|
||||
}
|
||||
|
||||
// commit operation to avoid creating multiple issues with multiple pushes
|
||||
if err := b.CommitAsNeeded(); err != nil {
|
||||
err := errors.Wrap(err, "bug commit")
|
||||
out <- core.NewExportError(err, b.Id())
|
||||
return
|
||||
}
|
||||
|
||||
// cache bug github ID and URL
|
||||
bugGithubID = id
|
||||
bugGithubURL = url
|
||||
}
|
||||
|
||||
// get createOp hash
|
||||
hash, err := createOp.Hash()
|
||||
if err != nil {
|
||||
out <- core.NewExportError(err, b.Id())
|
||||
return
|
||||
}
|
||||
|
||||
bugCreationHash = hash.String()
|
||||
|
||||
// cache operation github id
|
||||
ge.cachedOperationIDs[bugCreationHash] = bugGithubID
|
||||
|
||||
for _, op := range snapshot.Operations[1:] {
|
||||
// ignore SetMetadata operations
|
||||
if _, ok := op.(*bug.SetMetadataOperation); ok {
|
||||
continue
|
||||
}
|
||||
|
||||
// get operation hash
|
||||
hash, err := op.Hash()
|
||||
if err != nil {
|
||||
err := errors.Wrap(err, "operation hash")
|
||||
out <- core.NewExportError(err, b.Id())
|
||||
return
|
||||
}
|
||||
|
||||
// ignore operations already existing in github (due to import or export)
|
||||
// cache the ID of already exported or imported issues and events from Github
|
||||
if id, ok := op.GetMetadata(keyGithubId); ok {
|
||||
ge.cachedOperationIDs[hash.String()] = id
|
||||
out <- core.NewExportNothing(hash.String(), "already exported operation")
|
||||
continue
|
||||
}
|
||||
|
||||
opAuthor := op.GetAuthor()
|
||||
client, err := ge.getIdentityClient(opAuthor.Id())
|
||||
if err != nil {
|
||||
out <- core.NewExportNothing(hash.String(), "missing operation author token")
|
||||
continue
|
||||
}
|
||||
|
||||
var id, url string
|
||||
switch op.(type) {
|
||||
case *bug.AddCommentOperation:
|
||||
opr := op.(*bug.AddCommentOperation)
|
||||
|
||||
// send operation to github
|
||||
id, url, err = addCommentGithubIssue(client, bugGithubID, opr.Message)
|
||||
if err != nil {
|
||||
err := errors.Wrap(err, "adding comment")
|
||||
out <- core.NewExportError(err, b.Id())
|
||||
return
|
||||
}
|
||||
|
||||
out <- core.NewExportComment(hash.String())
|
||||
|
||||
// cache comment id
|
||||
ge.cachedOperationIDs[hash.String()] = id
|
||||
|
||||
case *bug.EditCommentOperation:
|
||||
|
||||
opr := op.(*bug.EditCommentOperation)
|
||||
targetHash := opr.Target.String()
|
||||
|
||||
// Since github doesn't consider the issue body as a comment
|
||||
if targetHash == bugCreationHash {
|
||||
|
||||
// case bug creation operation: we need to edit the Github issue
|
||||
if err := updateGithubIssueBody(client, bugGithubID, opr.Message); err != nil {
|
||||
err := errors.Wrap(err, "editing issue")
|
||||
out <- core.NewExportError(err, b.Id())
|
||||
return
|
||||
}
|
||||
|
||||
out <- core.NewExportCommentEdition(hash.String())
|
||||
|
||||
id = bugGithubID
|
||||
url = bugGithubURL
|
||||
|
||||
} else {
|
||||
|
||||
// case comment edition operation: we need to edit the Github comment
|
||||
commentID, ok := ge.cachedOperationIDs[targetHash]
|
||||
if !ok {
|
||||
panic("unexpected error: comment id not found")
|
||||
}
|
||||
|
||||
eid, eurl, err := editCommentGithubIssue(client, commentID, opr.Message)
|
||||
if err != nil {
|
||||
err := errors.Wrap(err, "editing comment")
|
||||
out <- core.NewExportError(err, b.Id())
|
||||
return
|
||||
}
|
||||
|
||||
out <- core.NewExportCommentEdition(hash.String())
|
||||
|
||||
// use comment id/url instead of issue id/url
|
||||
id = eid
|
||||
url = eurl
|
||||
}
|
||||
|
||||
case *bug.SetStatusOperation:
|
||||
opr := op.(*bug.SetStatusOperation)
|
||||
if err := updateGithubIssueStatus(client, bugGithubID, opr.Status); err != nil {
|
||||
err := errors.Wrap(err, "editing status")
|
||||
out <- core.NewExportError(err, b.Id())
|
||||
return
|
||||
}
|
||||
|
||||
out <- core.NewExportStatusChange(hash.String())
|
||||
|
||||
id = bugGithubID
|
||||
url = bugGithubURL
|
||||
|
||||
case *bug.SetTitleOperation:
|
||||
opr := op.(*bug.SetTitleOperation)
|
||||
if err := updateGithubIssueTitle(client, bugGithubID, opr.Title); err != nil {
|
||||
err := errors.Wrap(err, "editing title")
|
||||
out <- core.NewExportError(err, b.Id())
|
||||
return
|
||||
}
|
||||
|
||||
out <- core.NewExportTitleEdition(hash.String())
|
||||
|
||||
id = bugGithubID
|
||||
url = bugGithubURL
|
||||
|
||||
case *bug.LabelChangeOperation:
|
||||
opr := op.(*bug.LabelChangeOperation)
|
||||
if err := ge.updateGithubIssueLabels(client, bugGithubID, opr.Added, opr.Removed); err != nil {
|
||||
err := errors.Wrap(err, "updating labels")
|
||||
out <- core.NewExportError(err, b.Id())
|
||||
return
|
||||
}
|
||||
|
||||
out <- core.NewExportLabelChange(hash.String())
|
||||
|
||||
id = bugGithubID
|
||||
url = bugGithubURL
|
||||
|
||||
default:
|
||||
panic("unhandled operation type case")
|
||||
}
|
||||
|
||||
// mark operation as exported
|
||||
if err := markOperationAsExported(b, hash, id, url); err != nil {
|
||||
err := errors.Wrap(err, "marking operation as exported")
|
||||
out <- core.NewExportError(err, b.Id())
|
||||
return
|
||||
}
|
||||
|
||||
// commit at each operation export to avoid exporting same events multiple times
|
||||
if err := b.CommitAsNeeded(); err != nil {
|
||||
err := errors.Wrap(err, "bug commit")
|
||||
out <- core.NewExportError(err, b.Id())
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// getRepositoryNodeID request github api v3 to get repository node id
|
||||
func getRepositoryNodeID(owner, project, token string) (string, error) {
|
||||
url := fmt.Sprintf("%s/repos/%s/%s", githubV3Url, owner, project)
|
||||
|
||||
client := &http.Client{
|
||||
Timeout: defaultTimeout,
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// need the token for private repositories
|
||||
req.Header.Set("Authorization", fmt.Sprintf("token %s", token))
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return "", fmt.Errorf("HTTP error %v retrieving repository node id", resp.StatusCode)
|
||||
}
|
||||
|
||||
aux := struct {
|
||||
NodeID string `json:"node_id"`
|
||||
}{}
|
||||
|
||||
data, _ := ioutil.ReadAll(resp.Body)
|
||||
err = resp.Body.Close()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(data, &aux)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return aux.NodeID, nil
|
||||
}
|
||||
|
||||
func markOperationAsExported(b *cache.BugCache, target git.Hash, githubID, githubURL string) error {
|
||||
_, err := b.SetMetadata(
|
||||
target,
|
||||
map[string]string{
|
||||
keyGithubId: githubID,
|
||||
keyGithubUrl: githubURL,
|
||||
},
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// get label from github
|
||||
func (ge *githubExporter) getGithubLabelID(gc *githubv4.Client, label string) (string, error) {
|
||||
q := &labelQuery{}
|
||||
variables := map[string]interface{}{
|
||||
"label": githubv4.String(label),
|
||||
"owner": githubv4.String(ge.conf[keyOwner]),
|
||||
"name": githubv4.String(ge.conf[keyProject]),
|
||||
}
|
||||
|
||||
parentCtx := context.Background()
|
||||
ctx, cancel := context.WithTimeout(parentCtx, defaultTimeout)
|
||||
defer cancel()
|
||||
|
||||
if err := gc.Query(ctx, q, variables); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// if label id is empty, it means there is no such label in this Github repository
|
||||
if q.Repository.Label.ID == "" {
|
||||
return "", fmt.Errorf("label not found")
|
||||
}
|
||||
|
||||
return q.Repository.Label.ID, nil
|
||||
}
|
||||
|
||||
// create a new label and return it github id
|
||||
// NOTE: since createLabel mutation is still in preview mode we use github api v3 to create labels
|
||||
// see https://developer.github.com/v4/mutation/createlabel/ and https://developer.github.com/v4/previews/#labels-preview
|
||||
func (ge *githubExporter) createGithubLabel(label, color string) (string, error) {
|
||||
url := fmt.Sprintf("%s/repos/%s/%s/labels", githubV3Url, ge.conf[keyOwner], ge.conf[keyProject])
|
||||
|
||||
client := &http.Client{
|
||||
Timeout: defaultTimeout,
|
||||
}
|
||||
|
||||
params := struct {
|
||||
Name string `json:"name"`
|
||||
Color string `json:"color"`
|
||||
Description string `json:"description"`
|
||||
}{
|
||||
Name: label,
|
||||
Color: color,
|
||||
}
|
||||
|
||||
data, err := json.Marshal(params)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", url, bytes.NewBuffer(data))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// need the token for private repositories
|
||||
req.Header.Set("Authorization", fmt.Sprintf("token %s", ge.conf[keyToken]))
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusCreated {
|
||||
return "", fmt.Errorf("error creating label: response status %v", resp.StatusCode)
|
||||
}
|
||||
|
||||
aux := struct {
|
||||
ID int `json:"id"`
|
||||
NodeID string `json:"node_id"`
|
||||
Color string `json:"color"`
|
||||
}{}
|
||||
|
||||
data, _ = ioutil.ReadAll(resp.Body)
|
||||
defer resp.Body.Close()
|
||||
|
||||
err = json.Unmarshal(data, &aux)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return aux.NodeID, nil
|
||||
}
|
||||
|
||||
/**
|
||||
// create github label using api v4
|
||||
func (ge *githubExporter) createGithubLabelV4(gc *githubv4.Client, label, labelColor string) (string, error) {
|
||||
m := createLabelMutation{}
|
||||
input := createLabelInput{
|
||||
RepositoryID: ge.repositoryID,
|
||||
Name: githubv4.String(label),
|
||||
Color: githubv4.String(labelColor),
|
||||
}
|
||||
|
||||
parentCtx := context.Background()
|
||||
ctx, cancel := context.WithTimeout(parentCtx, defaultTimeout)
|
||||
defer cancel()
|
||||
|
||||
if err := gc.Mutate(ctx, &m, input, nil); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return m.CreateLabel.Label.ID, nil
|
||||
}
|
||||
*/
|
||||
|
||||
func (ge *githubExporter) getOrCreateGithubLabelID(gc *githubv4.Client, repositoryID string, label bug.Label) (string, error) {
|
||||
// try to get label id
|
||||
labelID, err := ge.getGithubLabelID(gc, string(label))
|
||||
if err == nil {
|
||||
return labelID, nil
|
||||
}
|
||||
|
||||
// RGBA to hex color
|
||||
rgba := label.RGBA()
|
||||
hexColor := fmt.Sprintf("%.2x%.2x%.2x", rgba.R, rgba.G, rgba.B)
|
||||
|
||||
labelID, err = ge.createGithubLabel(string(label), hexColor)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return labelID, nil
|
||||
}
|
||||
|
||||
func (ge *githubExporter) getLabelsIDs(gc *githubv4.Client, repositoryID string, labels []bug.Label) ([]githubv4.ID, error) {
|
||||
ids := make([]githubv4.ID, 0, len(labels))
|
||||
var err error
|
||||
|
||||
// check labels ids
|
||||
for _, label := range labels {
|
||||
id, ok := ge.cachedLabels[string(label)]
|
||||
if !ok {
|
||||
// try to query label id
|
||||
id, err = ge.getOrCreateGithubLabelID(gc, repositoryID, label)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "get or create github label")
|
||||
}
|
||||
|
||||
// cache label id
|
||||
ge.cachedLabels[string(label)] = id
|
||||
}
|
||||
|
||||
ids = append(ids, githubv4.ID(id))
|
||||
}
|
||||
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
// create a github issue and return it ID
|
||||
func createGithubIssue(gc *githubv4.Client, repositoryID, title, body string) (string, string, error) {
|
||||
m := &createIssueMutation{}
|
||||
input := githubv4.CreateIssueInput{
|
||||
RepositoryID: repositoryID,
|
||||
Title: githubv4.String(title),
|
||||
Body: (*githubv4.String)(&body),
|
||||
}
|
||||
|
||||
parentCtx := context.Background()
|
||||
ctx, cancel := context.WithTimeout(parentCtx, defaultTimeout)
|
||||
defer cancel()
|
||||
|
||||
if err := gc.Mutate(ctx, m, input, nil); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
issue := m.CreateIssue.Issue
|
||||
return issue.ID, issue.URL, nil
|
||||
}
|
||||
|
||||
// add a comment to an issue and return it ID
|
||||
func addCommentGithubIssue(gc *githubv4.Client, subjectID string, body string) (string, string, error) {
|
||||
m := &addCommentToIssueMutation{}
|
||||
input := githubv4.AddCommentInput{
|
||||
SubjectID: subjectID,
|
||||
Body: githubv4.String(body),
|
||||
}
|
||||
|
||||
parentCtx := context.Background()
|
||||
ctx, cancel := context.WithTimeout(parentCtx, defaultTimeout)
|
||||
defer cancel()
|
||||
|
||||
if err := gc.Mutate(ctx, m, input, nil); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
node := m.AddComment.CommentEdge.Node
|
||||
return node.ID, node.URL, nil
|
||||
}
|
||||
|
||||
func editCommentGithubIssue(gc *githubv4.Client, commentID, body string) (string, string, error) {
|
||||
m := &updateIssueCommentMutation{}
|
||||
input := githubv4.UpdateIssueCommentInput{
|
||||
ID: commentID,
|
||||
Body: githubv4.String(body),
|
||||
}
|
||||
|
||||
parentCtx := context.Background()
|
||||
ctx, cancel := context.WithTimeout(parentCtx, defaultTimeout)
|
||||
defer cancel()
|
||||
|
||||
if err := gc.Mutate(ctx, m, input, nil); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
return commentID, m.UpdateIssueComment.IssueComment.URL, nil
|
||||
}
|
||||
|
||||
func updateGithubIssueStatus(gc *githubv4.Client, id string, status bug.Status) error {
|
||||
m := &updateIssueMutation{}
|
||||
|
||||
// set state
|
||||
var state githubv4.IssueState
|
||||
|
||||
switch status {
|
||||
case bug.OpenStatus:
|
||||
state = githubv4.IssueStateOpen
|
||||
case bug.ClosedStatus:
|
||||
state = githubv4.IssueStateClosed
|
||||
default:
|
||||
panic("unknown bug state")
|
||||
}
|
||||
|
||||
input := githubv4.UpdateIssueInput{
|
||||
ID: id,
|
||||
State: &state,
|
||||
}
|
||||
|
||||
parentCtx := context.Background()
|
||||
ctx, cancel := context.WithTimeout(parentCtx, defaultTimeout)
|
||||
defer cancel()
|
||||
|
||||
if err := gc.Mutate(ctx, m, input, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func updateGithubIssueBody(gc *githubv4.Client, id string, body string) error {
|
||||
m := &updateIssueMutation{}
|
||||
input := githubv4.UpdateIssueInput{
|
||||
ID: id,
|
||||
Body: (*githubv4.String)(&body),
|
||||
}
|
||||
|
||||
parentCtx := context.Background()
|
||||
ctx, cancel := context.WithTimeout(parentCtx, defaultTimeout)
|
||||
defer cancel()
|
||||
|
||||
if err := gc.Mutate(ctx, m, input, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func updateGithubIssueTitle(gc *githubv4.Client, id, title string) error {
|
||||
m := &updateIssueMutation{}
|
||||
input := githubv4.UpdateIssueInput{
|
||||
ID: id,
|
||||
Title: (*githubv4.String)(&title),
|
||||
}
|
||||
|
||||
parentCtx := context.Background()
|
||||
ctx, cancel := context.WithTimeout(parentCtx, defaultTimeout)
|
||||
defer cancel()
|
||||
|
||||
if err := gc.Mutate(ctx, m, input, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// update github issue labels
|
||||
func (ge *githubExporter) updateGithubIssueLabels(gc *githubv4.Client, labelableID string, added, removed []bug.Label) error {
|
||||
var errs []string
|
||||
var wg sync.WaitGroup
|
||||
|
||||
parentCtx := context.Background()
|
||||
|
||||
if len(added) > 0 {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
addedIDs, err := ge.getLabelsIDs(gc, labelableID, added)
|
||||
if err != nil {
|
||||
errs = append(errs, errors.Wrap(err, "getting added labels ids").Error())
|
||||
return
|
||||
}
|
||||
|
||||
m := &addLabelsToLabelableMutation{}
|
||||
inputAdd := githubv4.AddLabelsToLabelableInput{
|
||||
LabelableID: labelableID,
|
||||
LabelIDs: addedIDs,
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(parentCtx, defaultTimeout)
|
||||
defer cancel()
|
||||
|
||||
// add labels
|
||||
if err := gc.Mutate(ctx, m, inputAdd, nil); err != nil {
|
||||
errs = append(errs, err.Error())
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
if len(removed) > 0 {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
removedIDs, err := ge.getLabelsIDs(gc, labelableID, removed)
|
||||
if err != nil {
|
||||
errs = append(errs, errors.Wrap(err, "getting added labels ids").Error())
|
||||
return
|
||||
}
|
||||
|
||||
m2 := &removeLabelsFromLabelableMutation{}
|
||||
inputRemove := githubv4.RemoveLabelsFromLabelableInput{
|
||||
LabelableID: labelableID,
|
||||
LabelIDs: removedIDs,
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(parentCtx, defaultTimeout)
|
||||
defer cancel()
|
||||
|
||||
// remove label labels
|
||||
if err := gc.Mutate(ctx, m2, inputRemove, nil); err != nil {
|
||||
errs = append(errs, err.Error())
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
|
||||
if len(errs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("label change error: %v", strings.Join(errs, "\n"))
|
||||
}
|
74
bridge/github/export_mutation.go
Normal file
74
bridge/github/export_mutation.go
Normal file
@ -0,0 +1,74 @@
|
||||
package github
|
||||
|
||||
type createIssueMutation struct {
|
||||
CreateIssue struct {
|
||||
Issue struct {
|
||||
ID string `graphql:"id"`
|
||||
URL string `graphql:"url"`
|
||||
}
|
||||
} `graphql:"createIssue(input:$input)"`
|
||||
}
|
||||
|
||||
type updateIssueMutation struct {
|
||||
UpdateIssue struct {
|
||||
Issue struct {
|
||||
ID string `graphql:"id"`
|
||||
URL string `graphql:"url"`
|
||||
}
|
||||
} `graphql:"updateIssue(input:$input)"`
|
||||
}
|
||||
|
||||
type addCommentToIssueMutation struct {
|
||||
AddComment struct {
|
||||
CommentEdge struct {
|
||||
Node struct {
|
||||
ID string `graphql:"id"`
|
||||
URL string `graphql:"url"`
|
||||
}
|
||||
}
|
||||
} `graphql:"addComment(input:$input)"`
|
||||
}
|
||||
|
||||
type updateIssueCommentMutation struct {
|
||||
UpdateIssueComment struct {
|
||||
IssueComment struct {
|
||||
ID string `graphql:"id"`
|
||||
URL string `graphql:"url"`
|
||||
} `graphql:"issueComment"`
|
||||
} `graphql:"updateIssueComment(input:$input)"`
|
||||
}
|
||||
|
||||
type removeLabelsFromLabelableMutation struct {
|
||||
AddLabels struct {
|
||||
Labelable struct {
|
||||
Typename string `graphql:"__typename"`
|
||||
}
|
||||
} `graphql:"removeLabelsFromLabelable(input:$input)"`
|
||||
}
|
||||
|
||||
type addLabelsToLabelableMutation struct {
|
||||
RemoveLabels struct {
|
||||
Labelable struct {
|
||||
Typename string `graphql:"__typename"`
|
||||
}
|
||||
} `graphql:"addLabelsToLabelable(input:$input)"`
|
||||
}
|
||||
|
||||
/**
|
||||
type createLabelMutation struct {
|
||||
CreateLabel struct {
|
||||
Label struct {
|
||||
ID string `graphql:"id"`
|
||||
} `graphql:"label"`
|
||||
} `graphql:"createLabel(input: $input)"`
|
||||
}
|
||||
|
||||
type createLabelInput struct {
|
||||
Color githubv4.String `json:"color"`
|
||||
Description *githubv4.String `json:"description,omitempty"`
|
||||
Name githubv4.String `json:"name"`
|
||||
RepositoryID githubv4.ID `json:"repositoryId"`
|
||||
|
||||
ClientMutationID *githubv4.String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
*/
|
340
bridge/github/export_test.go
Normal file
340
bridge/github/export_test.go
Normal file
@ -0,0 +1,340 @@
|
||||
package github
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/MichaelMure/git-bug/bridge/core"
|
||||
"github.com/MichaelMure/git-bug/bug"
|
||||
"github.com/MichaelMure/git-bug/cache"
|
||||
"github.com/MichaelMure/git-bug/repository"
|
||||
"github.com/MichaelMure/git-bug/util/interrupt"
|
||||
)
|
||||
|
||||
const (
|
||||
testRepoBaseName = "git-bug-test-github-exporter"
|
||||
)
|
||||
|
||||
type testCase struct {
|
||||
name string
|
||||
bug *cache.BugCache
|
||||
numOrOp int // number of original operations
|
||||
}
|
||||
|
||||
func testCases(t *testing.T, repo *cache.RepoCache, identity *cache.IdentityCache) []*testCase {
|
||||
// simple bug
|
||||
simpleBug, _, err := repo.NewBug("simple bug", "new bug")
|
||||
require.NoError(t, err)
|
||||
|
||||
// bug with comments
|
||||
bugWithComments, _, err := repo.NewBug("bug with comments", "new bug")
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = bugWithComments.AddComment("new comment")
|
||||
require.NoError(t, err)
|
||||
|
||||
// bug with label changes
|
||||
bugLabelChange, _, err := repo.NewBug("bug label change", "new bug")
|
||||
require.NoError(t, err)
|
||||
|
||||
_, _, err = bugLabelChange.ChangeLabels([]string{"bug"}, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, _, err = bugLabelChange.ChangeLabels([]string{"core"}, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, _, err = bugLabelChange.ChangeLabels(nil, []string{"bug"})
|
||||
require.NoError(t, err)
|
||||
|
||||
// bug with comments editions
|
||||
bugWithCommentEditions, createOp, err := repo.NewBug("bug with comments editions", "new bug")
|
||||
require.NoError(t, err)
|
||||
|
||||
createOpHash, err := createOp.Hash()
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = bugWithCommentEditions.EditComment(createOpHash, "first comment edited")
|
||||
require.NoError(t, err)
|
||||
|
||||
commentOp, err := bugWithCommentEditions.AddComment("first comment")
|
||||
require.NoError(t, err)
|
||||
|
||||
commentOpHash, err := commentOp.Hash()
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = bugWithCommentEditions.EditComment(commentOpHash, "first comment edited")
|
||||
require.NoError(t, err)
|
||||
|
||||
// bug status changed
|
||||
bugStatusChanged, _, err := repo.NewBug("bug status changed", "new bug")
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = bugStatusChanged.Close()
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = bugStatusChanged.Open()
|
||||
require.NoError(t, err)
|
||||
|
||||
// bug title changed
|
||||
bugTitleEdited, _, err := repo.NewBug("bug title edited", "new bug")
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = bugTitleEdited.SetTitle("bug title edited again")
|
||||
require.NoError(t, err)
|
||||
|
||||
return []*testCase{
|
||||
&testCase{
|
||||
name: "simple bug",
|
||||
bug: simpleBug,
|
||||
numOrOp: 1,
|
||||
},
|
||||
&testCase{
|
||||
name: "bug with comments",
|
||||
bug: bugWithComments,
|
||||
numOrOp: 2,
|
||||
},
|
||||
&testCase{
|
||||
name: "bug label change",
|
||||
bug: bugLabelChange,
|
||||
numOrOp: 4,
|
||||
},
|
||||
&testCase{
|
||||
name: "bug with comment editions",
|
||||
bug: bugWithCommentEditions,
|
||||
numOrOp: 4,
|
||||
},
|
||||
&testCase{
|
||||
name: "bug changed status",
|
||||
bug: bugStatusChanged,
|
||||
numOrOp: 3,
|
||||
},
|
||||
&testCase{
|
||||
name: "bug title edited",
|
||||
bug: bugTitleEdited,
|
||||
numOrOp: 2,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestPushPull(t *testing.T) {
|
||||
// repo owner
|
||||
user := os.Getenv("GITHUB_TEST_USER")
|
||||
|
||||
// token must have 'repo' and 'delete_repo' scopes
|
||||
token := os.Getenv("GITHUB_TOKEN_ADMIN")
|
||||
if token == "" {
|
||||
t.Skip("Env var GITHUB_TOKEN_ADMIN missing")
|
||||
}
|
||||
|
||||
// create repo backend
|
||||
repo := repository.CreateTestRepo(false)
|
||||
defer repository.CleanupTestRepos(t, repo)
|
||||
|
||||
backend, err := cache.NewRepoCache(repo)
|
||||
require.NoError(t, err)
|
||||
|
||||
// set author identity
|
||||
author, err := backend.NewIdentity("test identity", "test@test.org")
|
||||
require.NoError(t, err)
|
||||
|
||||
err = backend.SetUserIdentity(author)
|
||||
require.NoError(t, err)
|
||||
|
||||
defer backend.Close()
|
||||
interrupt.RegisterCleaner(backend.Close)
|
||||
|
||||
tests := testCases(t, backend, author)
|
||||
|
||||
// generate project name
|
||||
projectName := generateRepoName()
|
||||
|
||||
// create target Github repository
|
||||
err = createRepository(projectName, token)
|
||||
require.NoError(t, err)
|
||||
|
||||
fmt.Println("created repository", projectName)
|
||||
|
||||
// Make sure to remove the Github repository when the test end
|
||||
defer func(t *testing.T) {
|
||||
if err := deleteRepository(projectName, user, token); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
fmt.Println("deleted repository:", projectName)
|
||||
}(t)
|
||||
|
||||
interrupt.RegisterCleaner(func() error {
|
||||
return deleteRepository(projectName, user, token)
|
||||
})
|
||||
|
||||
// initialize exporter
|
||||
exporter := &githubExporter{}
|
||||
err = exporter.Init(core.Configuration{
|
||||
keyOwner: user,
|
||||
keyProject: projectName,
|
||||
keyToken: token,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
start := time.Now()
|
||||
|
||||
// export all bugs
|
||||
events, err := exporter.ExportAll(backend, time.Time{})
|
||||
require.NoError(t, err)
|
||||
|
||||
for result := range events {
|
||||
require.NoError(t, result.Err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
fmt.Printf("test repository exported in %f seconds\n", time.Since(start).Seconds())
|
||||
|
||||
repoTwo := repository.CreateTestRepo(false)
|
||||
defer repository.CleanupTestRepos(t, repoTwo)
|
||||
|
||||
// create a second backend
|
||||
backendTwo, err := cache.NewRepoCache(repoTwo)
|
||||
require.NoError(t, err)
|
||||
|
||||
importer := &githubImporter{}
|
||||
err = importer.Init(core.Configuration{
|
||||
keyOwner: user,
|
||||
keyProject: projectName,
|
||||
keyToken: token,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
// import all exported bugs to the second backend
|
||||
err = importer.ImportAll(backendTwo, time.Time{})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Len(t, backendTwo.AllBugsIds(), len(tests))
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// for each operation a SetMetadataOperation will be added
|
||||
// so number of operations should double
|
||||
require.Len(t, tt.bug.Snapshot().Operations, tt.numOrOp*2)
|
||||
|
||||
// verify operation have correct metadata
|
||||
for _, op := range tt.bug.Snapshot().Operations {
|
||||
// Check if the originals operations (*not* SetMetadata) are tagged properly
|
||||
if _, ok := op.(*bug.SetMetadataOperation); !ok {
|
||||
_, haveIDMetadata := op.GetMetadata(keyGithubId)
|
||||
require.True(t, haveIDMetadata)
|
||||
|
||||
_, haveURLMetada := op.GetMetadata(keyGithubUrl)
|
||||
require.True(t, haveURLMetada)
|
||||
}
|
||||
}
|
||||
|
||||
// get bug github ID
|
||||
bugGithubID, ok := tt.bug.Snapshot().GetCreateMetadata(keyGithubId)
|
||||
require.True(t, ok)
|
||||
|
||||
// retrieve bug from backendTwo
|
||||
importedBug, err := backendTwo.ResolveBugCreateMetadata(keyGithubId, bugGithubID)
|
||||
require.NoError(t, err)
|
||||
|
||||
// verify bug have same number of original operations
|
||||
require.Len(t, importedBug.Snapshot().Operations, tt.numOrOp)
|
||||
|
||||
// verify bugs are taged with origin=github
|
||||
issueOrigin, ok := importedBug.Snapshot().GetCreateMetadata(keyOrigin)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, issueOrigin, target)
|
||||
|
||||
//TODO: maybe more tests to ensure bug final state
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func generateRepoName() string {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||||
b := make([]rune, 8)
|
||||
for i := range b {
|
||||
b[i] = letterRunes[rand.Intn(len(letterRunes))]
|
||||
}
|
||||
return fmt.Sprintf("%s-%s", testRepoBaseName, string(b))
|
||||
}
|
||||
|
||||
// create repository need a token with scope 'repo'
|
||||
func createRepository(project, token string) error {
|
||||
// This function use the V3 Github API because repository creation is not supported yet on the V4 API.
|
||||
url := fmt.Sprintf("%s/user/repos", githubV3Url)
|
||||
|
||||
params := struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Private bool `json:"private"`
|
||||
HasIssues bool `json:"has_issues"`
|
||||
}{
|
||||
Name: project,
|
||||
Description: "git-bug exporter temporary test repository",
|
||||
Private: true,
|
||||
HasIssues: true,
|
||||
}
|
||||
|
||||
data, err := json.Marshal(params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", url, bytes.NewBuffer(data))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// need the token for private repositories
|
||||
req.Header.Set("Authorization", fmt.Sprintf("token %s", token))
|
||||
|
||||
client := &http.Client{
|
||||
Timeout: defaultTimeout,
|
||||
}
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return resp.Body.Close()
|
||||
}
|
||||
|
||||
// delete repository need a token with scope 'delete_repo'
|
||||
func deleteRepository(project, owner, token string) error {
|
||||
// This function use the V3 Github API because repository removal is not supported yet on the V4 API.
|
||||
url := fmt.Sprintf("%s/repos/%s/%s", githubV3Url, owner, project)
|
||||
|
||||
req, err := http.NewRequest("DELETE", url, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// need the token for private repositories
|
||||
req.Header.Set("Authorization", fmt.Sprintf("token %s", token))
|
||||
|
||||
client := &http.Client{
|
||||
Timeout: defaultTimeout,
|
||||
}
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusNoContent {
|
||||
return fmt.Errorf("error deleting repository")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -17,7 +17,7 @@ func init() {
|
||||
type Github struct{}
|
||||
|
||||
func (*Github) Target() string {
|
||||
return "github"
|
||||
return target
|
||||
}
|
||||
|
||||
func (*Github) NewImporter() core.Importer {
|
||||
@ -25,7 +25,7 @@ func (*Github) NewImporter() core.Importer {
|
||||
}
|
||||
|
||||
func (*Github) NewExporter() core.Exporter {
|
||||
return nil
|
||||
return &githubExporter{}
|
||||
}
|
||||
|
||||
func buildClient(token string) *githubv4.Client {
|
||||
|
@ -16,6 +16,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
keyOrigin = "origin"
|
||||
keyGithubId = "github-id"
|
||||
keyGithubUrl = "github-url"
|
||||
keyGithubLogin = "github-login"
|
||||
@ -113,6 +114,7 @@ func (gi *githubImporter) ensureIssue(repo *cache.RepoCache, issue issueTimeline
|
||||
cleanText,
|
||||
nil,
|
||||
map[string]string{
|
||||
keyOrigin: target,
|
||||
keyGithubId: parseId(issue.Id),
|
||||
keyGithubUrl: issue.Url.String(),
|
||||
})
|
||||
@ -147,6 +149,7 @@ func (gi *githubImporter) ensureIssue(repo *cache.RepoCache, issue issueTimeline
|
||||
cleanText,
|
||||
nil,
|
||||
map[string]string{
|
||||
keyOrigin: target,
|
||||
keyGithubId: parseId(issue.Id),
|
||||
keyGithubUrl: issue.Url.String(),
|
||||
},
|
||||
@ -502,7 +505,7 @@ func (gi *githubImporter) getGhost(repo *cache.RepoCache) (*cache.IdentityCache,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var q userQuery
|
||||
var q ghostQuery
|
||||
|
||||
variables := map[string]interface{}{
|
||||
"login": githubv4.String("ghost"),
|
||||
@ -510,7 +513,11 @@ func (gi *githubImporter) getGhost(repo *cache.RepoCache) (*cache.IdentityCache,
|
||||
|
||||
gc := buildClient(gi.conf[keyToken])
|
||||
|
||||
err = gc.Query(context.TODO(), &q, variables)
|
||||
parentCtx := context.Background()
|
||||
ctx, cancel := context.WithTimeout(parentCtx, defaultTimeout)
|
||||
defer cancel()
|
||||
|
||||
err = gc.Query(ctx, &q, variables)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -522,7 +529,7 @@ func (gi *githubImporter) getGhost(repo *cache.RepoCache) (*cache.IdentityCache,
|
||||
|
||||
return repo.NewIdentityRaw(
|
||||
name,
|
||||
string(q.User.Email),
|
||||
"",
|
||||
string(q.User.Login),
|
||||
string(q.User.AvatarUrl),
|
||||
map[string]string{
|
||||
|
@ -160,11 +160,18 @@ type commentEditQuery struct {
|
||||
} `graphql:"repository(owner: $owner, name: $name)"`
|
||||
}
|
||||
|
||||
type userQuery struct {
|
||||
type ghostQuery struct {
|
||||
User struct {
|
||||
Login githubv4.String
|
||||
AvatarUrl githubv4.String
|
||||
Name *githubv4.String
|
||||
Email githubv4.String
|
||||
} `graphql:"user(login: $login)"`
|
||||
}
|
||||
|
||||
type labelQuery struct {
|
||||
Repository struct {
|
||||
Label struct {
|
||||
ID string `graphql:"id"`
|
||||
} `graphql:"label(name: $label)"`
|
||||
} `graphql:"repository(owner: $owner, name: $name)"`
|
||||
}
|
||||
|
@ -190,7 +190,7 @@ func Test_Importer(t *testing.T) {
|
||||
assert.Equal(t, op.(*bug.EditCommentOperation).Author.Name(), ops[i].(*bug.EditCommentOperation).Author.Name())
|
||||
|
||||
default:
|
||||
panic("Unknown operation type")
|
||||
panic("unknown operation type")
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -59,7 +59,7 @@ type iterator struct {
|
||||
commentEdit commentEditIterator
|
||||
}
|
||||
|
||||
// NewIterator create and initalize a new iterator
|
||||
// NewIterator create and initialize a new iterator
|
||||
func NewIterator(owner, project, token string, since time.Time) *iterator {
|
||||
i := &iterator{
|
||||
gc: buildClient(token),
|
||||
@ -147,7 +147,11 @@ func (i *iterator) Error() error {
|
||||
}
|
||||
|
||||
func (i *iterator) queryIssue() bool {
|
||||
if err := i.gc.Query(context.TODO(), &i.timeline.query, i.timeline.variables); err != nil {
|
||||
parentCtx := context.Background()
|
||||
ctx, cancel := context.WithTimeout(parentCtx, defaultTimeout)
|
||||
defer cancel()
|
||||
|
||||
if err := i.gc.Query(ctx, &i.timeline.query, i.timeline.variables); err != nil {
|
||||
i.err = err
|
||||
return false
|
||||
}
|
||||
@ -220,7 +224,12 @@ func (i *iterator) NextTimelineItem() bool {
|
||||
|
||||
// more timelines, query them
|
||||
i.timeline.variables["timelineAfter"] = i.timeline.query.Repository.Issues.Nodes[0].Timeline.PageInfo.EndCursor
|
||||
if err := i.gc.Query(context.TODO(), &i.timeline.query, i.timeline.variables); err != nil {
|
||||
|
||||
parentCtx := context.Background()
|
||||
ctx, cancel := context.WithTimeout(parentCtx, defaultTimeout)
|
||||
defer cancel()
|
||||
|
||||
if err := i.gc.Query(ctx, &i.timeline.query, i.timeline.variables); err != nil {
|
||||
i.err = err
|
||||
return false
|
||||
}
|
||||
@ -236,7 +245,11 @@ func (i *iterator) TimelineItemValue() timelineItem {
|
||||
}
|
||||
|
||||
func (i *iterator) queryIssueEdit() bool {
|
||||
if err := i.gc.Query(context.TODO(), &i.issueEdit.query, i.issueEdit.variables); err != nil {
|
||||
parentCtx := context.Background()
|
||||
ctx, cancel := context.WithTimeout(parentCtx, defaultTimeout)
|
||||
defer cancel()
|
||||
|
||||
if err := i.gc.Query(ctx, &i.issueEdit.query, i.issueEdit.variables); err != nil {
|
||||
i.err = err
|
||||
//i.timeline.issueEdit.index = -1
|
||||
return false
|
||||
@ -334,7 +347,11 @@ func (i *iterator) IssueEditValue() userContentEdit {
|
||||
}
|
||||
|
||||
func (i *iterator) queryCommentEdit() bool {
|
||||
if err := i.gc.Query(context.TODO(), &i.commentEdit.query, i.commentEdit.variables); err != nil {
|
||||
parentCtx := context.Background()
|
||||
ctx, cancel := context.WithTimeout(parentCtx, defaultTimeout)
|
||||
defer cancel()
|
||||
|
||||
if err := i.gc.Query(ctx, &i.commentEdit.query, i.commentEdit.variables); err != nil {
|
||||
i.err = err
|
||||
return false
|
||||
}
|
||||
|
@ -49,6 +49,8 @@ type Operation interface {
|
||||
GetMetadata(key string) (string, bool)
|
||||
// AllMetadata return all metadata for this operation
|
||||
AllMetadata() map[string]string
|
||||
// GetAuthor return the author identity
|
||||
GetAuthor() identity.Interface
|
||||
}
|
||||
|
||||
func hashRaw(data []byte) git.Hash {
|
||||
@ -222,3 +224,8 @@ func (op *OpBase) AllMetadata() map[string]string {
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// GetAuthor return author identity
|
||||
func (op *OpBase) GetAuthor() identity.Interface {
|
||||
return op.Author
|
||||
}
|
||||
|
@ -54,6 +54,11 @@ func (snap *Snapshot) LastEditUnix() int64 {
|
||||
return snap.Operations[len(snap.Operations)-1].GetUnixTime()
|
||||
}
|
||||
|
||||
// GetCreateMetadata return the creation metadata
|
||||
func (snap *Snapshot) GetCreateMetadata(key string) (string, bool) {
|
||||
return snap.Operations[0].GetMetadata(key)
|
||||
}
|
||||
|
||||
// SearchTimelineItem will search in the timeline for an item matching the given hash
|
||||
func (snap *Snapshot) SearchTimelineItem(hash git.Hash) (TimelineItem, error) {
|
||||
for i := range snap.Timeline {
|
||||
@ -87,5 +92,45 @@ func (snap *Snapshot) addParticipant(participant identity.Interface) {
|
||||
snap.Participants = append(snap.Participants, participant)
|
||||
}
|
||||
|
||||
// HasParticipant return true if the id is a participant
|
||||
func (snap *Snapshot) HasParticipant(id string) bool {
|
||||
for _, p := range snap.Participants {
|
||||
if p.Id() == id {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// HasAnyParticipant return true if one of the ids is a participant
|
||||
func (snap *Snapshot) HasAnyParticipant(ids ...string) bool {
|
||||
for _, id := range ids {
|
||||
if snap.HasParticipant(id) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// HasActor return true if the id is a actor
|
||||
func (snap *Snapshot) HasActor(id string) bool {
|
||||
for _, p := range snap.Actors {
|
||||
if p.Id() == id {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// HasAnyActor return true if one of the ids is a actor
|
||||
func (snap *Snapshot) HasAnyActor(ids ...string) bool {
|
||||
for _, id := range ids {
|
||||
if snap.HasActor(id) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Sign post method for gqlgen
|
||||
func (snap *Snapshot) IsAuthored() {}
|
||||
|
18
cache/bug_cache.go
vendored
18
cache/bug_cache.go
vendored
@ -254,6 +254,24 @@ func (c *BugCache) EditCommentRaw(author *IdentityCache, unixTime int64, target
|
||||
return op, c.notifyUpdated()
|
||||
}
|
||||
|
||||
func (c *BugCache) SetMetadata(target git.Hash, newMetadata map[string]string) (*bug.SetMetadataOperation, error) {
|
||||
author, err := c.repoCache.GetUserIdentity()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return c.SetMetadataRaw(author, time.Now().Unix(), target, newMetadata)
|
||||
}
|
||||
|
||||
func (c *BugCache) SetMetadataRaw(author *IdentityCache, unixTime int64, target git.Hash, newMetadata map[string]string) (*bug.SetMetadataOperation, error) {
|
||||
op, err := bug.SetMetadata(c.bug, author.Identity, unixTime, target, newMetadata)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return op, c.notifyUpdated()
|
||||
}
|
||||
|
||||
func (c *BugCache) Commit() error {
|
||||
err := c.bug.Commit(c.repoCache.repo)
|
||||
if err != nil {
|
||||
|
@ -3,11 +3,12 @@ package commands
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/MichaelMure/git-bug/bridge"
|
||||
"github.com/MichaelMure/git-bug/bridge/core"
|
||||
"github.com/MichaelMure/git-bug/cache"
|
||||
"github.com/MichaelMure/git-bug/util/interrupt"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func runBridgePull(cmd *cobra.Command, args []string) error {
|
||||
@ -44,6 +45,7 @@ var bridgePullCmd = &cobra.Command{
|
||||
Short: "Pull updates.",
|
||||
PreRunE: loadRepo,
|
||||
RunE: runBridgePull,
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
62
commands/bridge_push.go
Normal file
62
commands/bridge_push.go
Normal file
@ -0,0 +1,62 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/MichaelMure/git-bug/bridge"
|
||||
"github.com/MichaelMure/git-bug/bridge/core"
|
||||
"github.com/MichaelMure/git-bug/cache"
|
||||
"github.com/MichaelMure/git-bug/util/interrupt"
|
||||
)
|
||||
|
||||
func runBridgePush(cmd *cobra.Command, args []string) error {
|
||||
backend, err := cache.NewRepoCache(repo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer backend.Close()
|
||||
interrupt.RegisterCleaner(backend.Close)
|
||||
|
||||
var b *core.Bridge
|
||||
|
||||
if len(args) == 0 {
|
||||
b, err = bridge.DefaultBridge(backend)
|
||||
} else {
|
||||
b, err = bridge.LoadBridge(backend, args[0])
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO: by default export only new events
|
||||
out, err := b.ExportAll(time.Time{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for result := range out {
|
||||
if result.Err != nil {
|
||||
fmt.Println(result.Err, result.Reason)
|
||||
} else {
|
||||
fmt.Printf("%s: %s\n", result.String(), result.ID)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var bridgePushCmd = &cobra.Command{
|
||||
Use: "push [<name>]",
|
||||
Short: "Push updates.",
|
||||
PreRunE: loadRepo,
|
||||
RunE: runBridgePush,
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
}
|
||||
|
||||
func init() {
|
||||
bridgeCmd.AddCommand(bridgePushCmd)
|
||||
}
|
29
doc/man/git-bug-bridge-push.1
Normal file
29
doc/man/git-bug-bridge-push.1
Normal file
@ -0,0 +1,29 @@
|
||||
.TH "GIT-BUG" "1" "Apr 2019" "Generated from git-bug's source code" ""
|
||||
.nh
|
||||
.ad l
|
||||
|
||||
|
||||
.SH NAME
|
||||
.PP
|
||||
git\-bug\-bridge\-push \- Push updates.
|
||||
|
||||
|
||||
.SH SYNOPSIS
|
||||
.PP
|
||||
\fBgit\-bug bridge push [<name>] [flags]\fP
|
||||
|
||||
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
Push updates.
|
||||
|
||||
|
||||
.SH OPTIONS
|
||||
.PP
|
||||
\fB\-h\fP, \fB\-\-help\fP[=false]
|
||||
help for push
|
||||
|
||||
|
||||
.SH SEE ALSO
|
||||
.PP
|
||||
\fBgit\-bug\-bridge(1)\fP
|
@ -26,4 +26,4 @@ Configure and use bridges to other bug trackers.
|
||||
|
||||
.SH SEE ALSO
|
||||
.PP
|
||||
\fBgit\-bug(1)\fP, \fBgit\-bug\-bridge\-configure(1)\fP, \fBgit\-bug\-bridge\-pull(1)\fP, \fBgit\-bug\-bridge\-rm(1)\fP
|
||||
\fBgit\-bug(1)\fP, \fBgit\-bug\-bridge\-configure(1)\fP, \fBgit\-bug\-bridge\-pull(1)\fP, \fBgit\-bug\-bridge\-push(1)\fP, \fBgit\-bug\-bridge\-rm(1)\fP
|
||||
|
@ -21,5 +21,6 @@ git-bug bridge [flags]
|
||||
* [git-bug](git-bug.md) - A bug tracker embedded in Git.
|
||||
* [git-bug bridge configure](git-bug_bridge_configure.md) - Configure a new bridge.
|
||||
* [git-bug bridge pull](git-bug_bridge_pull.md) - Pull updates.
|
||||
* [git-bug bridge push](git-bug_bridge_push.md) - Push updates.
|
||||
* [git-bug bridge rm](git-bug_bridge_rm.md) - Delete a configured bridge.
|
||||
|
||||
|
22
doc/md/git-bug_bridge_push.md
Normal file
22
doc/md/git-bug_bridge_push.md
Normal file
@ -0,0 +1,22 @@
|
||||
## git-bug bridge push
|
||||
|
||||
Push updates.
|
||||
|
||||
### Synopsis
|
||||
|
||||
Push updates.
|
||||
|
||||
```
|
||||
git-bug bridge push [<name>] [flags]
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for push
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [git-bug bridge](git-bug_bridge.md) - Configure and use bridges to other bug trackers.
|
||||
|
@ -351,6 +351,26 @@ _git-bug_bridge_pull()
|
||||
noun_aliases=()
|
||||
}
|
||||
|
||||
_git-bug_bridge_push()
|
||||
{
|
||||
last_command="git-bug_bridge_push"
|
||||
|
||||
command_aliases=()
|
||||
|
||||
commands=()
|
||||
|
||||
flags=()
|
||||
two_word_flags=()
|
||||
local_nonpersistent_flags=()
|
||||
flags_with_completion=()
|
||||
flags_completion=()
|
||||
|
||||
|
||||
must_have_one_flag=()
|
||||
must_have_one_noun=()
|
||||
noun_aliases=()
|
||||
}
|
||||
|
||||
_git-bug_bridge_rm()
|
||||
{
|
||||
last_command="git-bug_bridge_rm"
|
||||
@ -380,6 +400,7 @@ _git-bug_bridge()
|
||||
commands=()
|
||||
commands+=("configure")
|
||||
commands+=("pull")
|
||||
commands+=("push")
|
||||
commands+=("rm")
|
||||
|
||||
flags=()
|
||||
|
@ -50,6 +50,7 @@ Register-ArgumentCompleter -Native -CommandName 'git-bug' -ScriptBlock {
|
||||
'git-bug;bridge' {
|
||||
[CompletionResult]::new('configure', 'configure', [CompletionResultType]::ParameterValue, 'Configure a new bridge.')
|
||||
[CompletionResult]::new('pull', 'pull', [CompletionResultType]::ParameterValue, 'Pull updates.')
|
||||
[CompletionResult]::new('push', 'push', [CompletionResultType]::ParameterValue, 'Push updates.')
|
||||
[CompletionResult]::new('rm', 'rm', [CompletionResultType]::ParameterValue, 'Delete a configured bridge.')
|
||||
break
|
||||
}
|
||||
@ -71,6 +72,9 @@ Register-ArgumentCompleter -Native -CommandName 'git-bug' -ScriptBlock {
|
||||
'git-bug;bridge;pull' {
|
||||
break
|
||||
}
|
||||
'git-bug;bridge;push' {
|
||||
break
|
||||
}
|
||||
'git-bug;bridge;rm' {
|
||||
break
|
||||
}
|
||||
|
@ -116,6 +116,7 @@ function _git-bug_bridge {
|
||||
commands=(
|
||||
"configure:Configure a new bridge."
|
||||
"pull:Pull updates."
|
||||
"push:Push updates."
|
||||
"rm:Delete a configured bridge."
|
||||
)
|
||||
_describe "command" commands
|
||||
@ -129,6 +130,9 @@ function _git-bug_bridge {
|
||||
pull)
|
||||
_git-bug_bridge_pull
|
||||
;;
|
||||
push)
|
||||
_git-bug_bridge_push
|
||||
;;
|
||||
rm)
|
||||
_git-bug_bridge_rm
|
||||
;;
|
||||
@ -149,6 +153,10 @@ function _git-bug_bridge_pull {
|
||||
_arguments
|
||||
}
|
||||
|
||||
function _git-bug_bridge_push {
|
||||
_arguments
|
||||
}
|
||||
|
||||
function _git-bug_bridge_rm {
|
||||
_arguments
|
||||
}
|
||||
|
2
vendor/github.com/shurcooL/githubv4/.travis.yml
generated
vendored
2
vendor/github.com/shurcooL/githubv4/.travis.yml
generated
vendored
@ -12,5 +12,5 @@ install:
|
||||
script:
|
||||
- go get -t -v ./...
|
||||
- diff -u <(echo -n) <(gofmt -d -s .)
|
||||
- go tool vet .
|
||||
- go vet ./...
|
||||
- go test -v -race ./...
|
||||
|
8
vendor/github.com/shurcooL/githubv4/README.md
generated
vendored
8
vendor/github.com/shurcooL/githubv4/README.md
generated
vendored
@ -48,7 +48,7 @@ func main() {
|
||||
|
||||
### Simple Query
|
||||
|
||||
To make a query, you need to define a Go type that corresponds to the GitHub GraphQL schema, and contains the fields you're interested in querying. You can look up the GitHub GraphQL schema at https://developer.github.com/v4/reference/query/.
|
||||
To make a query, you need to define a Go type that corresponds to the GitHub GraphQL schema, and contains the fields you're interested in querying. You can look up the GitHub GraphQL schema at https://developer.github.com/v4/query/.
|
||||
|
||||
For example, to make the following GraphQL query:
|
||||
|
||||
@ -89,7 +89,7 @@ fmt.Println("CreatedAt:", query.Viewer.CreatedAt)
|
||||
|
||||
### Scalar Types
|
||||
|
||||
For each scalar in the GitHub GraphQL schema listed at https://developer.github.com/v4/reference/scalar/, there is a corresponding Go type in package `githubv4`.
|
||||
For each scalar in the GitHub GraphQL schema listed at https://developer.github.com/v4/scalar/, there is a corresponding Go type in package `githubv4`.
|
||||
|
||||
You can use these types when writing queries:
|
||||
|
||||
@ -127,7 +127,7 @@ var query struct {
|
||||
// Call client.Query() and use results in query...
|
||||
```
|
||||
|
||||
The [`DateTime`](https://developer.github.com/v4/reference/scalar/datetime/) scalar is described as "an ISO-8601 encoded UTC date string". If you wanted to fetch in that form without parsing it into a `time.Time`, you can use the `string` type. For example, this would work:
|
||||
The [`DateTime`](https://developer.github.com/v4/scalar/datetime/) scalar is described as "an ISO-8601 encoded UTC date string". If you wanted to fetch in that form without parsing it into a `time.Time`, you can use the `string` type. For example, this would work:
|
||||
|
||||
```Go
|
||||
// import "html/template"
|
||||
@ -336,7 +336,7 @@ for {
|
||||
}
|
||||
```
|
||||
|
||||
There is more than one way to perform pagination. Consider additional fields inside [`PageInfo`](https://developer.github.com/v4/reference/object/pageinfo/) object.
|
||||
There is more than one way to perform pagination. Consider additional fields inside [`PageInfo`](https://developer.github.com/v4/object/pageinfo/) object.
|
||||
|
||||
### Mutations
|
||||
|
||||
|
298
vendor/github.com/shurcooL/githubv4/enum.go
generated
vendored
298
vendor/github.com/shurcooL/githubv4/enum.go
generated
vendored
@ -36,6 +36,24 @@ const (
|
||||
CommentCannotUpdateReasonLoginRequired CommentCannotUpdateReason = "LOGIN_REQUIRED" // You must be logged in to update this comment.
|
||||
CommentCannotUpdateReasonMaintenance CommentCannotUpdateReason = "MAINTENANCE" // Repository is under maintenance.
|
||||
CommentCannotUpdateReasonVerifiedEmailRequired CommentCannotUpdateReason = "VERIFIED_EMAIL_REQUIRED" // At least one email address must be verified to update this comment.
|
||||
CommentCannotUpdateReasonDenied CommentCannotUpdateReason = "DENIED" // You cannot update this comment.
|
||||
)
|
||||
|
||||
// CommitContributionOrderField represents properties by which commit contribution connections can be ordered.
|
||||
type CommitContributionOrderField string
|
||||
|
||||
// Properties by which commit contribution connections can be ordered.
|
||||
const (
|
||||
CommitContributionOrderFieldOccurredAt CommitContributionOrderField = "OCCURRED_AT" // Order commit contributions by when they were made.
|
||||
CommitContributionOrderFieldCommitCount CommitContributionOrderField = "COMMIT_COUNT" // Order commit contributions by how many commits they represent.
|
||||
)
|
||||
|
||||
// ContributionOrderField represents properties by which contribution connections can be ordered.
|
||||
type ContributionOrderField string
|
||||
|
||||
// Properties by which contribution connections can be ordered.
|
||||
const (
|
||||
ContributionOrderFieldOccurredAt ContributionOrderField = "OCCURRED_AT" // Order contributions by when they were made.
|
||||
)
|
||||
|
||||
// DefaultRepositoryPermissionField represents the possible default permissions for repositories.
|
||||
@ -49,18 +67,28 @@ const (
|
||||
DefaultRepositoryPermissionFieldAdmin DefaultRepositoryPermissionField = "ADMIN" // Can read, write, and administrate repos by default.
|
||||
)
|
||||
|
||||
// DeploymentOrderField represents properties by which deployment connections can be ordered.
|
||||
type DeploymentOrderField string
|
||||
|
||||
// Properties by which deployment connections can be ordered.
|
||||
const (
|
||||
DeploymentOrderFieldCreatedAt DeploymentOrderField = "CREATED_AT" // Order collection by creation time.
|
||||
)
|
||||
|
||||
// DeploymentState represents the possible states in which a deployment can be.
|
||||
type DeploymentState string
|
||||
|
||||
// The possible states in which a deployment can be.
|
||||
const (
|
||||
DeploymentStateAbandoned DeploymentState = "ABANDONED" // The pending deployment was not updated after 30 minutes.
|
||||
DeploymentStateActive DeploymentState = "ACTIVE" // The deployment is currently active.
|
||||
DeploymentStateDestroyed DeploymentState = "DESTROYED" // An inactive transient deployment.
|
||||
DeploymentStateError DeploymentState = "ERROR" // The deployment experienced an error.
|
||||
DeploymentStateFailure DeploymentState = "FAILURE" // The deployment has failed.
|
||||
DeploymentStateInactive DeploymentState = "INACTIVE" // The deployment is inactive.
|
||||
DeploymentStatePending DeploymentState = "PENDING" // The deployment is pending.
|
||||
DeploymentStateAbandoned DeploymentState = "ABANDONED" // The pending deployment was not updated after 30 minutes.
|
||||
DeploymentStateActive DeploymentState = "ACTIVE" // The deployment is currently active.
|
||||
DeploymentStateDestroyed DeploymentState = "DESTROYED" // An inactive transient deployment.
|
||||
DeploymentStateError DeploymentState = "ERROR" // The deployment experienced an error.
|
||||
DeploymentStateFailure DeploymentState = "FAILURE" // The deployment has failed.
|
||||
DeploymentStateInactive DeploymentState = "INACTIVE" // The deployment is inactive.
|
||||
DeploymentStatePending DeploymentState = "PENDING" // The deployment is pending.
|
||||
DeploymentStateQueued DeploymentState = "QUEUED" // The deployment has queued.
|
||||
DeploymentStateInProgress DeploymentState = "IN_PROGRESS" // The deployment is in progress.
|
||||
)
|
||||
|
||||
// DeploymentStatusState represents the possible states for a deployment status.
|
||||
@ -68,11 +96,13 @@ type DeploymentStatusState string
|
||||
|
||||
// The possible states for a deployment status.
|
||||
const (
|
||||
DeploymentStatusStatePending DeploymentStatusState = "PENDING" // The deployment is pending.
|
||||
DeploymentStatusStateSuccess DeploymentStatusState = "SUCCESS" // The deployment was successful.
|
||||
DeploymentStatusStateFailure DeploymentStatusState = "FAILURE" // The deployment has failed.
|
||||
DeploymentStatusStateInactive DeploymentStatusState = "INACTIVE" // The deployment is inactive.
|
||||
DeploymentStatusStateError DeploymentStatusState = "ERROR" // The deployment experienced an error.
|
||||
DeploymentStatusStatePending DeploymentStatusState = "PENDING" // The deployment is pending.
|
||||
DeploymentStatusStateSuccess DeploymentStatusState = "SUCCESS" // The deployment was successful.
|
||||
DeploymentStatusStateFailure DeploymentStatusState = "FAILURE" // The deployment has failed.
|
||||
DeploymentStatusStateInactive DeploymentStatusState = "INACTIVE" // The deployment is inactive.
|
||||
DeploymentStatusStateError DeploymentStatusState = "ERROR" // The deployment experienced an error.
|
||||
DeploymentStatusStateQueued DeploymentStatusState = "QUEUED" // The deployment is queued.
|
||||
DeploymentStatusStateInProgress DeploymentStatusState = "IN_PROGRESS" // The deployment is in progress.
|
||||
)
|
||||
|
||||
// GistOrderField represents properties by which gist connections can be ordered.
|
||||
@ -115,9 +145,20 @@ const (
|
||||
GitSignatureStateExpiredKey GitSignatureState = "EXPIRED_KEY" // Signing key expired.
|
||||
GitSignatureStateOcspPending GitSignatureState = "OCSP_PENDING" // Valid signature, pending certificate revocation checking.
|
||||
GitSignatureStateOcspError GitSignatureState = "OCSP_ERROR" // Valid siganture, though certificate revocation check failed.
|
||||
GitSignatureStateBadCert GitSignatureState = "BAD_CERT" // The signing certificate or its chain could not be verified.
|
||||
GitSignatureStateOcspRevoked GitSignatureState = "OCSP_REVOKED" // One or more certificates in chain has been revoked.
|
||||
)
|
||||
|
||||
// IdentityProviderConfigurationState represents the possible states in which authentication can be configured with an identity provider.
|
||||
type IdentityProviderConfigurationState string
|
||||
|
||||
// The possible states in which authentication can be configured with an identity provider.
|
||||
const (
|
||||
IdentityProviderConfigurationStateEnforced IdentityProviderConfigurationState = "ENFORCED" // Authentication with an identity provider is configured and enforced.
|
||||
IdentityProviderConfigurationStateConfigured IdentityProviderConfigurationState = "CONFIGURED" // Authentication with an identity provider is configured but not enforced.
|
||||
IdentityProviderConfigurationStateUnconfigured IdentityProviderConfigurationState = "UNCONFIGURED" // Authentication with an identity provider is not configured.
|
||||
)
|
||||
|
||||
// IssueOrderField represents properties by which issue connections can be ordered.
|
||||
type IssueOrderField string
|
||||
|
||||
@ -136,6 +177,7 @@ const (
|
||||
IssuePubSubTopicUpdated IssuePubSubTopic = "UPDATED" // The channel ID for observing issue updates.
|
||||
IssuePubSubTopicMarkasread IssuePubSubTopic = "MARKASREAD" // The channel ID for marking an issue as read.
|
||||
IssuePubSubTopicTimeline IssuePubSubTopic = "TIMELINE" // The channel ID for updating items on the issue timeline.
|
||||
IssuePubSubTopicState IssuePubSubTopic = "STATE" // The channel ID for observing issue state updates.
|
||||
)
|
||||
|
||||
// IssueState represents the possible states of an issue.
|
||||
@ -147,6 +189,39 @@ const (
|
||||
IssueStateClosed IssueState = "CLOSED" // An issue that has been closed.
|
||||
)
|
||||
|
||||
// IssueTimelineItemsItemType represents the possible item types found in a timeline.
|
||||
type IssueTimelineItemsItemType string
|
||||
|
||||
// The possible item types found in a timeline.
|
||||
const (
|
||||
IssueTimelineItemsItemTypeIssueComment IssueTimelineItemsItemType = "ISSUE_COMMENT" // Represents a comment on an Issue.
|
||||
IssueTimelineItemsItemTypeCrossReferencedEvent IssueTimelineItemsItemType = "CROSS_REFERENCED_EVENT" // Represents a mention made by one issue or pull request to another.
|
||||
IssueTimelineItemsItemTypeAddedToProjectEvent IssueTimelineItemsItemType = "ADDED_TO_PROJECT_EVENT" // Represents a 'added_to_project' event on a given issue or pull request.
|
||||
IssueTimelineItemsItemTypeAssignedEvent IssueTimelineItemsItemType = "ASSIGNED_EVENT" // Represents an 'assigned' event on any assignable object.
|
||||
IssueTimelineItemsItemTypeClosedEvent IssueTimelineItemsItemType = "CLOSED_EVENT" // Represents a 'closed' event on any `Closable`.
|
||||
IssueTimelineItemsItemTypeCommentDeletedEvent IssueTimelineItemsItemType = "COMMENT_DELETED_EVENT" // Represents a 'comment_deleted' event on a given issue or pull request.
|
||||
IssueTimelineItemsItemTypeConvertedNoteToIssueEvent IssueTimelineItemsItemType = "CONVERTED_NOTE_TO_ISSUE_EVENT" // Represents a 'converted_note_to_issue' event on a given issue or pull request.
|
||||
IssueTimelineItemsItemTypeDemilestonedEvent IssueTimelineItemsItemType = "DEMILESTONED_EVENT" // Represents a 'demilestoned' event on a given issue or pull request.
|
||||
IssueTimelineItemsItemTypeLabeledEvent IssueTimelineItemsItemType = "LABELED_EVENT" // Represents a 'labeled' event on a given issue or pull request.
|
||||
IssueTimelineItemsItemTypeLockedEvent IssueTimelineItemsItemType = "LOCKED_EVENT" // Represents a 'locked' event on a given issue or pull request.
|
||||
IssueTimelineItemsItemTypeMentionedEvent IssueTimelineItemsItemType = "MENTIONED_EVENT" // Represents a 'mentioned' event on a given issue or pull request.
|
||||
IssueTimelineItemsItemTypeMilestonedEvent IssueTimelineItemsItemType = "MILESTONED_EVENT" // Represents a 'milestoned' event on a given issue or pull request.
|
||||
IssueTimelineItemsItemTypeMovedColumnsInProjectEvent IssueTimelineItemsItemType = "MOVED_COLUMNS_IN_PROJECT_EVENT" // Represents a 'moved_columns_in_project' event on a given issue or pull request.
|
||||
IssueTimelineItemsItemTypePinnedEvent IssueTimelineItemsItemType = "PINNED_EVENT" // Represents a 'pinned' event on a given issue or pull request.
|
||||
IssueTimelineItemsItemTypeReferencedEvent IssueTimelineItemsItemType = "REFERENCED_EVENT" // Represents a 'referenced' event on a given `ReferencedSubject`.
|
||||
IssueTimelineItemsItemTypeRemovedFromProjectEvent IssueTimelineItemsItemType = "REMOVED_FROM_PROJECT_EVENT" // Represents a 'removed_from_project' event on a given issue or pull request.
|
||||
IssueTimelineItemsItemTypeRenamedTitleEvent IssueTimelineItemsItemType = "RENAMED_TITLE_EVENT" // Represents a 'renamed' event on a given issue or pull request.
|
||||
IssueTimelineItemsItemTypeReopenedEvent IssueTimelineItemsItemType = "REOPENED_EVENT" // Represents a 'reopened' event on any `Closable`.
|
||||
IssueTimelineItemsItemTypeSubscribedEvent IssueTimelineItemsItemType = "SUBSCRIBED_EVENT" // Represents a 'subscribed' event on a given `Subscribable`.
|
||||
IssueTimelineItemsItemTypeTransferredEvent IssueTimelineItemsItemType = "TRANSFERRED_EVENT" // Represents a 'transferred' event on a given issue or pull request.
|
||||
IssueTimelineItemsItemTypeUnassignedEvent IssueTimelineItemsItemType = "UNASSIGNED_EVENT" // Represents an 'unassigned' event on any assignable object.
|
||||
IssueTimelineItemsItemTypeUnlabeledEvent IssueTimelineItemsItemType = "UNLABELED_EVENT" // Represents an 'unlabeled' event on a given issue or pull request.
|
||||
IssueTimelineItemsItemTypeUnlockedEvent IssueTimelineItemsItemType = "UNLOCKED_EVENT" // Represents an 'unlocked' event on a given issue or pull request.
|
||||
IssueTimelineItemsItemTypeUserBlockedEvent IssueTimelineItemsItemType = "USER_BLOCKED_EVENT" // Represents a 'user_blocked' event on a given user.
|
||||
IssueTimelineItemsItemTypeUnpinnedEvent IssueTimelineItemsItemType = "UNPINNED_EVENT" // Represents an 'unpinned' event on a given issue or pull request.
|
||||
IssueTimelineItemsItemTypeUnsubscribedEvent IssueTimelineItemsItemType = "UNSUBSCRIBED_EVENT" // Represents an 'unsubscribed' event on a given `Subscribable`.
|
||||
)
|
||||
|
||||
// LanguageOrderField represents properties by which language connections can be ordered.
|
||||
type LanguageOrderField string
|
||||
|
||||
@ -225,6 +300,34 @@ const (
|
||||
OrganizationInvitationTypeEmail OrganizationInvitationType = "EMAIL" // The invitation was to an email address.
|
||||
)
|
||||
|
||||
// OrganizationMemberRole represents the possible roles within an organization for its members.
|
||||
type OrganizationMemberRole string
|
||||
|
||||
// The possible roles within an organization for its members.
|
||||
const (
|
||||
OrganizationMemberRoleMember OrganizationMemberRole = "MEMBER" // The user is a member of the organization.
|
||||
OrganizationMemberRoleAdmin OrganizationMemberRole = "ADMIN" // The user is an administrator of the organization.
|
||||
)
|
||||
|
||||
// PinnableItemType represents represents items that can be pinned to a profile page or dashboard.
|
||||
type PinnableItemType string
|
||||
|
||||
// Represents items that can be pinned to a profile page or dashboard.
|
||||
const (
|
||||
PinnableItemTypeRepository PinnableItemType = "REPOSITORY" // A repository.
|
||||
PinnableItemTypeGist PinnableItemType = "GIST" // A gist.
|
||||
PinnableItemTypeIssue PinnableItemType = "ISSUE" // An issue.
|
||||
)
|
||||
|
||||
// ProjectCardArchivedState represents the possible archived states of a project card.
|
||||
type ProjectCardArchivedState string
|
||||
|
||||
// The possible archived states of a project card.
|
||||
const (
|
||||
ProjectCardArchivedStateArchived ProjectCardArchivedState = "ARCHIVED" // A project card that is archived.
|
||||
ProjectCardArchivedStateNotArchived ProjectCardArchivedState = "NOT_ARCHIVED" // A project card that is not archived.
|
||||
)
|
||||
|
||||
// ProjectCardState represents various content states of a ProjectCard.
|
||||
type ProjectCardState string
|
||||
|
||||
@ -235,6 +338,16 @@ const (
|
||||
ProjectCardStateRedacted ProjectCardState = "REDACTED" // The card is redacted.
|
||||
)
|
||||
|
||||
// ProjectColumnPurpose represents the semantic purpose of the column - todo, in progress, or done.
|
||||
type ProjectColumnPurpose string
|
||||
|
||||
// The semantic purpose of the column - todo, in progress, or done.
|
||||
const (
|
||||
ProjectColumnPurposeTodo ProjectColumnPurpose = "TODO" // The column contains cards still to be worked on.
|
||||
ProjectColumnPurposeInProgress ProjectColumnPurpose = "IN_PROGRESS" // The column contains cards which are currently being worked on.
|
||||
ProjectColumnPurposeDone ProjectColumnPurpose = "DONE" // The column contains cards which are complete.
|
||||
)
|
||||
|
||||
// ProjectOrderField represents properties by which project connections can be ordered.
|
||||
type ProjectOrderField string
|
||||
|
||||
@ -254,6 +367,15 @@ const (
|
||||
ProjectStateClosed ProjectState = "CLOSED" // The project is closed.
|
||||
)
|
||||
|
||||
// PullRequestOrderField represents properties by which pull_requests connections can be ordered.
|
||||
type PullRequestOrderField string
|
||||
|
||||
// Properties by which pull_requests connections can be ordered.
|
||||
const (
|
||||
PullRequestOrderFieldCreatedAt PullRequestOrderField = "CREATED_AT" // Order pull_requests by creation time.
|
||||
PullRequestOrderFieldUpdatedAt PullRequestOrderField = "UPDATED_AT" // Order pull_requests by update time.
|
||||
)
|
||||
|
||||
// PullRequestPubSubTopic represents the possible PubSub channels for a pull request.
|
||||
type PullRequestPubSubTopic string
|
||||
|
||||
@ -263,6 +385,16 @@ const (
|
||||
PullRequestPubSubTopicMarkasread PullRequestPubSubTopic = "MARKASREAD" // The channel ID for marking an pull request as read.
|
||||
PullRequestPubSubTopicHeadRef PullRequestPubSubTopic = "HEAD_REF" // The channel ID for observing head ref updates.
|
||||
PullRequestPubSubTopicTimeline PullRequestPubSubTopic = "TIMELINE" // The channel ID for updating items on the pull request timeline.
|
||||
PullRequestPubSubTopicState PullRequestPubSubTopic = "STATE" // The channel ID for observing pull request state updates.
|
||||
)
|
||||
|
||||
// PullRequestReviewCommentState represents the possible states of a pull request review comment.
|
||||
type PullRequestReviewCommentState string
|
||||
|
||||
// The possible states of a pull request review comment.
|
||||
const (
|
||||
PullRequestReviewCommentStatePending PullRequestReviewCommentState = "PENDING" // A comment that is part of a pending review.
|
||||
PullRequestReviewCommentStateSubmitted PullRequestReviewCommentState = "SUBMITTED" // A comment that is part of a submitted review.
|
||||
)
|
||||
|
||||
// PullRequestReviewEvent represents the possible events to perform on a pull request review.
|
||||
@ -298,6 +430,55 @@ const (
|
||||
PullRequestStateMerged PullRequestState = "MERGED" // A pull request that has been closed by being merged.
|
||||
)
|
||||
|
||||
// PullRequestTimelineItemsItemType represents the possible item types found in a timeline.
|
||||
type PullRequestTimelineItemsItemType string
|
||||
|
||||
// The possible item types found in a timeline.
|
||||
const (
|
||||
PullRequestTimelineItemsItemTypePullRequestCommit PullRequestTimelineItemsItemType = "PULL_REQUEST_COMMIT" // Represents a Git commit part of a pull request.
|
||||
PullRequestTimelineItemsItemTypePullRequestCommitCommentThread PullRequestTimelineItemsItemType = "PULL_REQUEST_COMMIT_COMMENT_THREAD" // Represents a commit comment thread part of a pull request.
|
||||
PullRequestTimelineItemsItemTypePullRequestReview PullRequestTimelineItemsItemType = "PULL_REQUEST_REVIEW" // A review object for a given pull request.
|
||||
PullRequestTimelineItemsItemTypePullRequestReviewThread PullRequestTimelineItemsItemType = "PULL_REQUEST_REVIEW_THREAD" // A threaded list of comments for a given pull request.
|
||||
PullRequestTimelineItemsItemTypePullRequestRevisionMarker PullRequestTimelineItemsItemType = "PULL_REQUEST_REVISION_MARKER" // Represents the latest point in the pull request timeline for which the viewer has seen the pull request's commits.
|
||||
PullRequestTimelineItemsItemTypeBaseRefChangedEvent PullRequestTimelineItemsItemType = "BASE_REF_CHANGED_EVENT" // Represents a 'base_ref_changed' event on a given issue or pull request.
|
||||
PullRequestTimelineItemsItemTypeBaseRefForcePushedEvent PullRequestTimelineItemsItemType = "BASE_REF_FORCE_PUSHED_EVENT" // Represents a 'base_ref_force_pushed' event on a given pull request.
|
||||
PullRequestTimelineItemsItemTypeDeployedEvent PullRequestTimelineItemsItemType = "DEPLOYED_EVENT" // Represents a 'deployed' event on a given pull request.
|
||||
PullRequestTimelineItemsItemTypeDeploymentEnvironmentChangedEvent PullRequestTimelineItemsItemType = "DEPLOYMENT_ENVIRONMENT_CHANGED_EVENT" // Represents a 'deployment_environment_changed' event on a given pull request.
|
||||
PullRequestTimelineItemsItemTypeHeadRefDeletedEvent PullRequestTimelineItemsItemType = "HEAD_REF_DELETED_EVENT" // Represents a 'head_ref_deleted' event on a given pull request.
|
||||
PullRequestTimelineItemsItemTypeHeadRefForcePushedEvent PullRequestTimelineItemsItemType = "HEAD_REF_FORCE_PUSHED_EVENT" // Represents a 'head_ref_force_pushed' event on a given pull request.
|
||||
PullRequestTimelineItemsItemTypeHeadRefRestoredEvent PullRequestTimelineItemsItemType = "HEAD_REF_RESTORED_EVENT" // Represents a 'head_ref_restored' event on a given pull request.
|
||||
PullRequestTimelineItemsItemTypeMergedEvent PullRequestTimelineItemsItemType = "MERGED_EVENT" // Represents a 'merged' event on a given pull request.
|
||||
PullRequestTimelineItemsItemTypeReviewDismissedEvent PullRequestTimelineItemsItemType = "REVIEW_DISMISSED_EVENT" // Represents a 'review_dismissed' event on a given issue or pull request.
|
||||
PullRequestTimelineItemsItemTypeReviewRequestedEvent PullRequestTimelineItemsItemType = "REVIEW_REQUESTED_EVENT" // Represents an 'review_requested' event on a given pull request.
|
||||
PullRequestTimelineItemsItemTypeReviewRequestRemovedEvent PullRequestTimelineItemsItemType = "REVIEW_REQUEST_REMOVED_EVENT" // Represents an 'review_request_removed' event on a given pull request.
|
||||
PullRequestTimelineItemsItemTypeIssueComment PullRequestTimelineItemsItemType = "ISSUE_COMMENT" // Represents a comment on an Issue.
|
||||
PullRequestTimelineItemsItemTypeCrossReferencedEvent PullRequestTimelineItemsItemType = "CROSS_REFERENCED_EVENT" // Represents a mention made by one issue or pull request to another.
|
||||
PullRequestTimelineItemsItemTypeAddedToProjectEvent PullRequestTimelineItemsItemType = "ADDED_TO_PROJECT_EVENT" // Represents a 'added_to_project' event on a given issue or pull request.
|
||||
PullRequestTimelineItemsItemTypeAssignedEvent PullRequestTimelineItemsItemType = "ASSIGNED_EVENT" // Represents an 'assigned' event on any assignable object.
|
||||
PullRequestTimelineItemsItemTypeClosedEvent PullRequestTimelineItemsItemType = "CLOSED_EVENT" // Represents a 'closed' event on any `Closable`.
|
||||
PullRequestTimelineItemsItemTypeCommentDeletedEvent PullRequestTimelineItemsItemType = "COMMENT_DELETED_EVENT" // Represents a 'comment_deleted' event on a given issue or pull request.
|
||||
PullRequestTimelineItemsItemTypeConvertedNoteToIssueEvent PullRequestTimelineItemsItemType = "CONVERTED_NOTE_TO_ISSUE_EVENT" // Represents a 'converted_note_to_issue' event on a given issue or pull request.
|
||||
PullRequestTimelineItemsItemTypeDemilestonedEvent PullRequestTimelineItemsItemType = "DEMILESTONED_EVENT" // Represents a 'demilestoned' event on a given issue or pull request.
|
||||
PullRequestTimelineItemsItemTypeLabeledEvent PullRequestTimelineItemsItemType = "LABELED_EVENT" // Represents a 'labeled' event on a given issue or pull request.
|
||||
PullRequestTimelineItemsItemTypeLockedEvent PullRequestTimelineItemsItemType = "LOCKED_EVENT" // Represents a 'locked' event on a given issue or pull request.
|
||||
PullRequestTimelineItemsItemTypeMentionedEvent PullRequestTimelineItemsItemType = "MENTIONED_EVENT" // Represents a 'mentioned' event on a given issue or pull request.
|
||||
PullRequestTimelineItemsItemTypeMilestonedEvent PullRequestTimelineItemsItemType = "MILESTONED_EVENT" // Represents a 'milestoned' event on a given issue or pull request.
|
||||
PullRequestTimelineItemsItemTypeMovedColumnsInProjectEvent PullRequestTimelineItemsItemType = "MOVED_COLUMNS_IN_PROJECT_EVENT" // Represents a 'moved_columns_in_project' event on a given issue or pull request.
|
||||
PullRequestTimelineItemsItemTypePinnedEvent PullRequestTimelineItemsItemType = "PINNED_EVENT" // Represents a 'pinned' event on a given issue or pull request.
|
||||
PullRequestTimelineItemsItemTypeReferencedEvent PullRequestTimelineItemsItemType = "REFERENCED_EVENT" // Represents a 'referenced' event on a given `ReferencedSubject`.
|
||||
PullRequestTimelineItemsItemTypeRemovedFromProjectEvent PullRequestTimelineItemsItemType = "REMOVED_FROM_PROJECT_EVENT" // Represents a 'removed_from_project' event on a given issue or pull request.
|
||||
PullRequestTimelineItemsItemTypeRenamedTitleEvent PullRequestTimelineItemsItemType = "RENAMED_TITLE_EVENT" // Represents a 'renamed' event on a given issue or pull request.
|
||||
PullRequestTimelineItemsItemTypeReopenedEvent PullRequestTimelineItemsItemType = "REOPENED_EVENT" // Represents a 'reopened' event on any `Closable`.
|
||||
PullRequestTimelineItemsItemTypeSubscribedEvent PullRequestTimelineItemsItemType = "SUBSCRIBED_EVENT" // Represents a 'subscribed' event on a given `Subscribable`.
|
||||
PullRequestTimelineItemsItemTypeTransferredEvent PullRequestTimelineItemsItemType = "TRANSFERRED_EVENT" // Represents a 'transferred' event on a given issue or pull request.
|
||||
PullRequestTimelineItemsItemTypeUnassignedEvent PullRequestTimelineItemsItemType = "UNASSIGNED_EVENT" // Represents an 'unassigned' event on any assignable object.
|
||||
PullRequestTimelineItemsItemTypeUnlabeledEvent PullRequestTimelineItemsItemType = "UNLABELED_EVENT" // Represents an 'unlabeled' event on a given issue or pull request.
|
||||
PullRequestTimelineItemsItemTypeUnlockedEvent PullRequestTimelineItemsItemType = "UNLOCKED_EVENT" // Represents an 'unlocked' event on a given issue or pull request.
|
||||
PullRequestTimelineItemsItemTypeUserBlockedEvent PullRequestTimelineItemsItemType = "USER_BLOCKED_EVENT" // Represents a 'user_blocked' event on a given user.
|
||||
PullRequestTimelineItemsItemTypeUnpinnedEvent PullRequestTimelineItemsItemType = "UNPINNED_EVENT" // Represents an 'unpinned' event on a given issue or pull request.
|
||||
PullRequestTimelineItemsItemTypeUnsubscribedEvent PullRequestTimelineItemsItemType = "UNSUBSCRIBED_EVENT" // Represents an 'unsubscribed' event on a given `Subscribable`.
|
||||
)
|
||||
|
||||
// ReactionContent represents emojis that can be attached to Issues, Pull Requests and Comments.
|
||||
type ReactionContent string
|
||||
|
||||
@ -309,6 +490,8 @@ const (
|
||||
ReactionContentHooray ReactionContent = "HOORAY" // Represents the 🎉 emoji.
|
||||
ReactionContentConfused ReactionContent = "CONFUSED" // Represents the 😕 emoji.
|
||||
ReactionContentHeart ReactionContent = "HEART" // Represents the ❤️ emoji.
|
||||
ReactionContentRocket ReactionContent = "ROCKET" // Represents the 🚀 emoji.
|
||||
ReactionContentEyes ReactionContent = "EYES" // Represents the 👀 emoji.
|
||||
)
|
||||
|
||||
// ReactionOrderField represents a list of fields that reactions can be ordered by.
|
||||
@ -337,6 +520,18 @@ const (
|
||||
ReleaseOrderFieldName ReleaseOrderField = "NAME" // Order releases alphabetically by name.
|
||||
)
|
||||
|
||||
// ReportedContentClassifiers represents the reasons a piece of content can be reported or minimized.
|
||||
type ReportedContentClassifiers string
|
||||
|
||||
// The reasons a piece of content can be reported or minimized.
|
||||
const (
|
||||
ReportedContentClassifiersSpam ReportedContentClassifiers = "SPAM" // A spammy piece of content.
|
||||
ReportedContentClassifiersAbuse ReportedContentClassifiers = "ABUSE" // An abusive or harassing piece of content.
|
||||
ReportedContentClassifiersOffTopic ReportedContentClassifiers = "OFF_TOPIC" // An irrelevant piece of content.
|
||||
ReportedContentClassifiersOutdated ReportedContentClassifiers = "OUTDATED" // An outdated piece of content.
|
||||
ReportedContentClassifiersResolved ReportedContentClassifiers = "RESOLVED" // The content has been resolved.
|
||||
)
|
||||
|
||||
// RepositoryAffiliation represents the affiliation of a user to a repository.
|
||||
type RepositoryAffiliation string
|
||||
|
||||
@ -396,9 +591,11 @@ type RepositoryPermission string
|
||||
|
||||
// The access level to a repository.
|
||||
const (
|
||||
RepositoryPermissionAdmin RepositoryPermission = "ADMIN" // Can read, clone, push, and add collaborators.
|
||||
RepositoryPermissionWrite RepositoryPermission = "WRITE" // Can read, clone and push.
|
||||
RepositoryPermissionRead RepositoryPermission = "READ" // Can read and clone.
|
||||
RepositoryPermissionAdmin RepositoryPermission = "ADMIN" // Can read, clone, and push to this repository. Can also manage issues, pull requests, and repository settings, including adding collaborators.
|
||||
RepositoryPermissionMaintain RepositoryPermission = "MAINTAIN" // Can read, clone, and push to this repository. They can also manage issues, pull requests, and some repository settings.
|
||||
RepositoryPermissionWrite RepositoryPermission = "WRITE" // Can read, clone, and push to this repository. Can also manage issues and pull requests.
|
||||
RepositoryPermissionTriage RepositoryPermission = "TRIAGE" // Can read and clone this repository. Can also manage issues and pull requests.
|
||||
RepositoryPermissionRead RepositoryPermission = "READ" // Can read and clone this repository. Can also open and comment on issues and pull requests.
|
||||
)
|
||||
|
||||
// RepositoryPrivacy represents the privacy of a repository.
|
||||
@ -420,6 +617,55 @@ const (
|
||||
SearchTypeUser SearchType = "USER" // Returns results matching users and organizations on GitHub.
|
||||
)
|
||||
|
||||
// SecurityAdvisoryEcosystem represents the possible ecosystems of a security vulnerability's package.
|
||||
type SecurityAdvisoryEcosystem string
|
||||
|
||||
// The possible ecosystems of a security vulnerability's package.
|
||||
const (
|
||||
SecurityAdvisoryEcosystemRubygems SecurityAdvisoryEcosystem = "RUBYGEMS" // Ruby gems hosted at RubyGems.org.
|
||||
SecurityAdvisoryEcosystemNpm SecurityAdvisoryEcosystem = "NPM" // JavaScript packages hosted at npmjs.com.
|
||||
SecurityAdvisoryEcosystemPip SecurityAdvisoryEcosystem = "PIP" // Python packages hosted at PyPI.org.
|
||||
SecurityAdvisoryEcosystemMaven SecurityAdvisoryEcosystem = "MAVEN" // Java artifacts hosted at the Maven central repository.
|
||||
SecurityAdvisoryEcosystemNuget SecurityAdvisoryEcosystem = "NUGET" // .NET packages hosted at the NuGet Gallery.
|
||||
)
|
||||
|
||||
// SecurityAdvisoryIdentifierType represents identifier formats available for advisories.
|
||||
type SecurityAdvisoryIdentifierType string
|
||||
|
||||
// Identifier formats available for advisories.
|
||||
const (
|
||||
SecurityAdvisoryIdentifierTypeCve SecurityAdvisoryIdentifierType = "CVE" // Common Vulnerabilities and Exposures Identifier.
|
||||
SecurityAdvisoryIdentifierTypeGhsa SecurityAdvisoryIdentifierType = "GHSA" // GitHub Security Advisory ID.
|
||||
)
|
||||
|
||||
// SecurityAdvisoryOrderField represents properties by which security advisory connections can be ordered.
|
||||
type SecurityAdvisoryOrderField string
|
||||
|
||||
// Properties by which security advisory connections can be ordered.
|
||||
const (
|
||||
SecurityAdvisoryOrderFieldPublishedAt SecurityAdvisoryOrderField = "PUBLISHED_AT" // Order advisories by publication time.
|
||||
SecurityAdvisoryOrderFieldUpdatedAt SecurityAdvisoryOrderField = "UPDATED_AT" // Order advisories by update time.
|
||||
)
|
||||
|
||||
// SecurityAdvisorySeverity represents severity of the vulnerability.
|
||||
type SecurityAdvisorySeverity string
|
||||
|
||||
// Severity of the vulnerability.
|
||||
const (
|
||||
SecurityAdvisorySeverityLow SecurityAdvisorySeverity = "LOW" // Low.
|
||||
SecurityAdvisorySeverityModerate SecurityAdvisorySeverity = "MODERATE" // Moderate.
|
||||
SecurityAdvisorySeverityHigh SecurityAdvisorySeverity = "HIGH" // High.
|
||||
SecurityAdvisorySeverityCritical SecurityAdvisorySeverity = "CRITICAL" // Critical.
|
||||
)
|
||||
|
||||
// SecurityVulnerabilityOrderField represents properties by which security vulnerability connections can be ordered.
|
||||
type SecurityVulnerabilityOrderField string
|
||||
|
||||
// Properties by which security vulnerability connections can be ordered.
|
||||
const (
|
||||
SecurityVulnerabilityOrderFieldUpdatedAt SecurityVulnerabilityOrderField = "UPDATED_AT" // Order vulnerability by update time.
|
||||
)
|
||||
|
||||
// StarOrderField represents properties by which star connections can be ordered.
|
||||
type StarOrderField string
|
||||
|
||||
@ -445,7 +691,7 @@ type SubscriptionState string
|
||||
|
||||
// The possible states of a subscription.
|
||||
const (
|
||||
SubscriptionStateUnsubscribed SubscriptionState = "UNSUBSCRIBED" // The User is only notified when particpating or @mentioned.
|
||||
SubscriptionStateUnsubscribed SubscriptionState = "UNSUBSCRIBED" // The User is only notified when participating or @mentioned.
|
||||
SubscriptionStateSubscribed SubscriptionState = "SUBSCRIBED" // The User is notified of all conversations.
|
||||
SubscriptionStateIgnored SubscriptionState = "IGNORED" // The User is never notified.
|
||||
)
|
||||
@ -527,3 +773,23 @@ const (
|
||||
TopicSuggestionDeclineReasonPersonalPreference TopicSuggestionDeclineReason = "PERSONAL_PREFERENCE" // The viewer does not like the suggested topic.
|
||||
TopicSuggestionDeclineReasonTooGeneral TopicSuggestionDeclineReason = "TOO_GENERAL" // The suggested topic is too general for the repository.
|
||||
)
|
||||
|
||||
// UserBlockDuration represents the possible durations that a user can be blocked for.
|
||||
type UserBlockDuration string
|
||||
|
||||
// The possible durations that a user can be blocked for.
|
||||
const (
|
||||
UserBlockDurationOneDay UserBlockDuration = "ONE_DAY" // The user was blocked for 1 day.
|
||||
UserBlockDurationThreeDays UserBlockDuration = "THREE_DAYS" // The user was blocked for 3 days.
|
||||
UserBlockDurationOneWeek UserBlockDuration = "ONE_WEEK" // The user was blocked for 7 days.
|
||||
UserBlockDurationOneMonth UserBlockDuration = "ONE_MONTH" // The user was blocked for 30 days.
|
||||
UserBlockDurationPermanent UserBlockDuration = "PERMANENT" // The user was blocked permanently.
|
||||
)
|
||||
|
||||
// UserStatusOrderField represents properties by which user status connections can be ordered.
|
||||
type UserStatusOrderField string
|
||||
|
||||
// Properties by which user status connections can be ordered.
|
||||
const (
|
||||
UserStatusOrderFieldUpdatedAt UserStatusOrderField = "UPDATED_AT" // Order user statuses by when they were updated.
|
||||
)
|
||||
|
13
vendor/github.com/shurcooL/githubv4/gen.go
generated
vendored
13
vendor/github.com/shurcooL/githubv4/gen.go
generated
vendored
@ -86,12 +86,12 @@ package githubv4
|
||||
|
||||
|
||||
{{- define "enum" -}}
|
||||
// {{.name}} {{.description | endSentence}}
|
||||
// {{.name}} {{.description | clean | endSentence}}
|
||||
type {{.name}} string
|
||||
|
||||
// {{.description | fullSentence}}
|
||||
// {{.description | clean | fullSentence}}
|
||||
const ({{range .enumValues}}
|
||||
{{$.name}}{{.name | enumIdentifier}} {{$.name}} = {{.name | quote}} // {{.description | fullSentence}}{{end}}
|
||||
{{$.name}}{{.name | enumIdentifier}} {{$.name}} = {{.name | quote}} // {{.description | clean | fullSentence}}{{end}}
|
||||
)
|
||||
{{- end -}}
|
||||
`),
|
||||
@ -110,12 +110,12 @@ type Input interface{}
|
||||
|
||||
|
||||
{{- define "inputObject" -}}
|
||||
// {{.name}} {{.description | endSentence}}
|
||||
// {{.name}} {{.description | clean | endSentence}}
|
||||
type {{.name}} struct {{"{"}}{{range .inputFields}}{{if eq .type.kind "NON_NULL"}}
|
||||
// {{.description | fullSentence}} (Required.)
|
||||
// {{.description | clean | fullSentence}} (Required.)
|
||||
{{.name | identifier}} {{.type | type}} ` + "`" + `json:"{{.name}}"` + "`" + `{{end}}{{end}}
|
||||
{{range .inputFields}}{{if ne .type.kind "NON_NULL"}}
|
||||
// {{.description | fullSentence}} (Optional.)
|
||||
// {{.description | clean | fullSentence}} (Optional.)
|
||||
{{.name | identifier}} {{.type | type}} ` + "`" + `json:"{{.name}},omitempty"` + "`" + `{{end}}{{end}}
|
||||
}
|
||||
{{- end -}}
|
||||
@ -167,6 +167,7 @@ func t(text string) *template.Template {
|
||||
"identifier": func(name string) string { return ident.ParseLowerCamelCase(name).ToMixedCaps() },
|
||||
"enumIdentifier": func(name string) string { return ident.ParseScreamingSnakeCase(name).ToMixedCaps() },
|
||||
"type": typeString,
|
||||
"clean": func(s string) string { return strings.Join(strings.Fields(s), " ") },
|
||||
"endSentence": func(s string) string {
|
||||
s = strings.ToLower(s[0:1]) + s[1:]
|
||||
switch {
|
||||
|
574
vendor/github.com/shurcooL/githubv4/input.go
generated
vendored
574
vendor/github.com/shurcooL/githubv4/input.go
generated
vendored
@ -4,7 +4,7 @@ package githubv4
|
||||
|
||||
// Input represents one of the Input structs:
|
||||
//
|
||||
// AcceptTopicSuggestionInput, AddCommentInput, AddProjectCardInput, AddProjectColumnInput, AddPullRequestReviewCommentInput, AddPullRequestReviewInput, AddReactionInput, AddStarInput, CommitAuthor, CreateProjectInput, DeclineTopicSuggestionInput, DeleteProjectCardInput, DeleteProjectColumnInput, DeleteProjectInput, DeletePullRequestReviewInput, DismissPullRequestReviewInput, DraftPullRequestReviewComment, GistOrder, IssueOrder, LanguageOrder, LockLockableInput, MilestoneOrder, MoveProjectCardInput, MoveProjectColumnInput, ProjectOrder, ReactionOrder, RefOrder, ReleaseOrder, RemoveOutsideCollaboratorInput, RemoveReactionInput, RemoveStarInput, RepositoryOrder, RequestReviewsInput, StarOrder, SubmitPullRequestReviewInput, TeamMemberOrder, TeamOrder, TeamRepositoryOrder, UpdateProjectCardInput, UpdateProjectColumnInput, UpdateProjectInput, UpdatePullRequestReviewCommentInput, UpdatePullRequestReviewInput, UpdateSubscriptionInput, UpdateTopicsInput.
|
||||
// AcceptTopicSuggestionInput, AddAssigneesToAssignableInput, AddCommentInput, AddLabelsToLabelableInput, AddProjectCardInput, AddProjectColumnInput, AddPullRequestReviewCommentInput, AddPullRequestReviewInput, AddReactionInput, AddStarInput, ChangeUserStatusInput, ClearLabelsFromLabelableInput, CloneProjectInput, CloseIssueInput, ClosePullRequestInput, CommitAuthor, CommitContributionOrder, ContributionOrder, ConvertProjectCardNoteToIssueInput, CreateBranchProtectionRuleInput, CreateContentAttachmentInput, CreateIssueInput, CreateProjectInput, CreatePullRequestInput, DeclineTopicSuggestionInput, DeleteBranchProtectionRuleInput, DeleteIssueCommentInput, DeleteIssueInput, DeleteProjectCardInput, DeleteProjectColumnInput, DeleteProjectInput, DeletePullRequestReviewCommentInput, DeletePullRequestReviewInput, DeploymentOrder, DismissPullRequestReviewInput, DraftPullRequestReviewComment, GistOrder, ImportProjectInput, IssueFilters, IssueOrder, LanguageOrder, LockLockableInput, MergePullRequestInput, MilestoneOrder, MinimizeCommentInput, MoveProjectCardInput, MoveProjectColumnInput, PinIssueInput, ProjectCardImport, ProjectColumnImport, ProjectOrder, PullRequestOrder, ReactionOrder, RefOrder, ReleaseOrder, RemoveAssigneesFromAssignableInput, RemoveLabelsFromLabelableInput, RemoveOutsideCollaboratorInput, RemoveReactionInput, RemoveStarInput, ReopenIssueInput, ReopenPullRequestInput, RepositoryOrder, RequestReviewsInput, ResolveReviewThreadInput, SecurityAdvisoryIdentifierFilter, SecurityAdvisoryOrder, SecurityVulnerabilityOrder, StarOrder, SubmitPullRequestReviewInput, TeamMemberOrder, TeamOrder, TeamRepositoryOrder, UnlockLockableInput, UnmarkIssueAsDuplicateInput, UnminimizeCommentInput, UnpinIssueInput, UnresolveReviewThreadInput, UpdateBranchProtectionRuleInput, UpdateIssueCommentInput, UpdateIssueInput, UpdateProjectCardInput, UpdateProjectColumnInput, UpdateProjectInput, UpdatePullRequestInput, UpdatePullRequestReviewCommentInput, UpdatePullRequestReviewInput, UpdateSubscriptionInput, UpdateTopicsInput, UserStatusOrder.
|
||||
type Input interface{}
|
||||
|
||||
// AcceptTopicSuggestionInput is an autogenerated input type of AcceptTopicSuggestion.
|
||||
@ -18,6 +18,17 @@ type AcceptTopicSuggestionInput struct {
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// AddAssigneesToAssignableInput is an autogenerated input type of AddAssigneesToAssignable.
|
||||
type AddAssigneesToAssignableInput struct {
|
||||
// The id of the assignable object to add assignees to. (Required.)
|
||||
AssignableID ID `json:"assignableId"`
|
||||
// The id of users to add as assignees. (Required.)
|
||||
AssigneeIDs []ID `json:"assigneeIds"`
|
||||
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// AddCommentInput is an autogenerated input type of AddComment.
|
||||
type AddCommentInput struct {
|
||||
// The Node ID of the subject to modify. (Required.)
|
||||
@ -29,6 +40,17 @@ type AddCommentInput struct {
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// AddLabelsToLabelableInput is an autogenerated input type of AddLabelsToLabelable.
|
||||
type AddLabelsToLabelableInput struct {
|
||||
// The id of the labelable object to add labels to. (Required.)
|
||||
LabelableID ID `json:"labelableId"`
|
||||
// The ids of the labels to add. (Required.)
|
||||
LabelIDs []ID `json:"labelIds"`
|
||||
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// AddProjectCardInput is an autogenerated input type of AddProjectCard.
|
||||
type AddProjectCardInput struct {
|
||||
// The Node ID of the ProjectColumn. (Required.)
|
||||
@ -109,6 +131,69 @@ type AddStarInput struct {
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// ChangeUserStatusInput is an autogenerated input type of ChangeUserStatus.
|
||||
type ChangeUserStatusInput struct {
|
||||
|
||||
// The emoji to represent your status. Can either be a native Unicode emoji or an emoji name with colons, e.g., :grinning:. (Optional.)
|
||||
Emoji *String `json:"emoji,omitempty"`
|
||||
// A short description of your current status. (Optional.)
|
||||
Message *String `json:"message,omitempty"`
|
||||
// The ID of the organization whose members will be allowed to see the status. If omitted, the status will be publicly visible. (Optional.)
|
||||
OrganizationID *ID `json:"organizationId,omitempty"`
|
||||
// Whether this status should indicate you are not fully available on GitHub, e.g., you are away. (Optional.)
|
||||
LimitedAvailability *Boolean `json:"limitedAvailability,omitempty"`
|
||||
// If set, the user status will not be shown after this date. (Optional.)
|
||||
ExpiresAt *DateTime `json:"expiresAt,omitempty"`
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// ClearLabelsFromLabelableInput is an autogenerated input type of ClearLabelsFromLabelable.
|
||||
type ClearLabelsFromLabelableInput struct {
|
||||
// The id of the labelable object to clear the labels from. (Required.)
|
||||
LabelableID ID `json:"labelableId"`
|
||||
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// CloneProjectInput is an autogenerated input type of CloneProject.
|
||||
type CloneProjectInput struct {
|
||||
// The owner ID to create the project under. (Required.)
|
||||
TargetOwnerID ID `json:"targetOwnerId"`
|
||||
// The source project to clone. (Required.)
|
||||
SourceID ID `json:"sourceId"`
|
||||
// Whether or not to clone the source project's workflows. (Required.)
|
||||
IncludeWorkflows Boolean `json:"includeWorkflows"`
|
||||
// The name of the project. (Required.)
|
||||
Name String `json:"name"`
|
||||
|
||||
// The description of the project. (Optional.)
|
||||
Body *String `json:"body,omitempty"`
|
||||
// The visibility of the project, defaults to false (private). (Optional.)
|
||||
Public *Boolean `json:"public,omitempty"`
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// CloseIssueInput is an autogenerated input type of CloseIssue.
|
||||
type CloseIssueInput struct {
|
||||
// ID of the issue to be closed. (Required.)
|
||||
IssueID ID `json:"issueId"`
|
||||
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// ClosePullRequestInput is an autogenerated input type of ClosePullRequest.
|
||||
type ClosePullRequestInput struct {
|
||||
// ID of the pull request to be closed. (Required.)
|
||||
PullRequestID ID `json:"pullRequestId"`
|
||||
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// CommitAuthor specifies an author for filtering Git commits.
|
||||
type CommitAuthor struct {
|
||||
|
||||
@ -118,6 +203,108 @@ type CommitAuthor struct {
|
||||
Emails *[]String `json:"emails,omitempty"`
|
||||
}
|
||||
|
||||
// CommitContributionOrder represents ordering options for commit contribution connections.
|
||||
type CommitContributionOrder struct {
|
||||
// The field by which to order commit contributions. (Required.)
|
||||
Field CommitContributionOrderField `json:"field"`
|
||||
// The ordering direction. (Required.)
|
||||
Direction OrderDirection `json:"direction"`
|
||||
}
|
||||
|
||||
// ContributionOrder represents ordering options for contribution connections.
|
||||
type ContributionOrder struct {
|
||||
// The field by which to order contributions. (Required.)
|
||||
Field ContributionOrderField `json:"field"`
|
||||
// The ordering direction. (Required.)
|
||||
Direction OrderDirection `json:"direction"`
|
||||
}
|
||||
|
||||
// ConvertProjectCardNoteToIssueInput is an autogenerated input type of ConvertProjectCardNoteToIssue.
|
||||
type ConvertProjectCardNoteToIssueInput struct {
|
||||
// The ProjectCard ID to convert. (Required.)
|
||||
ProjectCardID ID `json:"projectCardId"`
|
||||
// The ID of the repository to create the issue in. (Required.)
|
||||
RepositoryID ID `json:"repositoryId"`
|
||||
|
||||
// The title of the newly created issue. Defaults to the card's note text. (Optional.)
|
||||
Title *String `json:"title,omitempty"`
|
||||
// The body of the newly created issue. (Optional.)
|
||||
Body *String `json:"body,omitempty"`
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// CreateBranchProtectionRuleInput is an autogenerated input type of CreateBranchProtectionRule.
|
||||
type CreateBranchProtectionRuleInput struct {
|
||||
// The global relay id of the repository in which a new branch protection rule should be created in. (Required.)
|
||||
RepositoryID ID `json:"repositoryId"`
|
||||
// The glob-like pattern used to determine matching branches. (Required.)
|
||||
Pattern String `json:"pattern"`
|
||||
|
||||
// Are approving reviews required to update matching branches. (Optional.)
|
||||
RequiresApprovingReviews *Boolean `json:"requiresApprovingReviews,omitempty"`
|
||||
// Number of approving reviews required to update matching branches. (Optional.)
|
||||
RequiredApprovingReviewCount *Int `json:"requiredApprovingReviewCount,omitempty"`
|
||||
// Are commits required to be signed. (Optional.)
|
||||
RequiresCommitSignatures *Boolean `json:"requiresCommitSignatures,omitempty"`
|
||||
// Can admins overwrite branch protection. (Optional.)
|
||||
IsAdminEnforced *Boolean `json:"isAdminEnforced,omitempty"`
|
||||
// Are status checks required to update matching branches. (Optional.)
|
||||
RequiresStatusChecks *Boolean `json:"requiresStatusChecks,omitempty"`
|
||||
// Are branches required to be up to date before merging. (Optional.)
|
||||
RequiresStrictStatusChecks *Boolean `json:"requiresStrictStatusChecks,omitempty"`
|
||||
// Are reviews from code owners required to update matching branches. (Optional.)
|
||||
RequiresCodeOwnerReviews *Boolean `json:"requiresCodeOwnerReviews,omitempty"`
|
||||
// Will new commits pushed to matching branches dismiss pull request review approvals. (Optional.)
|
||||
DismissesStaleReviews *Boolean `json:"dismissesStaleReviews,omitempty"`
|
||||
// Is dismissal of pull request reviews restricted. (Optional.)
|
||||
RestrictsReviewDismissals *Boolean `json:"restrictsReviewDismissals,omitempty"`
|
||||
// A list of User or Team IDs allowed to dismiss reviews on pull requests targeting matching branches. (Optional.)
|
||||
ReviewDismissalActorIDs *[]ID `json:"reviewDismissalActorIds,omitempty"`
|
||||
// Is pushing to matching branches restricted. (Optional.)
|
||||
RestrictsPushes *Boolean `json:"restrictsPushes,omitempty"`
|
||||
// A list of User or Team IDs allowed to push to matching branches. (Optional.)
|
||||
PushActorIDs *[]ID `json:"pushActorIds,omitempty"`
|
||||
// List of required status check contexts that must pass for commits to be accepted to matching branches. (Optional.)
|
||||
RequiredStatusCheckContexts *[]String `json:"requiredStatusCheckContexts,omitempty"`
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// CreateContentAttachmentInput is an autogenerated input type of CreateContentAttachment.
|
||||
type CreateContentAttachmentInput struct {
|
||||
// The node ID of the content_reference. (Required.)
|
||||
ContentReferenceID ID `json:"contentReferenceId"`
|
||||
// The title of the content attachment. (Required.)
|
||||
Title String `json:"title"`
|
||||
// The body of the content attachment, which may contain markdown. (Required.)
|
||||
Body String `json:"body"`
|
||||
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// CreateIssueInput is an autogenerated input type of CreateIssue.
|
||||
type CreateIssueInput struct {
|
||||
// The Node ID of the repository. (Required.)
|
||||
RepositoryID ID `json:"repositoryId"`
|
||||
// The title for the issue. (Required.)
|
||||
Title String `json:"title"`
|
||||
|
||||
// The body for the issue description. (Optional.)
|
||||
Body *String `json:"body,omitempty"`
|
||||
// The Node ID for the user assignee for this issue. (Optional.)
|
||||
AssigneeIDs *[]ID `json:"assigneeIds,omitempty"`
|
||||
// The Node ID of the milestone for this issue. (Optional.)
|
||||
MilestoneID *ID `json:"milestoneId,omitempty"`
|
||||
// An array of Node IDs of labels for this issue. (Optional.)
|
||||
LabelIDs *[]ID `json:"labelIds,omitempty"`
|
||||
// An array of Node IDs for projects associated with this issue. (Optional.)
|
||||
ProjectIDs *[]ID `json:"projectIds,omitempty"`
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// CreateProjectInput is an autogenerated input type of CreateProject.
|
||||
type CreateProjectInput struct {
|
||||
// The owner ID to create the project under. (Required.)
|
||||
@ -131,6 +318,25 @@ type CreateProjectInput struct {
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// CreatePullRequestInput is an autogenerated input type of CreatePullRequest.
|
||||
type CreatePullRequestInput struct {
|
||||
// The Node ID of the repository. (Required.)
|
||||
RepositoryID ID `json:"repositoryId"`
|
||||
// The name of the branch you want your changes pulled into. This should be an existing branch on the current repository. You cannot update the base branch on a pull request to point to another repository. (Required.)
|
||||
BaseRefName String `json:"baseRefName"`
|
||||
// The name of the branch where your changes are implemented. For cross-repository pull requests in the same network, namespace `head_ref_name` with a user like this: `username:branch`. (Required.)
|
||||
HeadRefName String `json:"headRefName"`
|
||||
// The title of the pull request. (Required.)
|
||||
Title String `json:"title"`
|
||||
|
||||
// The contents of the pull request. (Optional.)
|
||||
Body *String `json:"body,omitempty"`
|
||||
// Indicates whether maintainers can modify the pull request. (Optional.)
|
||||
MaintainerCanModify *Boolean `json:"maintainerCanModify,omitempty"`
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// DeclineTopicSuggestionInput is an autogenerated input type of DeclineTopicSuggestion.
|
||||
type DeclineTopicSuggestionInput struct {
|
||||
// The Node ID of the repository. (Required.)
|
||||
@ -144,6 +350,33 @@ type DeclineTopicSuggestionInput struct {
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// DeleteBranchProtectionRuleInput is an autogenerated input type of DeleteBranchProtectionRule.
|
||||
type DeleteBranchProtectionRuleInput struct {
|
||||
// The global relay id of the branch protection rule to be deleted. (Required.)
|
||||
BranchProtectionRuleID ID `json:"branchProtectionRuleId"`
|
||||
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// DeleteIssueCommentInput is an autogenerated input type of DeleteIssueComment.
|
||||
type DeleteIssueCommentInput struct {
|
||||
// The ID of the comment to delete. (Required.)
|
||||
ID ID `json:"id"`
|
||||
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// DeleteIssueInput is an autogenerated input type of DeleteIssue.
|
||||
type DeleteIssueInput struct {
|
||||
// The ID of the issue to delete. (Required.)
|
||||
IssueID ID `json:"issueId"`
|
||||
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// DeleteProjectCardInput is an autogenerated input type of DeleteProjectCard.
|
||||
type DeleteProjectCardInput struct {
|
||||
// The id of the card to delete. (Required.)
|
||||
@ -171,6 +404,15 @@ type DeleteProjectInput struct {
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// DeletePullRequestReviewCommentInput is an autogenerated input type of DeletePullRequestReviewComment.
|
||||
type DeletePullRequestReviewCommentInput struct {
|
||||
// The ID of the comment to delete. (Required.)
|
||||
ID ID `json:"id"`
|
||||
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// DeletePullRequestReviewInput is an autogenerated input type of DeletePullRequestReview.
|
||||
type DeletePullRequestReviewInput struct {
|
||||
// The Node ID of the pull request review to delete. (Required.)
|
||||
@ -180,6 +422,14 @@ type DeletePullRequestReviewInput struct {
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// DeploymentOrder represents ordering options for deployment connections.
|
||||
type DeploymentOrder struct {
|
||||
// The field to order deployments by. (Required.)
|
||||
Field DeploymentOrderField `json:"field"`
|
||||
// The ordering direction. (Required.)
|
||||
Direction OrderDirection `json:"direction"`
|
||||
}
|
||||
|
||||
// DismissPullRequestReviewInput is an autogenerated input type of DismissPullRequestReview.
|
||||
type DismissPullRequestReviewInput struct {
|
||||
// The Node ID of the pull request review to modify. (Required.)
|
||||
@ -209,6 +459,44 @@ type GistOrder struct {
|
||||
Direction OrderDirection `json:"direction"`
|
||||
}
|
||||
|
||||
// ImportProjectInput is an autogenerated input type of ImportProject.
|
||||
type ImportProjectInput struct {
|
||||
// The name of the Organization or User to create the Project under. (Required.)
|
||||
OwnerName String `json:"ownerName"`
|
||||
// The name of Project. (Required.)
|
||||
Name String `json:"name"`
|
||||
// A list of columns containing issues and pull requests. (Required.)
|
||||
ColumnImports []ProjectColumnImport `json:"columnImports"`
|
||||
|
||||
// The description of Project. (Optional.)
|
||||
Body *String `json:"body,omitempty"`
|
||||
// Whether the Project is public or not. (Optional.)
|
||||
Public *Boolean `json:"public,omitempty"`
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// IssueFilters represents ways in which to filter lists of issues.
|
||||
type IssueFilters struct {
|
||||
|
||||
// List issues assigned to given name. Pass in `null` for issues with no assigned user, and `*` for issues assigned to any user. (Optional.)
|
||||
Assignee *String `json:"assignee,omitempty"`
|
||||
// List issues created by given name. (Optional.)
|
||||
CreatedBy *String `json:"createdBy,omitempty"`
|
||||
// List issues where the list of label names exist on the issue. (Optional.)
|
||||
Labels *[]String `json:"labels,omitempty"`
|
||||
// List issues where the given name is mentioned in the issue. (Optional.)
|
||||
Mentioned *String `json:"mentioned,omitempty"`
|
||||
// List issues by given milestone argument. If an string representation of an integer is passed, it should refer to a milestone by its number field. Pass in `null` for issues with no milestone, and `*` for issues that are assigned to any milestone. (Optional.)
|
||||
Milestone *String `json:"milestone,omitempty"`
|
||||
// List issues that have been updated at or after the given date. (Optional.)
|
||||
Since *DateTime `json:"since,omitempty"`
|
||||
// List issues filtered by the list of states given. (Optional.)
|
||||
States *[]IssueState `json:"states,omitempty"`
|
||||
// List issues subscribed to by viewer. (Optional.)
|
||||
ViewerSubscribed *Boolean `json:"viewerSubscribed,omitempty"`
|
||||
}
|
||||
|
||||
// IssueOrder represents ways in which lists of issues can be ordered upon return.
|
||||
type IssueOrder struct {
|
||||
// The field in which to order issues by. (Required.)
|
||||
@ -236,6 +524,21 @@ type LockLockableInput struct {
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// MergePullRequestInput is an autogenerated input type of MergePullRequest.
|
||||
type MergePullRequestInput struct {
|
||||
// ID of the pull request to be merged. (Required.)
|
||||
PullRequestID ID `json:"pullRequestId"`
|
||||
|
||||
// Commit headline to use for the merge commit; if omitted, a default message will be used. (Optional.)
|
||||
CommitHeadline *String `json:"commitHeadline,omitempty"`
|
||||
// Commit body to use for the merge commit; if omitted, a default message will be used. (Optional.)
|
||||
CommitBody *String `json:"commitBody,omitempty"`
|
||||
// OID that the pull request head ref must match to allow merge; if omitted, no check is performed. (Optional.)
|
||||
ExpectedHeadOid *GitObjectID `json:"expectedHeadOid,omitempty"`
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// MilestoneOrder represents ordering options for milestone connections.
|
||||
type MilestoneOrder struct {
|
||||
// The field to order milestones by. (Required.)
|
||||
@ -244,6 +547,17 @@ type MilestoneOrder struct {
|
||||
Direction OrderDirection `json:"direction"`
|
||||
}
|
||||
|
||||
// MinimizeCommentInput is an autogenerated input type of MinimizeComment.
|
||||
type MinimizeCommentInput struct {
|
||||
// The Node ID of the subject to modify. (Required.)
|
||||
SubjectID ID `json:"subjectId"`
|
||||
// The classification of comment. (Required.)
|
||||
Classifier ReportedContentClassifiers `json:"classifier"`
|
||||
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// MoveProjectCardInput is an autogenerated input type of MoveProjectCard.
|
||||
type MoveProjectCardInput struct {
|
||||
// The id of the card to move. (Required.)
|
||||
@ -268,6 +582,34 @@ type MoveProjectColumnInput struct {
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// PinIssueInput is an autogenerated input type of PinIssue.
|
||||
type PinIssueInput struct {
|
||||
// The ID of the issue to be pinned. (Required.)
|
||||
IssueID ID `json:"issueId"`
|
||||
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// ProjectCardImport represents an issue or PR and its owning repository to be used in a project card.
|
||||
type ProjectCardImport struct {
|
||||
// Repository name with owner (owner/repository). (Required.)
|
||||
Repository String `json:"repository"`
|
||||
// The issue or pull request number. (Required.)
|
||||
Number Int `json:"number"`
|
||||
}
|
||||
|
||||
// ProjectColumnImport represents a project column and a list of its issues and PRs.
|
||||
type ProjectColumnImport struct {
|
||||
// The name of the column. (Required.)
|
||||
ColumnName String `json:"columnName"`
|
||||
// The position of the column, starting from 0. (Required.)
|
||||
Position Int `json:"position"`
|
||||
|
||||
// A list of issues and pull requests in the column. (Optional.)
|
||||
Issues *[]ProjectCardImport `json:"issues,omitempty"`
|
||||
}
|
||||
|
||||
// ProjectOrder represents ways in which lists of projects can be ordered upon return.
|
||||
type ProjectOrder struct {
|
||||
// The field in which to order projects by. (Required.)
|
||||
@ -276,6 +618,14 @@ type ProjectOrder struct {
|
||||
Direction OrderDirection `json:"direction"`
|
||||
}
|
||||
|
||||
// PullRequestOrder represents ways in which lists of issues can be ordered upon return.
|
||||
type PullRequestOrder struct {
|
||||
// The field in which to order pull requests by. (Required.)
|
||||
Field PullRequestOrderField `json:"field"`
|
||||
// The direction in which to order pull requests by the specified field. (Required.)
|
||||
Direction OrderDirection `json:"direction"`
|
||||
}
|
||||
|
||||
// ReactionOrder represents ways in which lists of reactions can be ordered upon return.
|
||||
type ReactionOrder struct {
|
||||
// The field in which to order reactions by. (Required.)
|
||||
@ -300,6 +650,28 @@ type ReleaseOrder struct {
|
||||
Direction OrderDirection `json:"direction"`
|
||||
}
|
||||
|
||||
// RemoveAssigneesFromAssignableInput is an autogenerated input type of RemoveAssigneesFromAssignable.
|
||||
type RemoveAssigneesFromAssignableInput struct {
|
||||
// The id of the assignable object to remove assignees from. (Required.)
|
||||
AssignableID ID `json:"assignableId"`
|
||||
// The id of users to remove as assignees. (Required.)
|
||||
AssigneeIDs []ID `json:"assigneeIds"`
|
||||
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// RemoveLabelsFromLabelableInput is an autogenerated input type of RemoveLabelsFromLabelable.
|
||||
type RemoveLabelsFromLabelableInput struct {
|
||||
// The id of the Labelable to remove labels from. (Required.)
|
||||
LabelableID ID `json:"labelableId"`
|
||||
// The ids of labels to remove. (Required.)
|
||||
LabelIDs []ID `json:"labelIds"`
|
||||
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// RemoveOutsideCollaboratorInput is an autogenerated input type of RemoveOutsideCollaborator.
|
||||
type RemoveOutsideCollaboratorInput struct {
|
||||
// The ID of the outside collaborator to remove. (Required.)
|
||||
@ -331,6 +703,24 @@ type RemoveStarInput struct {
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// ReopenIssueInput is an autogenerated input type of ReopenIssue.
|
||||
type ReopenIssueInput struct {
|
||||
// ID of the issue to be opened. (Required.)
|
||||
IssueID ID `json:"issueId"`
|
||||
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// ReopenPullRequestInput is an autogenerated input type of ReopenPullRequest.
|
||||
type ReopenPullRequestInput struct {
|
||||
// ID of the pull request to be reopened. (Required.)
|
||||
PullRequestID ID `json:"pullRequestId"`
|
||||
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// RepositoryOrder represents ordering options for repository connections.
|
||||
type RepositoryOrder struct {
|
||||
// The field to order repositories by. (Required.)
|
||||
@ -354,6 +744,39 @@ type RequestReviewsInput struct {
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// ResolveReviewThreadInput is an autogenerated input type of ResolveReviewThread.
|
||||
type ResolveReviewThreadInput struct {
|
||||
// The ID of the thread to resolve. (Required.)
|
||||
ThreadID ID `json:"threadId"`
|
||||
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// SecurityAdvisoryIdentifierFilter represents an advisory identifier to filter results on.
|
||||
type SecurityAdvisoryIdentifierFilter struct {
|
||||
// The identifier type. (Required.)
|
||||
Type SecurityAdvisoryIdentifierType `json:"type"`
|
||||
// The identifier string. Supports exact or partial matching. (Required.)
|
||||
Value String `json:"value"`
|
||||
}
|
||||
|
||||
// SecurityAdvisoryOrder represents ordering options for security advisory connections.
|
||||
type SecurityAdvisoryOrder struct {
|
||||
// The field to order security advisories by. (Required.)
|
||||
Field SecurityAdvisoryOrderField `json:"field"`
|
||||
// The ordering direction. (Required.)
|
||||
Direction OrderDirection `json:"direction"`
|
||||
}
|
||||
|
||||
// SecurityVulnerabilityOrder represents ordering options for security vulnerability connections.
|
||||
type SecurityVulnerabilityOrder struct {
|
||||
// The field to order security vulnerabilities by. (Required.)
|
||||
Field SecurityVulnerabilityOrderField `json:"field"`
|
||||
// The ordering direction. (Required.)
|
||||
Direction OrderDirection `json:"direction"`
|
||||
}
|
||||
|
||||
// StarOrder represents ways in which star connections can be ordered.
|
||||
type StarOrder struct {
|
||||
// The field in which to order nodes by. (Required.)
|
||||
@ -399,13 +822,133 @@ type TeamRepositoryOrder struct {
|
||||
Direction OrderDirection `json:"direction"`
|
||||
}
|
||||
|
||||
// UnlockLockableInput is an autogenerated input type of UnlockLockable.
|
||||
type UnlockLockableInput struct {
|
||||
// ID of the issue or pull request to be unlocked. (Required.)
|
||||
LockableID ID `json:"lockableId"`
|
||||
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// UnmarkIssueAsDuplicateInput is an autogenerated input type of UnmarkIssueAsDuplicate.
|
||||
type UnmarkIssueAsDuplicateInput struct {
|
||||
// ID of the issue or pull request currently marked as a duplicate. (Required.)
|
||||
DuplicateID ID `json:"duplicateId"`
|
||||
// ID of the issue or pull request currently considered canonical/authoritative/original. (Required.)
|
||||
CanonicalID ID `json:"canonicalId"`
|
||||
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// UnminimizeCommentInput is an autogenerated input type of UnminimizeComment.
|
||||
type UnminimizeCommentInput struct {
|
||||
// The Node ID of the subject to modify. (Required.)
|
||||
SubjectID ID `json:"subjectId"`
|
||||
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// UnpinIssueInput is an autogenerated input type of UnpinIssue.
|
||||
type UnpinIssueInput struct {
|
||||
// The ID of the issue to be unpinned. (Required.)
|
||||
IssueID ID `json:"issueId"`
|
||||
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// UnresolveReviewThreadInput is an autogenerated input type of UnresolveReviewThread.
|
||||
type UnresolveReviewThreadInput struct {
|
||||
// The ID of the thread to unresolve. (Required.)
|
||||
ThreadID ID `json:"threadId"`
|
||||
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateBranchProtectionRuleInput is an autogenerated input type of UpdateBranchProtectionRule.
|
||||
type UpdateBranchProtectionRuleInput struct {
|
||||
// The global relay id of the branch protection rule to be updated. (Required.)
|
||||
BranchProtectionRuleID ID `json:"branchProtectionRuleId"`
|
||||
|
||||
// The glob-like pattern used to determine matching branches. (Optional.)
|
||||
Pattern *String `json:"pattern,omitempty"`
|
||||
// Are approving reviews required to update matching branches. (Optional.)
|
||||
RequiresApprovingReviews *Boolean `json:"requiresApprovingReviews,omitempty"`
|
||||
// Number of approving reviews required to update matching branches. (Optional.)
|
||||
RequiredApprovingReviewCount *Int `json:"requiredApprovingReviewCount,omitempty"`
|
||||
// Are commits required to be signed. (Optional.)
|
||||
RequiresCommitSignatures *Boolean `json:"requiresCommitSignatures,omitempty"`
|
||||
// Can admins overwrite branch protection. (Optional.)
|
||||
IsAdminEnforced *Boolean `json:"isAdminEnforced,omitempty"`
|
||||
// Are status checks required to update matching branches. (Optional.)
|
||||
RequiresStatusChecks *Boolean `json:"requiresStatusChecks,omitempty"`
|
||||
// Are branches required to be up to date before merging. (Optional.)
|
||||
RequiresStrictStatusChecks *Boolean `json:"requiresStrictStatusChecks,omitempty"`
|
||||
// Are reviews from code owners required to update matching branches. (Optional.)
|
||||
RequiresCodeOwnerReviews *Boolean `json:"requiresCodeOwnerReviews,omitempty"`
|
||||
// Will new commits pushed to matching branches dismiss pull request review approvals. (Optional.)
|
||||
DismissesStaleReviews *Boolean `json:"dismissesStaleReviews,omitempty"`
|
||||
// Is dismissal of pull request reviews restricted. (Optional.)
|
||||
RestrictsReviewDismissals *Boolean `json:"restrictsReviewDismissals,omitempty"`
|
||||
// A list of User or Team IDs allowed to dismiss reviews on pull requests targeting matching branches. (Optional.)
|
||||
ReviewDismissalActorIDs *[]ID `json:"reviewDismissalActorIds,omitempty"`
|
||||
// Is pushing to matching branches restricted. (Optional.)
|
||||
RestrictsPushes *Boolean `json:"restrictsPushes,omitempty"`
|
||||
// A list of User or Team IDs allowed to push to matching branches. (Optional.)
|
||||
PushActorIDs *[]ID `json:"pushActorIds,omitempty"`
|
||||
// List of required status check contexts that must pass for commits to be accepted to matching branches. (Optional.)
|
||||
RequiredStatusCheckContexts *[]String `json:"requiredStatusCheckContexts,omitempty"`
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateIssueCommentInput is an autogenerated input type of UpdateIssueComment.
|
||||
type UpdateIssueCommentInput struct {
|
||||
// The ID of the IssueComment to modify. (Required.)
|
||||
ID ID `json:"id"`
|
||||
// The updated text of the comment. (Required.)
|
||||
Body String `json:"body"`
|
||||
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateIssueInput is an autogenerated input type of UpdateIssue.
|
||||
type UpdateIssueInput struct {
|
||||
// The ID of the Issue to modify. (Required.)
|
||||
ID ID `json:"id"`
|
||||
|
||||
// The title for the issue. (Optional.)
|
||||
Title *String `json:"title,omitempty"`
|
||||
// The body for the issue description. (Optional.)
|
||||
Body *String `json:"body,omitempty"`
|
||||
// An array of Node IDs of users for this issue. (Optional.)
|
||||
AssigneeIDs *[]ID `json:"assigneeIds,omitempty"`
|
||||
// The Node ID of the milestone for this issue. (Optional.)
|
||||
MilestoneID *ID `json:"milestoneId,omitempty"`
|
||||
// An array of Node IDs of labels for this issue. (Optional.)
|
||||
LabelIDs *[]ID `json:"labelIds,omitempty"`
|
||||
// The desired issue state. (Optional.)
|
||||
State *IssueState `json:"state,omitempty"`
|
||||
// An array of Node IDs for projects associated with this issue. (Optional.)
|
||||
ProjectIDs *[]ID `json:"projectIds,omitempty"`
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateProjectCardInput is an autogenerated input type of UpdateProjectCard.
|
||||
type UpdateProjectCardInput struct {
|
||||
// The ProjectCard ID to update. (Required.)
|
||||
ProjectCardID ID `json:"projectCardId"`
|
||||
// The note of ProjectCard. (Required.)
|
||||
Note String `json:"note"`
|
||||
|
||||
// Whether or not the ProjectCard should be archived. (Optional.)
|
||||
IsArchived *Boolean `json:"isArchived,omitempty"`
|
||||
// The note of ProjectCard. (Optional.)
|
||||
Note *String `json:"note,omitempty"`
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
@ -438,6 +981,23 @@ type UpdateProjectInput struct {
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// UpdatePullRequestInput is an autogenerated input type of UpdatePullRequest.
|
||||
type UpdatePullRequestInput struct {
|
||||
// The Node ID of the pull request. (Required.)
|
||||
PullRequestID ID `json:"pullRequestId"`
|
||||
|
||||
// The name of the branch you want your changes pulled into. This should be an existing branch on the current repository. (Optional.)
|
||||
BaseRefName *String `json:"baseRefName,omitempty"`
|
||||
// The title of the pull request. (Optional.)
|
||||
Title *String `json:"title,omitempty"`
|
||||
// The contents of the pull request. (Optional.)
|
||||
Body *String `json:"body,omitempty"`
|
||||
// Indicates whether maintainers can modify the pull request. (Optional.)
|
||||
MaintainerCanModify *Boolean `json:"maintainerCanModify,omitempty"`
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// UpdatePullRequestReviewCommentInput is an autogenerated input type of UpdatePullRequestReviewComment.
|
||||
type UpdatePullRequestReviewCommentInput struct {
|
||||
// The Node ID of the comment to modify. (Required.)
|
||||
@ -481,3 +1041,11 @@ type UpdateTopicsInput struct {
|
||||
// A unique identifier for the client performing the mutation. (Optional.)
|
||||
ClientMutationID *String `json:"clientMutationId,omitempty"`
|
||||
}
|
||||
|
||||
// UserStatusOrder represents ordering options for user status connections.
|
||||
type UserStatusOrder struct {
|
||||
// The field to order user statuses by. (Required.)
|
||||
Field UserStatusOrderField `json:"field"`
|
||||
// The ordering direction. (Required.)
|
||||
Direction OrderDirection `json:"direction"`
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user