Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use metadata to reconcile go-github with GitHub's OpenAPI descriptions #2919

Merged
merged 38 commits into from Nov 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
3083413
update doc urls
WillAbides Sep 8, 2023
11baddf
use metadata.yaml to reconcile source with OpenAPI descriptions
WillAbides Sep 8, 2023
462108e
trigger
WillAbides Sep 8, 2023
67d827b
minor refactor
WillAbides Sep 8, 2023
73e2220
go fmt
WillAbides Sep 8, 2023
d6360bd
update tools module
WillAbides Sep 8, 2023
7f4b553
revert script dir
WillAbides Sep 8, 2023
4aa1c11
restore gen-accessors.go and gen-stringify-test.go
WillAbides Sep 8, 2023
a1ba628
restore .gitignore
WillAbides Sep 8, 2023
7b7df59
go 1.20
WillAbides Sep 8, 2023
fa02527
update tooling and undocumented methods
WillAbides Sep 9, 2023
d855286
leave existing doc links in place
WillAbides Sep 10, 2023
43c3216
restore github dir
WillAbides Sep 10, 2023
ae5fd84
update regex
WillAbides Sep 10, 2023
000231c
update-urls
WillAbides Sep 10, 2023
e21c51b
include enterprise-server version in doc links
WillAbides Sep 10, 2023
1bf8fd6
add copyright notice
WillAbides Sep 10, 2023
0137f71
use ast in update-urls
WillAbides Sep 15, 2023
0f657ae
use ast in getServiceMethodsFromFile
WillAbides Sep 15, 2023
dfb3c8c
go fmt
WillAbides Sep 15, 2023
9a85b69
Use enterprise-cloud links
WillAbides Sep 15, 2023
63190e9
Merge branch 'master' into meta11
WillAbides Oct 14, 2023
b0ad415
refactor
WillAbides Oct 14, 2023
fcd94b3
fix comment
WillAbides Oct 14, 2023
cf4795b
start on CONTRIBUTING.md
WillAbides Oct 15, 2023
8e8cef8
rename metadata sub-commands
WillAbides Oct 15, 2023
b9b5e6f
make canonize more flexible
WillAbides Oct 15, 2023
b2b2e71
use //meta:operation directives
WillAbides Oct 19, 2023
54443b7
Merge branch 'master' into meta4
WillAbides Oct 19, 2023
ffd73b6
revert accidental test changes
WillAbides Oct 19, 2023
a2bff7b
Apply suggestions from code review
WillAbides Oct 19, 2023
4183cf5
Apply suggestions from code review
WillAbides Oct 19, 2023
b6d3af6
return AtoI errors
WillAbides Oct 19, 2023
6e4d263
update CONTRIBUTING.md
WillAbides Oct 19, 2023
0204952
Merge branch 'master' into meta4
WillAbides Oct 23, 2023
66a2035
add meta for RateLimitService.Get
WillAbides Oct 23, 2023
d72f064
Merge branch 'master' into meta4
WillAbides Nov 3, 2023
4a065a9
fix .golangci.yml exclusion for tools
WillAbides Nov 3, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions .codecov.yml
Expand Up @@ -3,5 +3,5 @@ ignore:
- "github/github-accessors.go"
# ignore experimental scrape package
- "scrape"
# ignore update-urls
- "update-urls"
# ignore tools
- "tools"
2 changes: 1 addition & 1 deletion .github/dependabot.yml
Expand Up @@ -9,7 +9,7 @@ updates:
schedule:
interval: weekly
- package-ecosystem: gomod
directory: update-urls
directory: tools
schedule:
interval: weekly
- package-ecosystem: github-actions
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/linter.yml
Expand Up @@ -14,3 +14,6 @@ jobs:
go-version: 1.x
cache-dependency-path: "**/go.sum"
- run: script/lint.sh
env:
CHECK_GITHUB_OPENAPI: 1
GITHUB_TOKEN: ${{ github.token }}
2 changes: 1 addition & 1 deletion .golangci.yml
Expand Up @@ -50,4 +50,4 @@ issues:
# We don't care about file inclusion via variable in examples or internal tools.
- linters: [ gosec ]
text: 'G304: Potential file inclusion via variable'
path: '^(example|update-urls)\/'
path: '^(example|tools)\/'
121 changes: 114 additions & 7 deletions CONTRIBUTING.md
@@ -1,10 +1,9 @@
# How to contribute #
# How to contribute

We'd love to accept your patches and contributions to this project. There are
a just a few small guidelines you need to follow.


## Contributor License Agreement ##
## Contributor License Agreement

Contributions to any Google project must be accompanied by a Contributor
License Agreement. This is not a copyright **assignment**, it simply gives
Expand All @@ -17,7 +16,7 @@ You generally only need to submit a CLA once, so if you've already submitted one
again.


## Reporting issues ##
## Reporting issues

