diff --git a/docs/api-contract.md b/docs/api-contract.md index 4a11a3e..ecf1098 100644 --- a/docs/api-contract.md +++ b/docs/api-contract.md @@ -182,6 +182,7 @@ Coverage notes: rows list direct tests when a symbol is named in test names or r | method | RepoService.AcceptTransfer | `func (s *RepoService) AcceptTransfer(ctx context.Context, owner, repo string) error` | AcceptTransfer accepts a pending repository transfer. | No direct tests. | | method | RepoService.Fork | `func (s *RepoService) Fork(ctx context.Context, owner, repo, org string) (*types.Repository, error)` | Fork forks a repository. If org is non-empty, forks into that organisation. | `TestRepoService_Good_Fork` | | method | RepoService.GetArchive | `func (s *RepoService) GetArchive(ctx context.Context, owner, repo, archive string) ([]byte, error)` | GetArchive returns a repository archive as raw bytes. | `TestRepoService_GetArchive_Good` | +| method | RepoService.GetSigningKey | `func (s *RepoService) GetSigningKey(ctx context.Context, owner, repo string) (string, error)` | GetSigningKey returns the repository signing key as ASCII-armoured text. | `TestRepoService_GetSigningKey_Good` | | method | RepoService.GetNewPinAllowed | `func (s *RepoService) GetNewPinAllowed(ctx context.Context, owner, repo string) (*types.NewIssuePinsAllowed, error)` | GetNewPinAllowed returns whether new issue pins are allowed for a repository. | `TestRepoService_GetNewPinAllowed_Good` | | method | RepoService.IterOrgRepos | `func (s *RepoService) IterOrgRepos(ctx context.Context, org string) iter.Seq2[types.Repository, error]` | IterOrgRepos returns an iterator over all repositories for an organisation. | No direct tests. | | method | RepoService.IterUserRepos | `func (s *RepoService) IterUserRepos(ctx context.Context) iter.Seq2[types.Repository, error]` | IterUserRepos returns an iterator over all repositories for the authenticated user. | No direct tests. | diff --git a/repos.go b/repos.go index be8d8e3..12ba612 100644 --- a/repos.go +++ b/repos.go @@ -154,6 +154,16 @@ func (s *RepoService) GetRawFile(ctx context.Context, owner, repo, filepath stri return s.client.GetRaw(ctx, path) } +// GetSigningKey returns the repository signing key as ASCII-armoured text. +func (s *RepoService) GetSigningKey(ctx context.Context, owner, repo string) (string, error) { + path := ResolvePath("/api/v1/repos/{owner}/{repo}/signing-key.gpg", pathParams("owner", owner, "repo", repo)) + data, err := s.client.GetRaw(ctx, path) + if err != nil { + return "", err + } + return string(data), nil +} + // ListIssueTemplates returns all issue templates available for a repository. func (s *RepoService) ListIssueTemplates(ctx context.Context, owner, repo string) ([]types.IssueTemplate, error) { path := ResolvePath("/api/v1/repos/{owner}/{repo}/issue_templates", pathParams("owner", owner, "repo", repo)) diff --git a/repos_test.go b/repos_test.go index 65aae91..fceffda 100644 --- a/repos_test.go +++ b/repos_test.go @@ -426,6 +426,32 @@ func TestRepoService_ListSubscribers_Good(t *testing.T) { } } +func TestRepoService_GetSigningKey_Good(t *testing.T) { + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodGet { + t.Errorf("expected GET, got %s", r.Method) + } + if r.URL.Path != "/api/v1/repos/core/go-forge/signing-key.gpg" { + t.Errorf("wrong path: %s", r.URL.Path) + http.NotFound(w, r) + return + } + w.Header().Set("Content-Type", "text/plain") + w.Write([]byte("-----BEGIN PGP PUBLIC KEY BLOCK-----\n...")) + })) + defer srv.Close() + + f := NewForge(srv.URL, "tok") + key, err := f.Repos.GetSigningKey(context.Background(), "core", "go-forge") + if err != nil { + t.Fatal(err) + } + want := "-----BEGIN PGP PUBLIC KEY BLOCK-----\n..." + if key != want { + t.Fatalf("got %q, want %q", key, want) + } +} + func TestRepoService_ListAssignees_Good(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet {