diff --git a/github/codesofconduct.go b/github/codesofconduct.go
new file mode 100644
index 00000000000..4318ba56d2c
--- /dev/null
+++ b/github/codesofconduct.go
@@ -0,0 +1,81 @@
+// Copyright 2023 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+ "context"
+ "fmt"
+)
+
+// CodesOfConductService provides access to code-of-conduct-related functions in the GitHub API.
+type CodesOfConductService service
+
+// CodeOfConduct represents a code of conduct.
+type CodeOfConduct struct {
+ Name *string `json:"name,omitempty"`
+ Key *string `json:"key,omitempty"`
+ URL *string `json:"url,omitempty"`
+ Body *string `json:"body,omitempty"`
+}
+
+func (c *CodeOfConduct) String() string {
+ return Stringify(c)
+}
+
+// List returns all codes of conduct.
+//
+// GitHub API docs: https://docs.github.com/rest/codes-of-conduct/codes-of-conduct#get-all-codes-of-conduct
+func (s *CodesOfConductService) List(ctx context.Context) ([]*CodeOfConduct, *Response, error) {
+ req, err := s.client.NewRequest("GET", "codes_of_conduct", nil)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ // TODO: remove custom Accept header when this API fully launches.
+ req.Header.Set("Accept", mediaTypeCodesOfConductPreview)
+
+ var cs []*CodeOfConduct
+ resp, err := s.client.Do(ctx, req, &cs)
+ if err != nil {
+ return nil, resp, err
+ }
+
+ return cs, resp, nil
+}
+
+// ListCodesOfConduct
+// Deprecated: Use CodesOfConductService.List instead
+func (c *Client) ListCodesOfConduct(ctx context.Context) ([]*CodeOfConduct, *Response, error) {
+ return c.CodesOfConduct.List(ctx)
+}
+
+// Get returns an individual code of conduct.
+//
+// GitHub API docs: https://docs.github.com/rest/codes-of-conduct/codes-of-conduct#get-a-code-of-conduct
+func (s *CodesOfConductService) Get(ctx context.Context, key string) (*CodeOfConduct, *Response, error) {
+ u := fmt.Sprintf("codes_of_conduct/%s", key)
+ req, err := s.client.NewRequest("GET", u, nil)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ // TODO: remove custom Accept header when this API fully launches.
+ req.Header.Set("Accept", mediaTypeCodesOfConductPreview)
+
+ coc := new(CodeOfConduct)
+ resp, err := s.client.Do(ctx, req, coc)
+ if err != nil {
+ return nil, resp, err
+ }
+
+ return coc, resp, nil
+}
+
+// GetCodeOfConduct
+// Deprecated: Use CodesOfConductService.Get instead
+func (c *Client) GetCodeOfConduct(ctx context.Context, key string) (*CodeOfConduct, *Response, error) {
+ return c.CodesOfConduct.Get(ctx, key)
+}
diff --git a/github/codesofconduct_test.go b/github/codesofconduct_test.go
new file mode 100644
index 00000000000..71ef31f7afd
--- /dev/null
+++ b/github/codesofconduct_test.go
@@ -0,0 +1,117 @@
+// Copyright 2023 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+ "context"
+ "fmt"
+ "net/http"
+ "testing"
+
+ "github.com/google/go-cmp/cmp"
+)
+
+func TestCodesOfConductService_List(t *testing.T) {
+ client, mux, _, teardown := setup()
+ defer teardown()
+
+ mux.HandleFunc("/codes_of_conduct", func(w http.ResponseWriter, r *http.Request) {
+ testMethod(t, r, "GET")
+ testHeader(t, r, "Accept", mediaTypeCodesOfConductPreview)
+ fmt.Fprint(w, `[{
+ "key": "key",
+ "name": "name",
+ "url": "url"}
+ ]`)
+ })
+
+ ctx := context.Background()
+ cs, _, err := client.ListCodesOfConduct(ctx)
+ assertNilError(t, err)
+
+ want := []*CodeOfConduct{
+ {
+ Key: String("key"),
+ Name: String("name"),
+ URL: String("url"),
+ }}
+ if !cmp.Equal(want, cs) {
+ t.Errorf("returned %+v, want %+v", cs, want)
+ }
+
+ const methodName = "List"
+ testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
+ got, resp, err := client.CodesOfConduct.List(ctx)
+ if got != nil {
+ t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
+ }
+ return resp, err
+ })
+}
+
+func TestCodesOfConductService_Get(t *testing.T) {
+ client, mux, _, teardown := setup()
+ defer teardown()
+
+ mux.HandleFunc("/codes_of_conduct/k", func(w http.ResponseWriter, r *http.Request) {
+ testMethod(t, r, "GET")
+ testHeader(t, r, "Accept", mediaTypeCodesOfConductPreview)
+ fmt.Fprint(w, `{
+ "key": "key",
+ "name": "name",
+ "url": "url",
+ "body": "body"}`,
+ )
+ })
+
+ ctx := context.Background()
+ coc, _, err := client.GetCodeOfConduct(ctx, "k")
+ assertNilError(t, err)
+
+ want := &CodeOfConduct{
+ Key: String("key"),
+ Name: String("name"),
+ URL: String("url"),
+ Body: String("body"),
+ }
+ if !cmp.Equal(want, coc) {
+ t.Errorf("returned %+v, want %+v", coc, want)
+ }
+
+ const methodName = "Get"
+ testBadOptions(t, methodName, func() (err error) {
+ _, _, err = client.CodesOfConduct.Get(ctx, "\n")
+ return err
+ })
+
+ testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
+ got, resp, err := client.CodesOfConduct.Get(ctx, "k")
+ if got != nil {
+ t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
+ }
+ return resp, err
+ })
+}
+
+func TestCodeOfConduct_Marshal(t *testing.T) {
+ testJSONMarshal(t, &CodeOfConduct{}, "{}")
+
+ a := &CodeOfConduct{
+ Name: String("name"),
+ Key: String("key"),
+ URL: String("url"),
+ Body: String("body"),
+ }
+
+ want := `{
+ "name": "name",
+ "key": "key",
+ "url": "url",
+ "body": "body"
+ }`
+
+ testJSONMarshal(t, a, want)
+}
diff --git a/github/emojis.go b/github/emojis.go
new file mode 100644
index 00000000000..15b57130b3b
--- /dev/null
+++ b/github/emojis.go
@@ -0,0 +1,37 @@
+// Copyright 2023 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+ "context"
+)
+
+// EmojisService provides access to emoji-related functions in the GitHub API.
+type EmojisService service
+
+// List returns the emojis available to use on GitHub.
+//
+// GitHub API docs: https://docs.github.com/rest/emojis/emojis#get-emojis
+func (s *EmojisService) List(ctx context.Context) (map[string]string, *Response, error) {
+ req, err := s.client.NewRequest("GET", "emojis", nil)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ var emoji map[string]string
+ resp, err := s.client.Do(ctx, req, &emoji)
+ if err != nil {
+ return nil, resp, err
+ }
+
+ return emoji, resp, nil
+}
+
+// ListEmojis
+// Deprecated: Use EmojisService.List instead
+func (c *Client) ListEmojis(ctx context.Context) (map[string]string, *Response, error) {
+ return c.Emojis.List(ctx)
+}
diff --git a/github/emojis_test.go b/github/emojis_test.go
new file mode 100644
index 00000000000..79c890e36d1
--- /dev/null
+++ b/github/emojis_test.go
@@ -0,0 +1,45 @@
+// Copyright 2023 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+ "context"
+ "fmt"
+ "net/http"
+ "testing"
+
+ "github.com/google/go-cmp/cmp"
+)
+
+func TestEmojisService_List(t *testing.T) {
+ client, mux, _, teardown := setup()
+ defer teardown()
+
+ mux.HandleFunc("/emojis", func(w http.ResponseWriter, r *http.Request) {
+ testMethod(t, r, "GET")
+ fmt.Fprint(w, `{"+1": "+1.png"}`)
+ })
+
+ ctx := context.Background()
+ emoji, _, err := client.ListEmojis(ctx)
+ if err != nil {
+ t.Errorf("List returned error: %v", err)
+ }
+
+ want := map[string]string{"+1": "+1.png"}
+ if !cmp.Equal(want, emoji) {
+ t.Errorf("List returned %+v, want %+v", emoji, want)
+ }
+
+ const methodName = "List"
+ testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
+ got, resp, err := client.Emojis.List(ctx)
+ if got != nil {
+ t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
+ }
+ return resp, err
+ })
+}
diff --git a/github/examples_test.go b/github/examples_test.go
index a2147bf417f..4aca86218fa 100644
--- a/github/examples_test.go
+++ b/github/examples_test.go
@@ -15,14 +15,14 @@ import (
"github.com/google/go-github/v55/github"
)
-func ExampleClient_Markdown() {
+func ExampleMarkdownService_Render() {
client := github.NewClient(nil)
input := "# heading #\n\nLink to issue #1"
opt := &github.MarkdownOptions{Mode: "gfm", Context: "google/go-github"}
ctx := context.Background()
- output, _, err := client.Markdown(ctx, input, opt)
+ output, _, err := client.Markdown.Render(ctx, input, opt)
if err != nil {
fmt.Println(err)
}
diff --git a/github/github.go b/github/github.go
index dace1184719..519f3f31a37 100644
--- a/github/github.go
+++ b/github/github.go
@@ -183,9 +183,11 @@ type Client struct {
Billing *BillingService
Checks *ChecksService
CodeScanning *CodeScanningService
+ CodesOfConduct *CodesOfConductService
Codespaces *CodespacesService
Dependabot *DependabotService
DependencyGraph *DependencyGraphService
+ Emojis *EmojisService
Enterprise *EnterpriseService
Gists *GistsService
Git *GitService
@@ -194,7 +196,9 @@ type Client struct {
IssueImport *IssueImportService
Issues *IssuesService
Licenses *LicensesService
+ Markdown *MarkdownService
Marketplace *MarketplaceService
+ Meta *MetaService
Migrations *MigrationService
Organizations *OrganizationsService
Projects *ProjectsService
@@ -401,8 +405,10 @@ func (c *Client) initialize() {
c.Checks = (*ChecksService)(&c.common)
c.CodeScanning = (*CodeScanningService)(&c.common)
c.Codespaces = (*CodespacesService)(&c.common)
+ c.CodesOfConduct = (*CodesOfConductService)(&c.common)
c.Dependabot = (*DependabotService)(&c.common)
c.DependencyGraph = (*DependencyGraphService)(&c.common)
+ c.Emojis = (*EmojisService)(&c.common)
c.Enterprise = (*EnterpriseService)(&c.common)
c.Gists = (*GistsService)(&c.common)
c.Git = (*GitService)(&c.common)
@@ -411,7 +417,9 @@ func (c *Client) initialize() {
c.IssueImport = (*IssueImportService)(&c.common)
c.Issues = (*IssuesService)(&c.common)
c.Licenses = (*LicensesService)(&c.common)
+ c.Markdown = (*MarkdownService)(&c.common)
c.Marketplace = &MarketplaceService{client: c}
+ c.Meta = (*MetaService)(&c.common)
c.Migrations = (*MigrationService)(&c.common)
c.Organizations = (*OrganizationsService)(&c.common)
c.Projects = (*ProjectsService)(&c.common)
diff --git a/github/markdown.go b/github/markdown.go
new file mode 100644
index 00000000000..48b445b3d85
--- /dev/null
+++ b/github/markdown.go
@@ -0,0 +1,67 @@
+// Copyright 2023 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+ "bytes"
+ "context"
+)
+
+// MarkdownService provides access to markdown-related functions in the GitHub API.
+type MarkdownService service
+
+// MarkdownOptions specifies optional parameters to the Render method.
+type MarkdownOptions struct {
+ // Mode identifies the rendering mode. Possible values are:
+ // markdown - render a document as plain Render, just like
+ // README files are rendered.
+ //
+ // gfm - to render a document as user-content, e.g. like user
+ // comments or issues are rendered. In GFM mode, hard line breaks are
+ // always taken into account, and issue and user mentions are linked
+ // accordingly.
+ //
+ // Default is "markdown".
+ Mode string
+
+ // Context identifies the repository context. Only taken into account
+ // when rendering as "gfm".
+ Context string
+}
+
+type markdownRenderRequest struct {
+ Text *string `json:"text,omitempty"`
+ Mode *string `json:"mode,omitempty"`
+ Context *string `json:"context,omitempty"`
+}
+
+// Render renders an arbitrary Render document.
+//
+// GitHub API docs: https://docs.github.com/rest/markdown/markdown#render-a-markdown-document
+func (s *MarkdownService) Render(ctx context.Context, text string, opts *MarkdownOptions) (string, *Response, error) {
+ request := &markdownRenderRequest{Text: String(text)}
+ if opts != nil {
+ if opts.Mode != "" {
+ request.Mode = String(opts.Mode)
+ }
+ if opts.Context != "" {
+ request.Context = String(opts.Context)
+ }
+ }
+
+ req, err := s.client.NewRequest("POST", "markdown", request)
+ if err != nil {
+ return "", nil, err
+ }
+
+ buf := new(bytes.Buffer)
+ resp, err := s.client.Do(ctx, req, buf)
+ if err != nil {
+ return "", resp, err
+ }
+
+ return buf.String(), resp, nil
+}
diff --git a/github/markdown_test.go b/github/markdown_test.go
new file mode 100644
index 00000000000..2b6e7eee48e
--- /dev/null
+++ b/github/markdown_test.go
@@ -0,0 +1,80 @@
+// Copyright 2023 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "net/http"
+ "testing"
+
+ "github.com/google/go-cmp/cmp"
+)
+
+func TestMarkdownService_Markdown(t *testing.T) {
+ client, mux, _, teardown := setup()
+ defer teardown()
+
+ input := &markdownRenderRequest{
+ Text: String("# text #"),
+ Mode: String("gfm"),
+ Context: String("google/go-github"),
+ }
+ mux.HandleFunc("/markdown", func(w http.ResponseWriter, r *http.Request) {
+ v := new(markdownRenderRequest)
+ assertNilError(t, json.NewDecoder(r.Body).Decode(v))
+
+ testMethod(t, r, "POST")
+ if !cmp.Equal(v, input) {
+ t.Errorf("Request body = %+v, want %+v", v, input)
+ }
+ fmt.Fprint(w, `
text
`)
+ })
+
+ ctx := context.Background()
+ md, _, err := client.Markdown.Render(ctx, "# text #", &MarkdownOptions{
+ Mode: "gfm",
+ Context: "google/go-github",
+ })
+ if err != nil {
+ t.Errorf("Render returned error: %v", err)
+ }
+
+ if want := "text
"; want != md {
+ t.Errorf("Render returned %+v, want %+v", md, want)
+ }
+
+ const methodName = "Render"
+ testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
+ got, resp, err := client.Markdown.Render(ctx, "# text #", &MarkdownOptions{
+ Mode: "gfm",
+ Context: "google/go-github",
+ })
+ if got != "" {
+ t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
+ }
+ return resp, err
+ })
+}
+
+func TestMarkdownRenderRequest_Marshal(t *testing.T) {
+ testJSONMarshal(t, &markdownRenderRequest{}, "{}")
+
+ a := &markdownRenderRequest{
+ Text: String("txt"),
+ Mode: String("mode"),
+ Context: String("ctx"),
+ }
+
+ want := `{
+ "text": "txt",
+ "mode": "mode",
+ "context": "ctx"
+ }`
+
+ testJSONMarshal(t, a, want)
+}
diff --git a/github/meta.go b/github/meta.go
new file mode 100644
index 00000000000..a4d9bac77b4
--- /dev/null
+++ b/github/meta.go
@@ -0,0 +1,146 @@
+// Copyright 2014 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+ "bytes"
+ "context"
+ "fmt"
+ "net/url"
+)
+
+// MetaService provides access to functions in the GitHub API that GitHub categorizes as "meta".
+type MetaService service
+
+// APIMeta represents metadata about the GitHub API.
+type APIMeta struct {
+ // An Array of IP addresses in CIDR format specifying the addresses
+ // that incoming service hooks will originate from on GitHub.com.
+ Hooks []string `json:"hooks,omitempty"`
+
+ // An Array of IP addresses in CIDR format specifying the Git servers
+ // for GitHub.com.
+ Git []string `json:"git,omitempty"`
+
+ // Whether authentication with username and password is supported.
+ // (GitHub Enterprise instances using CAS or OAuth for authentication
+ // will return false. Features like Basic Authentication with a
+ // username and password, sudo mode, and two-factor authentication are
+ // not supported on these servers.)
+ VerifiablePasswordAuthentication *bool `json:"verifiable_password_authentication,omitempty"`
+
+ // An array of IP addresses in CIDR format specifying the addresses
+ // which serve GitHub Pages websites.
+ Pages []string `json:"pages,omitempty"`
+
+ // An Array of IP addresses specifying the addresses that source imports
+ // will originate from on GitHub.com.
+ Importer []string `json:"importer,omitempty"`
+
+ // An array of IP addresses in CIDR format specifying the IP addresses
+ // GitHub Actions will originate from.
+ Actions []string `json:"actions,omitempty"`
+
+ // An array of IP addresses in CIDR format specifying the IP addresses
+ // Dependabot will originate from.
+ Dependabot []string `json:"dependabot,omitempty"`
+
+ // A map of algorithms to SSH key fingerprints.
+ SSHKeyFingerprints map[string]string `json:"ssh_key_fingerprints,omitempty"`
+
+ // An array of SSH keys.
+ SSHKeys []string `json:"ssh_keys,omitempty"`
+
+ // An array of IP addresses in CIDR format specifying the addresses
+ // which serve GitHub websites.
+ Web []string `json:"web,omitempty"`
+
+ // An array of IP addresses in CIDR format specifying the addresses
+ // which serve GitHub APIs.
+ API []string `json:"api,omitempty"`
+}
+
+// Get returns information about GitHub.com, the service. Or, if you access
+// this endpoint on your organization’s GitHub Enterprise installation, this
+// endpoint provides information about that installation.
+//
+// GitHub API docs: https://docs.github.com/rest/meta/meta#get-github-meta-information
+func (s *MetaService) Get(ctx context.Context) (*APIMeta, *Response, error) {
+ req, err := s.client.NewRequest("GET", "meta", nil)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ meta := new(APIMeta)
+ resp, err := s.client.Do(ctx, req, meta)
+ if err != nil {
+ return nil, resp, err
+ }
+
+ return meta, resp, nil
+}
+
+// APIMeta
+// Deprecated: Use MetaService.Get instead.
+func (c *Client) APIMeta(ctx context.Context) (*APIMeta, *Response, error) {
+ return c.Meta.Get(ctx)
+}
+
+// Octocat returns an ASCII art octocat with the specified message in a speech
+// bubble. If message is empty, a random zen phrase is used.
+//
+// GitHub API docs: https://docs.github.com/rest/meta/meta#get-octocat
+func (s *MetaService) Octocat(ctx context.Context, message string) (string, *Response, error) {
+ u := "octocat"
+ if message != "" {
+ u = fmt.Sprintf("%s?s=%s", u, url.QueryEscape(message))
+ }
+
+ req, err := s.client.NewRequest("GET", u, nil)
+ if err != nil {
+ return "", nil, err
+ }
+
+ buf := new(bytes.Buffer)
+ resp, err := s.client.Do(ctx, req, buf)
+ if err != nil {
+ return "", resp, err
+ }
+
+ return buf.String(), resp, nil
+}
+
+// Octocat
+// Deprecated: Use MetaService.Octocat instead.
+func (c *Client) Octocat(ctx context.Context, message string) (string, *Response, error) {
+ return c.Meta.Octocat(ctx, message)
+}
+
+// Zen returns a random line from The Zen of GitHub.
+//
+// See also: http://warpspire.com/posts/taste/
+//
+// GitHub API docs: https://docs.github.com/rest/meta/meta#get-the-zen-of-github
+func (s *MetaService) Zen(ctx context.Context) (string, *Response, error) {
+ req, err := s.client.NewRequest("GET", "zen", nil)
+ if err != nil {
+ return "", nil, err
+ }
+
+ buf := new(bytes.Buffer)
+ resp, err := s.client.Do(ctx, req, buf)
+ if err != nil {
+ return "", resp, err
+ }
+
+ return buf.String(), resp, nil
+}
+
+// Zen
+// Deprecated: Use MetaService.Zen instead.
+func (c *Client) Zen(ctx context.Context) (string, *Response, error) {
+ return c.Meta.Zen(ctx)
+}
diff --git a/github/meta_test.go b/github/meta_test.go
new file mode 100644
index 00000000000..c7b01e298ed
--- /dev/null
+++ b/github/meta_test.go
@@ -0,0 +1,155 @@
+// Copyright 2014 The go-github AUTHORS. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package github
+
+import (
+ "context"
+ "fmt"
+ "net/http"
+ "testing"
+
+ "github.com/google/go-cmp/cmp"
+)
+
+func TestAPIMeta_Marshal(t *testing.T) {
+ testJSONMarshal(t, &APIMeta{}, "{}")
+
+ a := &APIMeta{
+ Hooks: []string{"h"},
+ Git: []string{"g"},
+ VerifiablePasswordAuthentication: Bool(true),
+ Pages: []string{"p"},
+ Importer: []string{"i"},
+ Actions: []string{"a"},
+ Dependabot: []string{"d"},
+ SSHKeyFingerprints: map[string]string{"a": "f"},
+ SSHKeys: []string{"k"},
+ API: []string{"a"},
+ Web: []string{"w"},
+ }
+ want := `{
+ "hooks":["h"],
+ "git":["g"],
+ "verifiable_password_authentication":true,
+ "pages":["p"],
+ "importer":["i"],
+ "actions":["a"],
+ "dependabot":["d"],
+ "ssh_key_fingerprints":{"a":"f"},
+ "ssh_keys":["k"],
+ "api":["a"],
+ "web":["w"]
+ }`
+
+ testJSONMarshal(t, a, want)
+}
+
+func TestMetaService_Get(t *testing.T) {
+ client, mux, _, teardown := setup()
+ defer teardown()
+
+ mux.HandleFunc("/meta", func(w http.ResponseWriter, r *http.Request) {
+ testMethod(t, r, "GET")
+ fmt.Fprint(w, `{"web":["w"],"api":["a"],"hooks":["h"], "git":["g"], "pages":["p"], "importer":["i"], "actions":["a"], "dependabot":["d"], "verifiable_password_authentication": true}`)
+ })
+
+ ctx := context.Background()
+ meta, _, err := client.Meta.Get(ctx)
+ if err != nil {
+ t.Errorf("Get returned error: %v", err)
+ }
+
+ want := &APIMeta{
+ Hooks: []string{"h"},
+ Git: []string{"g"},
+ Pages: []string{"p"},
+ Importer: []string{"i"},
+ Actions: []string{"a"},
+ Dependabot: []string{"d"},
+ API: []string{"a"},
+ Web: []string{"w"},
+
+ VerifiablePasswordAuthentication: Bool(true),
+ }
+ if !cmp.Equal(want, meta) {
+ t.Errorf("Get returned %+v, want %+v", meta, want)
+ }
+
+ const methodName = "Get"
+ testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
+ got, resp, err := client.Meta.Get(ctx)
+ if got != nil {
+ t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
+ }
+ return resp, err
+ })
+}
+
+func TestMetaService_Octocat(t *testing.T) {
+ client, mux, _, teardown := setup()
+ defer teardown()
+
+ input := "input"
+ output := "sample text"
+
+ mux.HandleFunc("/octocat", func(w http.ResponseWriter, r *http.Request) {
+ testMethod(t, r, "GET")
+ testFormValues(t, r, values{"s": input})
+ w.Header().Set("Content-Type", "application/octocat-stream")
+ fmt.Fprint(w, output)
+ })
+
+ ctx := context.Background()
+ got, _, err := client.Meta.Octocat(ctx, input)
+ if err != nil {
+ t.Errorf("Octocat returned error: %v", err)
+ }
+
+ if want := output; got != want {
+ t.Errorf("Octocat returned %+v, want %+v", got, want)
+ }
+
+ const methodName = "Octocat"
+ testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
+ got, resp, err := client.Meta.Octocat(ctx, input)
+ if got != "" {
+ t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
+ }
+ return resp, err
+ })
+}
+
+func TestMetaService_Zen(t *testing.T) {
+ client, mux, _, teardown := setup()
+ defer teardown()
+
+ output := "sample text"
+
+ mux.HandleFunc("/zen", func(w http.ResponseWriter, r *http.Request) {
+ testMethod(t, r, "GET")
+ w.Header().Set("Content-Type", "text/plain;charset=utf-8")
+ fmt.Fprint(w, output)
+ })
+
+ ctx := context.Background()
+ got, _, err := client.Meta.Zen(ctx)
+ if err != nil {
+ t.Errorf("Zen returned error: %v", err)
+ }
+
+ if want := output; got != want {
+ t.Errorf("Zen returned %+v, want %+v", got, want)
+ }
+
+ const methodName = "Zen"
+ testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
+ got, resp, err := client.Meta.Zen(ctx)
+ if got != "" {
+ t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
+ }
+ return resp, err
+ })
+}
diff --git a/github/misc.go b/github/misc.go
deleted file mode 100644
index a01b716fa23..00000000000
--- a/github/misc.go
+++ /dev/null
@@ -1,247 +0,0 @@
-// Copyright 2014 The go-github AUTHORS. All rights reserved.
-//
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package github
-
-import (
- "bytes"
- "context"
- "fmt"
- "net/url"
-)
-
-// MarkdownOptions specifies optional parameters to the Markdown method.
-type MarkdownOptions struct {
- // Mode identifies the rendering mode. Possible values are:
- // markdown - render a document as plain Markdown, just like
- // README files are rendered.
- //
- // gfm - to render a document as user-content, e.g. like user
- // comments or issues are rendered. In GFM mode, hard line breaks are
- // always taken into account, and issue and user mentions are linked
- // accordingly.
- //
- // Default is "markdown".
- Mode string
-
- // Context identifies the repository context. Only taken into account
- // when rendering as "gfm".
- Context string
-}
-
-type markdownRequest struct {
- Text *string `json:"text,omitempty"`
- Mode *string `json:"mode,omitempty"`
- Context *string `json:"context,omitempty"`
-}
-
-// Markdown renders an arbitrary Markdown document.
-//
-// GitHub API docs: https://docs.github.com/en/rest/markdown/
-func (c *Client) Markdown(ctx context.Context, text string, opts *MarkdownOptions) (string, *Response, error) {
- request := &markdownRequest{Text: String(text)}
- if opts != nil {
- if opts.Mode != "" {
- request.Mode = String(opts.Mode)
- }
- if opts.Context != "" {
- request.Context = String(opts.Context)
- }
- }
-
- req, err := c.NewRequest("POST", "markdown", request)
- if err != nil {
- return "", nil, err
- }
-
- buf := new(bytes.Buffer)
- resp, err := c.Do(ctx, req, buf)
- if err != nil {
- return "", resp, err
- }
-
- return buf.String(), resp, nil
-}
-
-// ListEmojis returns the emojis available to use on GitHub.
-//
-// GitHub API docs: https://docs.github.com/en/rest/emojis/
-func (c *Client) ListEmojis(ctx context.Context) (map[string]string, *Response, error) {
- req, err := c.NewRequest("GET", "emojis", nil)
- if err != nil {
- return nil, nil, err
- }
-
- var emoji map[string]string
- resp, err := c.Do(ctx, req, &emoji)
- if err != nil {
- return nil, resp, err
- }
-
- return emoji, resp, nil
-}
-
-// CodeOfConduct represents a code of conduct.
-type CodeOfConduct struct {
- Name *string `json:"name,omitempty"`
- Key *string `json:"key,omitempty"`
- URL *string `json:"url,omitempty"`
- Body *string `json:"body,omitempty"`
-}
-
-func (c *CodeOfConduct) String() string {
- return Stringify(c)
-}
-
-// ListCodesOfConduct returns all codes of conduct.
-//
-// GitHub API docs: https://docs.github.com/en/rest/codes_of_conduct/#list-all-codes-of-conduct
-func (c *Client) ListCodesOfConduct(ctx context.Context) ([]*CodeOfConduct, *Response, error) {
- req, err := c.NewRequest("GET", "codes_of_conduct", nil)
- if err != nil {
- return nil, nil, err
- }
-
- // TODO: remove custom Accept header when this API fully launches.
- req.Header.Set("Accept", mediaTypeCodesOfConductPreview)
-
- var cs []*CodeOfConduct
- resp, err := c.Do(ctx, req, &cs)
- if err != nil {
- return nil, resp, err
- }
-
- return cs, resp, nil
-}
-
-// GetCodeOfConduct returns an individual code of conduct.
-//
-// https://docs.github.com/en/rest/codes_of_conduct/#get-an-individual-code-of-conduct
-func (c *Client) GetCodeOfConduct(ctx context.Context, key string) (*CodeOfConduct, *Response, error) {
- u := fmt.Sprintf("codes_of_conduct/%s", key)
- req, err := c.NewRequest("GET", u, nil)
- if err != nil {
- return nil, nil, err
- }
-
- // TODO: remove custom Accept header when this API fully launches.
- req.Header.Set("Accept", mediaTypeCodesOfConductPreview)
-
- coc := new(CodeOfConduct)
- resp, err := c.Do(ctx, req, coc)
- if err != nil {
- return nil, resp, err
- }
-
- return coc, resp, nil
-}
-
-// APIMeta represents metadata about the GitHub API.
-type APIMeta struct {
- // An Array of IP addresses in CIDR format specifying the addresses
- // that incoming service hooks will originate from on GitHub.com.
- Hooks []string `json:"hooks,omitempty"`
-
- // An Array of IP addresses in CIDR format specifying the Git servers
- // for GitHub.com.
- Git []string `json:"git,omitempty"`
-
- // Whether authentication with username and password is supported.
- // (GitHub Enterprise instances using CAS or OAuth for authentication
- // will return false. Features like Basic Authentication with a
- // username and password, sudo mode, and two-factor authentication are
- // not supported on these servers.)
- VerifiablePasswordAuthentication *bool `json:"verifiable_password_authentication,omitempty"`
-
- // An array of IP addresses in CIDR format specifying the addresses
- // which serve GitHub Pages websites.
- Pages []string `json:"pages,omitempty"`
-
- // An Array of IP addresses specifying the addresses that source imports
- // will originate from on GitHub.com.
- Importer []string `json:"importer,omitempty"`
-
- // An array of IP addresses in CIDR format specifying the IP addresses
- // GitHub Actions will originate from.
- Actions []string `json:"actions,omitempty"`
-
- // An array of IP addresses in CIDR format specifying the IP addresses
- // Dependabot will originate from.
- Dependabot []string `json:"dependabot,omitempty"`
-
- // A map of algorithms to SSH key fingerprints.
- SSHKeyFingerprints map[string]string `json:"ssh_key_fingerprints,omitempty"`
-
- // An array of SSH keys.
- SSHKeys []string `json:"ssh_keys,omitempty"`
-
- // An array of IP addresses in CIDR format specifying the addresses
- // which serve GitHub websites.
- Web []string `json:"web,omitempty"`
-
- // An array of IP addresses in CIDR format specifying the addresses
- // which serve GitHub APIs.
- API []string `json:"api,omitempty"`
-}
-
-// APIMeta returns information about GitHub.com, the service. Or, if you access
-// this endpoint on your organization’s GitHub Enterprise installation, this
-// endpoint provides information about that installation.
-//
-// GitHub API docs: https://docs.github.com/en/rest/meta#get-github-meta-information
-func (c *Client) APIMeta(ctx context.Context) (*APIMeta, *Response, error) {
- req, err := c.NewRequest("GET", "meta", nil)
- if err != nil {
- return nil, nil, err
- }
-
- meta := new(APIMeta)
- resp, err := c.Do(ctx, req, meta)
- if err != nil {
- return nil, resp, err
- }
-
- return meta, resp, nil
-}
-
-// Octocat returns an ASCII art octocat with the specified message in a speech
-// bubble. If message is empty, a random zen phrase is used.
-func (c *Client) Octocat(ctx context.Context, message string) (string, *Response, error) {
- u := "octocat"
- if message != "" {
- u = fmt.Sprintf("%s?s=%s", u, url.QueryEscape(message))
- }
-
- req, err := c.NewRequest("GET", u, nil)
- if err != nil {
- return "", nil, err
- }
-
- buf := new(bytes.Buffer)
- resp, err := c.Do(ctx, req, buf)
- if err != nil {
- return "", resp, err
- }
-
- return buf.String(), resp, nil
-}
-
-// Zen returns a random line from The Zen of GitHub.
-//
-// see also: http://warpspire.com/posts/taste/
-func (c *Client) Zen(ctx context.Context) (string, *Response, error) {
- req, err := c.NewRequest("GET", "zen", nil)
- if err != nil {
- return "", nil, err
- }
-
- buf := new(bytes.Buffer)
- resp, err := c.Do(ctx, req, buf)
- if err != nil {
- return "", resp, err
- }
-
- return buf.String(), resp, nil
-}
diff --git a/github/misc_test.go b/github/misc_test.go
deleted file mode 100644
index 45c99893812..00000000000
--- a/github/misc_test.go
+++ /dev/null
@@ -1,356 +0,0 @@
-// Copyright 2014 The go-github AUTHORS. All rights reserved.
-//
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package github
-
-import (
- "context"
- "encoding/json"
- "fmt"
- "net/http"
- "testing"
-
- "github.com/google/go-cmp/cmp"
-)
-
-func TestMarkdown(t *testing.T) {
- client, mux, _, teardown := setup()
- defer teardown()
-
- input := &markdownRequest{
- Text: String("# text #"),
- Mode: String("gfm"),
- Context: String("google/go-github"),
- }
- mux.HandleFunc("/markdown", func(w http.ResponseWriter, r *http.Request) {
- v := new(markdownRequest)
- assertNilError(t, json.NewDecoder(r.Body).Decode(v))
-
- testMethod(t, r, "POST")
- if !cmp.Equal(v, input) {
- t.Errorf("Request body = %+v, want %+v", v, input)
- }
- fmt.Fprint(w, `text
`)
- })
-
- ctx := context.Background()
- md, _, err := client.Markdown(ctx, "# text #", &MarkdownOptions{
- Mode: "gfm",
- Context: "google/go-github",
- })
- if err != nil {
- t.Errorf("Markdown returned error: %v", err)
- }
-
- if want := "text
"; want != md {
- t.Errorf("Markdown returned %+v, want %+v", md, want)
- }
-
- const methodName = "Markdown"
- testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
- got, resp, err := client.Markdown(ctx, "# text #", &MarkdownOptions{
- Mode: "gfm",
- Context: "google/go-github",
- })
- if got != "" {
- t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
- }
- return resp, err
- })
-}
-
-func TestListEmojis(t *testing.T) {
- client, mux, _, teardown := setup()
- defer teardown()
-
- mux.HandleFunc("/emojis", func(w http.ResponseWriter, r *http.Request) {
- testMethod(t, r, "GET")
- fmt.Fprint(w, `{"+1": "+1.png"}`)
- })
-
- ctx := context.Background()
- emoji, _, err := client.ListEmojis(ctx)
- if err != nil {
- t.Errorf("ListEmojis returned error: %v", err)
- }
-
- want := map[string]string{"+1": "+1.png"}
- if !cmp.Equal(want, emoji) {
- t.Errorf("ListEmojis returned %+v, want %+v", emoji, want)
- }
-
- const methodName = "ListEmojis"
- testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
- got, resp, err := client.ListEmojis(ctx)
- if got != nil {
- t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
- }
- return resp, err
- })
-}
-
-func TestListCodesOfConduct(t *testing.T) {
- client, mux, _, teardown := setup()
- defer teardown()
-
- mux.HandleFunc("/codes_of_conduct", func(w http.ResponseWriter, r *http.Request) {
- testMethod(t, r, "GET")
- testHeader(t, r, "Accept", mediaTypeCodesOfConductPreview)
- fmt.Fprint(w, `[{
- "key": "key",
- "name": "name",
- "url": "url"}
- ]`)
- })
-
- ctx := context.Background()
- cs, _, err := client.ListCodesOfConduct(ctx)
- if err != nil {
- t.Errorf("ListCodesOfConduct returned error: %v", err)
- }
-
- want := []*CodeOfConduct{
- {
- Key: String("key"),
- Name: String("name"),
- URL: String("url"),
- }}
- if !cmp.Equal(want, cs) {
- t.Errorf("ListCodesOfConduct returned %+v, want %+v", cs, want)
- }
-
- const methodName = "ListCodesOfConduct"
- testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
- got, resp, err := client.ListCodesOfConduct(ctx)
- if got != nil {
- t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
- }
- return resp, err
- })
-}
-
-func TestGetCodeOfConduct(t *testing.T) {
- client, mux, _, teardown := setup()
- defer teardown()
-
- mux.HandleFunc("/codes_of_conduct/k", func(w http.ResponseWriter, r *http.Request) {
- testMethod(t, r, "GET")
- testHeader(t, r, "Accept", mediaTypeCodesOfConductPreview)
- fmt.Fprint(w, `{
- "key": "key",
- "name": "name",
- "url": "url",
- "body": "body"}`,
- )
- })
-
- ctx := context.Background()
- coc, _, err := client.GetCodeOfConduct(ctx, "k")
- if err != nil {
- t.Errorf("ListCodesOfConduct returned error: %v", err)
- }
-
- want := &CodeOfConduct{
- Key: String("key"),
- Name: String("name"),
- URL: String("url"),
- Body: String("body"),
- }
- if !cmp.Equal(want, coc) {
- t.Errorf("GetCodeOfConductByKey returned %+v, want %+v", coc, want)
- }
-
- const methodName = "GetCodeOfConduct"
- testBadOptions(t, methodName, func() (err error) {
- _, _, err = client.GetCodeOfConduct(ctx, "\n")
- return err
- })
-
- testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
- got, resp, err := client.GetCodeOfConduct(ctx, "k")
- if got != nil {
- t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
- }
- return resp, err
- })
-}
-
-func TestAPIMeta_Marshal(t *testing.T) {
- testJSONMarshal(t, &APIMeta{}, "{}")
-
- a := &APIMeta{
- Hooks: []string{"h"},
- Git: []string{"g"},
- VerifiablePasswordAuthentication: Bool(true),
- Pages: []string{"p"},
- Importer: []string{"i"},
- Actions: []string{"a"},
- Dependabot: []string{"d"},
- SSHKeyFingerprints: map[string]string{"a": "f"},
- SSHKeys: []string{"k"},
- API: []string{"a"},
- Web: []string{"w"},
- }
- want := `{
- "hooks":["h"],
- "git":["g"],
- "verifiable_password_authentication":true,
- "pages":["p"],
- "importer":["i"],
- "actions":["a"],
- "dependabot":["d"],
- "ssh_key_fingerprints":{"a":"f"},
- "ssh_keys":["k"],
- "api":["a"],
- "web":["w"]
- }`
-
- testJSONMarshal(t, a, want)
-}
-
-func TestAPIMeta(t *testing.T) {
- client, mux, _, teardown := setup()
- defer teardown()
-
- mux.HandleFunc("/meta", func(w http.ResponseWriter, r *http.Request) {
- testMethod(t, r, "GET")
- fmt.Fprint(w, `{"web":["w"],"api":["a"],"hooks":["h"], "git":["g"], "pages":["p"], "importer":["i"], "actions":["a"], "dependabot":["d"], "verifiable_password_authentication": true}`)
- })
-
- ctx := context.Background()
- meta, _, err := client.APIMeta(ctx)
- if err != nil {
- t.Errorf("APIMeta returned error: %v", err)
- }
-
- want := &APIMeta{
- Hooks: []string{"h"},
- Git: []string{"g"},
- Pages: []string{"p"},
- Importer: []string{"i"},
- Actions: []string{"a"},
- Dependabot: []string{"d"},
- API: []string{"a"},
- Web: []string{"w"},
-
- VerifiablePasswordAuthentication: Bool(true),
- }
- if !cmp.Equal(want, meta) {
- t.Errorf("APIMeta returned %+v, want %+v", meta, want)
- }
-
- const methodName = "APIMeta"
- testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
- got, resp, err := client.APIMeta(ctx)
- if got != nil {
- t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
- }
- return resp, err
- })
-}
-
-func TestOctocat(t *testing.T) {
- client, mux, _, teardown := setup()
- defer teardown()
-
- input := "input"
- output := "sample text"
-
- mux.HandleFunc("/octocat", func(w http.ResponseWriter, r *http.Request) {
- testMethod(t, r, "GET")
- testFormValues(t, r, values{"s": input})
- w.Header().Set("Content-Type", "application/octocat-stream")
- fmt.Fprint(w, output)
- })
-
- ctx := context.Background()
- got, _, err := client.Octocat(ctx, input)
- if err != nil {
- t.Errorf("Octocat returned error: %v", err)
- }
-
- if want := output; got != want {
- t.Errorf("Octocat returned %+v, want %+v", got, want)
- }
-
- const methodName = "Octocat"
- testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
- got, resp, err := client.Octocat(ctx, input)
- if got != "" {
- t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
- }
- return resp, err
- })
-}
-
-func TestZen(t *testing.T) {
- client, mux, _, teardown := setup()
- defer teardown()
-
- output := "sample text"
-
- mux.HandleFunc("/zen", func(w http.ResponseWriter, r *http.Request) {
- testMethod(t, r, "GET")
- w.Header().Set("Content-Type", "text/plain;charset=utf-8")
- fmt.Fprint(w, output)
- })
-
- ctx := context.Background()
- got, _, err := client.Zen(ctx)
- if err != nil {
- t.Errorf("Zen returned error: %v", err)
- }
-
- if want := output; got != want {
- t.Errorf("Zen returned %+v, want %+v", got, want)
- }
-
- const methodName = "Zen"
- testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
- got, resp, err := client.Zen(ctx)
- if got != "" {
- t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
- }
- return resp, err
- })
-}
-
-func TestMarkdownRequest_Marshal(t *testing.T) {
- testJSONMarshal(t, &markdownRequest{}, "{}")
-
- a := &markdownRequest{
- Text: String("txt"),
- Mode: String("mode"),
- Context: String("ctx"),
- }
-
- want := `{
- "text": "txt",
- "mode": "mode",
- "context": "ctx"
- }`
-
- testJSONMarshal(t, a, want)
-}
-
-func TestCodeOfConduct_Marshal(t *testing.T) {
- testJSONMarshal(t, &CodeOfConduct{}, "{}")
-
- a := &CodeOfConduct{
- Name: String("name"),
- Key: String("key"),
- URL: String("url"),
- Body: String("body"),
- }
-
- want := `{
- "name": "name",
- "key": "key",
- "url": "url",
- "body": "body"
- }`
-
- testJSONMarshal(t, a, want)
-}
diff --git a/test/integration/misc_test.go b/test/integration/misc_test.go
index e0cee29bf07..6ffb163fdcd 100644
--- a/test/integration/misc_test.go
+++ b/test/integration/misc_test.go
@@ -15,32 +15,32 @@ import (
)
func TestEmojis(t *testing.T) {
- emoji, _, err := client.ListEmojis(context.Background())
+ emoji, _, err := client.Emojis.List(context.Background())
if err != nil {
- t.Fatalf("ListEmojis returned error: %v", err)
+ t.Fatalf("List returned error: %v", err)
}
if len(emoji) == 0 {
- t.Errorf("ListEmojis returned no emojis")
+ t.Errorf("List returned no emojis")
}
if _, ok := emoji["+1"]; !ok {
- t.Errorf("ListEmojis missing '+1' emoji")
+ t.Errorf("List missing '+1' emoji")
}
}
func TestAPIMeta(t *testing.T) {
- meta, _, err := client.APIMeta(context.Background())
+ meta, _, err := client.Meta.Get(context.Background())
if err != nil {
- t.Fatalf("APIMeta returned error: %v", err)
+ t.Fatalf("Get returned error: %v", err)
}
if len(meta.Hooks) == 0 {
- t.Errorf("APIMeta returned no hook addresses")
+ t.Errorf("Get returned no hook addresses")
}
if len(meta.Git) == 0 {
- t.Errorf("APIMeta returned no git addresses")
+ t.Errorf("Get returned no git addresses")
}
if !*meta.VerifiablePasswordAuthentication {