Bugs, feature requests, and development-related questions should be directed to
our [GitHub issue tracker](https://github.com/google/go-github/issues). If
Expand All @@ -29,7 +28,7 @@ how the requested feature would help you do that.
Security related bugs can either be reported in the issue tracker, or if they
are more sensitive, emailed to <opensource@google.com>.

## Submitting a patch ##
## Submitting a patch

1. It's generally best to start by opening a new issue describing the bug or
feature you're intending to fix. Even if you think it's relatively minor,
Expand Down Expand Up @@ -73,7 +72,112 @@ are more sensitive, emailed to <opensource@google.com>.
[pull request]: https://help.github.com/articles/creating-a-pull-request
[monitored by codecov.io]: https://codecov.io/gh/google/go-github

## Scripts ##
## Code Comments

Every exported method needs to have code comments that follow
[Go Doc Comments][]. A typical method's comments will look like this:

```go
// Get fetches a repository.
//
// GitHub API docs: https://docs.github.com/rest/repos/repos#get-a-repository
//
//meta:operation GET /repos/{owner}/{repo}
func (s *RepositoriesService) Get(ctx context.Context, owner, repo string) (*Repository, *Response, error) {
u := fmt.Sprintf("repos/%v/%v", owner, repo)
req, err := s.client.NewRequest("GET", u, nil)
...
}
```

The first line is the name of the method followed by a short description. This
could also be a longer description if needed, but there is no need to repeat any
details that are documented in GitHub's documentation because users are expected
to follow the documentation links to learn more.

After the description comes a link to the GitHub API documentation. This is
added or fixed automatically when you run `script/generate.sh`, so you won't
need to set this yourself.

Finally, the `//meta:operation` comment is a directive to the code generator
that maps the method to the corresponding OpenAPI operation. Once again, there
can be multiple directives for methods that call multiple
endpoints. `script/generate.sh` will normalize these directives for you, so if
you are adding a new method you can use the pattern from the `u := fmt.Sprintf`
line instead of looking up what the url parameters are called in the OpenAPI
description.

[Go Doc Comments]: https://go.dev/doc/comment

## Metadata

GitHub publishes [OpenAPI descriptions of their API][]. We use these
descriptions to keep documentation links up to date and to keep track of which
methods call which endpoints via the `//meta:operation` comments described
above. GitHub's descriptions are far too large to keep in this repository or to
pull down every time we generate code, so we keep only the metadata we need
in `openapi_operations.yaml`.

### openapi_operations.yaml

Most contributors won't need to interact with `openapi_operations.yaml`, but it
may be useful to know what it is. Its sections are:

- `openapi_operations` - is the metadata that comes from GitHub's OpenAPI
descriptions. It is generated by `script/metadata.sh update-openapi` and
should not be edited by hand. In the rare case where it needs to be
overridden, use the `operation_overrides` section instead.

An operation consists of `name`, `documentation_url`,
and `openapi_files`. `openapi_files` is the list of files where the operation
is described. In order or preference, values can be "api.github.com.json" for
operations available on the free plan, "ghec.json" for operations available on
GitHub Enterprise Cloud or "ghes-<version>.json" for operations available on
GitHub Enterprise Server. When an operation is described in multiple ghes
files, only the most recent version is included. `documentation_url` is the
URL that should be linked from godoc. It is the documentation link found in
the first file listed in `openapi_files`.

- `openapi_commit` - is the git commit that `script/metadata.sh update-openapi`
saw when it last updated `openapi_operations`. It is not necessarily the most
recent commit seen because `update-openapi` doesn't update the file when
there are no changes to `openapi_operations`.

- `operations` - contains manually added metadata that is not in GitHub's
OpenAPI descriptions. There are only a few of these. Some have
documentation_urls that point to relevant GitHub documentation that is not in
the OpenAPI descriptions. Others have no documentation_url and result in a
note in the generated code that the documentation is missing.

- `operation_overrides` - is where we override the documentation_url for
operations where the link in the OpenAPI descriptions is wrong.

### tools/metadata

The `tools/metadata` package is a command-line tool for working with metadata.
In a typical workflow, you won't use it directly, but you will use it indirectly
through `script/generate.sh` and `script/lint.sh`.

Its subcommands are:

- `update-openapi` - updates `openapi_operations.yaml` with the latest
information from GitHub's OpenAPI descriptions. With `--validate` it will
validate that the descriptions are correct as of the commit
in `openapi_commit`. `update-openapi --validate` is called
by `script/lint.sh`.

- `update-go` - updates Go files with documentation URLs and formats comments.
It is used by `script/generate.sh`.

- `format` - formats whitespace in `openapi_operations.yaml` and sorts its
arrays. It is used by `script/fmt.sh`.

- `unused` - lists operations from `openapi_operations.yaml` that are not mapped
from any methods.

[OpenAPI descriptions of their API]: https://github.com/github/rest-api-description

## Scripts

The `script` directory has shell scripts that help with common development
tasks.
Expand All @@ -86,6 +190,9 @@ tasks.
**script/lint.sh** runs linters on the project and checks generated files are
current.

**script/metadata.sh** runs `tools/metadata`. See the [Metadata](#metadata)
section for more information.

**script/test.sh** runs tests on all modules.

## Other notes on code organization ##
Expand All @@ -104,7 +211,7 @@ defined at <https://docs.github.com/en/rest/webhooks/repos> live in
[repos_hooks.go]: https://github.com/google/go-github/blob/master/github/repos_hooks.go


## Maintainer's Guide ##
## Maintainer's Guide

(These notes are mostly only for people merging in pull requests.)

Expand Down
2 changes: 1 addition & 1 deletion github/actions.go
Expand Up @@ -8,5 +8,5 @@ package github
// ActionsService handles communication with the actions related
// methods of the GitHub API.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/
// GitHub API docs: https://docs.github.com/rest/actions/
type ActionsService service
26 changes: 18 additions & 8 deletions github/actions_artifacts.go
Expand Up @@ -14,7 +14,7 @@ import (

// ArtifactWorkflowRun represents a GitHub artifact's workflow run.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/artifacts
// GitHub API docs: https://docs.github.com/rest/actions/artifacts
type ArtifactWorkflowRun struct {
ID *int64 `json:"id,omitempty"`
RepositoryID *int64 `json:"repository_id,omitempty"`
Expand All @@ -27,7 +27,7 @@ type ArtifactWorkflowRun struct {
// data between jobs in a workflow and provide storage for data
// once a workflow is complete.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/artifacts
// GitHub API docs: https://docs.github.com/rest/actions/artifacts
type Artifact struct {
ID *int64 `json:"id,omitempty"`
NodeID *string `json:"node_id,omitempty"`
Expand All @@ -44,15 +44,17 @@ type Artifact struct {

// ArtifactList represents a list of GitHub artifacts.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/artifacts#artifacts
// GitHub API docs: https://docs.github.com/rest/actions/artifacts#artifacts
type ArtifactList struct {
TotalCount *int64 `json:"total_count,omitempty"`
Artifacts []*Artifact `json:"artifacts,omitempty"`
}

// ListArtifacts lists all artifacts that belong to a repository.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/artifacts#list-artifacts-for-a-repository
// GitHub API docs: https://docs.github.com/rest/actions/artifacts#list-artifacts-for-a-repository
//
//meta:operation GET /repos/{owner}/{repo}/actions/artifacts
func (s *ActionsService) ListArtifacts(ctx context.Context, owner, repo string, opts *ListOptions) (*ArtifactList, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/artifacts", owner, repo)
u, err := addOptions(u, opts)
Expand All @@ -76,7 +78,9 @@ func (s *ActionsService) ListArtifacts(ctx context.Context, owner, repo string,

// ListWorkflowRunArtifacts lists all artifacts that belong to a workflow run.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/artifacts#list-workflow-run-artifacts
// GitHub API docs: https://docs.github.com/rest/actions/artifacts#list-workflow-run-artifacts
//
//meta:operation GET /repos/{owner}/{repo}/actions/runs/{run_id}/artifacts
func (s *ActionsService) ListWorkflowRunArtifacts(ctx context.Context, owner, repo string, runID int64, opts *ListOptions) (*ArtifactList, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/artifacts", owner, repo, runID)
u, err := addOptions(u, opts)
Expand All @@ -100,7 +104,9 @@ func (s *ActionsService) ListWorkflowRunArtifacts(ctx context.Context, owner, re

// GetArtifact gets a specific artifact for a workflow run.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/artifacts#get-an-artifact
// GitHub API docs: https://docs.github.com/rest/actions/artifacts#get-an-artifact
//
//meta:operation GET /repos/{owner}/{repo}/actions/artifacts/{artifact_id}
func (s *ActionsService) GetArtifact(ctx context.Context, owner, repo string, artifactID int64) (*Artifact, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/artifacts/%v", owner, repo, artifactID)

Expand All @@ -120,7 +126,9 @@ func (s *ActionsService) GetArtifact(ctx context.Context, owner, repo string, ar

// DownloadArtifact gets a redirect URL to download an archive for a repository.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/artifacts#download-an-artifact
// GitHub API docs: https://docs.github.com/rest/actions/artifacts#download-an-artifact
//
//meta:operation GET /repos/{owner}/{repo}/actions/artifacts/{artifact_id}/{archive_format}
func (s *ActionsService) DownloadArtifact(ctx context.Context, owner, repo string, artifactID int64, maxRedirects int) (*url.URL, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/artifacts/%v/zip", owner, repo, artifactID)

Expand All @@ -144,7 +152,9 @@ func (s *ActionsService) DownloadArtifact(ctx context.Context, owner, repo strin

// DeleteArtifact deletes a workflow run artifact.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/artifacts#delete-an-artifact
// GitHub API docs: https://docs.github.com/rest/actions/artifacts#delete-an-artifact
//
//meta:operation DELETE /repos/{owner}/{repo}/actions/artifacts/{artifact_id}
func (s *ActionsService) DeleteArtifact(ctx context.Context, owner, repo string, artifactID int64) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/artifacts/%v", owner, repo, artifactID)

Expand Down