oxidecomputer / third-party-api-clients

A place for keeping all our generated third party API clients.
https://docs.rs/octorust
MIT License
132 stars 55 forks source link

Repos::get_collaborator_permission_level() return model is not correct #89

Open samkearney opened 9 months ago

samkearney commented 9 months ago

The model returned from Repos::get_collaborator_permission_level() looks like (some attributes omitted):

pub struct RepositoryCollaboratorPermission {
    pub permission: String,
    pub user: Option<SimpleUser>,
}

pub struct SimpleUser {
    pub avatar_url: String,
    pub email: String,
    pub events_url: String,
    pub followers_url: String,
    pub following_url: String,
    pub gists_url: String,
    pub gravatar_id: String,
    pub html_url: String,
    pub id: i64,
    pub login: String,
    pub name: String,
    pub node_id: String,
    pub organizations_url: String,
    pub received_events_url: String,
    pub repos_url: String,
    pub site_admin: bool,
    pub starred_at: String,
    pub starred_url: String,
    pub subscriptions_url: String,
    pub type_: String,
    pub url: String,
}

Where the response schema from the API documentation for the endpoint looks like:

Expand Me

```json { "title": "Repository Collaborator Permission", "description": "Repository Collaborator Permission", "type": "object", "properties": { "permission": { "type": "string" }, "role_name": { "type": "string", "examples": [ "admin" ] }, "user": { "anyOf": [ { "type": "null" }, { "title": "Collaborator", "description": "Collaborator", "type": "object", "properties": { "login": { "type": "string", "examples": [ "octocat" ] }, "id": { "type": "integer", "examples": [ 1 ] }, "email": { "type": [ "string", "null" ] }, "name": { "type": [ "string", "null" ] }, "node_id": { "type": "string", "examples": [ "MDQ6VXNlcjE=" ] }, "avatar_url": { "type": "string", "format": "uri", "examples": [ "https://github.com/images/error/octocat_happy.gif" ] }, "gravatar_id": { "type": [ "string", "null" ], "examples": [ "41d064eb2195891e12d0413f63227ea7" ] }, "url": { "type": "string", "format": "uri", "examples": [ "https://api.github.com/users/octocat" ] }, "html_url": { "type": "string", "format": "uri", "examples": [ "https://github.com/octocat" ] }, "followers_url": { "type": "string", "format": "uri", "examples": [ "https://api.github.com/users/octocat/followers" ] }, "following_url": { "type": "string", "examples": [ "https://api.github.com/users/octocat/following{/other_user}" ] }, "gists_url": { "type": "string", "examples": [ "https://api.github.com/users/octocat/gists{/gist_id}" ] }, "starred_url": { "type": "string", "examples": [ "https://api.github.com/users/octocat/starred{/owner}{/repo}" ] }, "subscriptions_url": { "type": "string", "format": "uri", "examples": [ "https://api.github.com/users/octocat/subscriptions" ] }, "organizations_url": { "type": "string", "format": "uri", "examples": [ "https://api.github.com/users/octocat/orgs" ] }, "repos_url": { "type": "string", "format": "uri", "examples": [ "https://api.github.com/users/octocat/repos" ] }, "events_url": { "type": "string", "examples": [ "https://api.github.com/users/octocat/events{/privacy}" ] }, "received_events_url": { "type": "string", "format": "uri", "examples": [ "https://api.github.com/users/octocat/received_events" ] }, "type": { "type": "string", "examples": [ "User" ] }, "site_admin": { "type": "boolean" }, "permissions": { "type": "object", "properties": { "pull": { "type": "boolean" }, "triage": { "type": "boolean" }, "push": { "type": "boolean" }, "maintain": { "type": "boolean" }, "admin": { "type": "boolean" } }, "required": [ "pull", "push", "admin" ] }, "role_name": { "type": "string", "examples": [ "admin" ] } }, "required": [ "avatar_url", "events_url", "followers_url", "following_url", "gists_url", "gravatar_id", "html_url", "id", "node_id", "login", "organizations_url", "received_events_url", "repos_url", "site_admin", "starred_url", "subscriptions_url", "type", "url", "role_name" ] } ] } }, "required": [ "permission", "role_name", "user" ] } ```

The top-level field role_name is missing, and the user field looks more like the struct Collaborator than SimpleUser (although even Collaborator is not quite right, because FullRepositoryPermissions is missing the fields triage and maintain).

This may be because the code is generated from GitHub's API spec 1.1.4 (Dec 2021) instead of the latest version 2.1.0 (Oct 2022)?

1oglop1 commented 8 months ago

I'd assume so, I just started with octorust and deemed it unusable due to outdated spec.

It may be a good idea to change the issue title to something like [Github]: API is not up to date

It would be great of this project could just watch API changes and release automatically.

samkearney commented 8 months ago

I'm thinking of creating my own Rust GitHub client because this one seems to be unmaintained, https://github.com/XAMPPRocky/octocrab is done manually and not generated, and I'm not aware of any others. We'll see if I can find the time 😄

1oglop1 commented 8 months ago

I'm thinking of creating my own Rust GitHub client because this one seems to be unmaintained, https://github.com/XAMPPRocky/octocrab is done manually and not generated, and I'm not aware of any others. We'll see if I can find the time 😄

Yeah, it took me 5 minutes to rule out octocrab for 2 reasons: manual and missing endpoints.

I was thinking the same but before putting any effort into it, it would be great if such a project could be backed up by GitHub itself so the maintenance is not left to a single individual. Perhaps the way to go about it would be to start the conversation over at https://github.com/octokit.

Today I tested the generator from this repository with the latest spec but apart from several small changes, the necessary change I needed for create_deployment endpoint was not enough.

Because the endpoint has an optional field required_contexts which accepts valid value of []

required_contexts array of strings The status contexts to verify against commit status checks. If you omit this parameter, GitHub verifies all unique contexts before creating a deployment. To bypass checking entirely, pass an empty array. Defaults to all unique contexts.

but the generated code is:

#[serde(
        default,
        skip_serializing_if = "Vec::is_empty",
        deserialize_with = "crate::utils::deserialize_null_vector::deserialize"
    )]
    pub required_contexts: Vec<String>,

So the generated code does not allow []