octokit / octokit.graphql.net

A GitHub GraphQL client library for .NET
MIT License
143 stars 49 forks source link

[BUG]: Mutation UpdateProjectV2ItemFieldValue fails with ProjectV2FieldValue has the wrong arguments error #292

Open CodyALohse opened 1 year ago

CodyALohse commented 1 year ago

What happened?

When performing an UpdateProjectV2ItemFieldValue mutation the response returns with a ProjectV2FieldValue has the wrong arguments error

var updateStatusQuery = new Mutation().UpdateProjectV2ItemFieldValue(
    new UpdateProjectV2ItemFieldValueInput {
        FieldId = new ID("xxxxxxx_xxxxxxx-xxxxxxxxxxxx"),
        ItemId = new ID("xxxxxx_xxxxxxxxx-xxxxxxxxxxxx"),
        ProjectId = new ID("xxx_xxxxxxx-xxxxxxx"),
        ClientMutationId = "abc123",
        Value = new ProjectV2FieldValue {
            SingleSelectOptionId = "8499aa9c" 
        }
    })
    .Select(p => p.ProjectV2Item.Id);

var updateStatusRes = await connection.Run(updateStatusQuery);

Below is the generated query:

{ "query":"mutation {
    updateProjectV2ItemFieldValue(input:{
        projectId:\"xxx_xxxxxxx-xxxxxxxs\",
        itemId:\"xxxxxx_xxxxxxxxx-xxxxxxxxxxxx\",
        fieldId:\"xxxxxxx_xxxxxxx-xxxxxxxxxxxx\",
        value:{
            text:null,
            number:null,
            date:null,
            singleSelectOptionId:\"8499aa9c\",
            iterationId:null }
        ,clientMutationId:\"abc123\"})
        {projectV2Item{id}}}","variables":null}

It appears that the value object ProjectV2FieldValue cannot be passed with more than one property per request. Performing a request without the additional null properties does succeed:

{ "query":"mutation {
    updateProjectV2ItemFieldValue(input:{
        projectId:\"xxx_xxxxxxx-xxxxxxxs\",
        itemId:\"xxxxxx_xxxxxxxxx-xxxxxxxxxxxx\",
        fieldId:\"xxxxxxx_xxxxxxx-xxxxxxxxxxxx\",
        value:{
            singleSelectOptionId:\"8499aa9c\",
         }
        ,clientMutationId:\"abc123\"})
        {projectV2Item{id}}}","variables":null}

Thanks

Versions

v0.2.0-beta

Relevant log output

No response

Code of Conduct

Dan-Albrecht commented 11 months ago

@nickfloyd, in true hacktoberfest spirit, I have a total hack-job of a fix for this. The problem is, it introduces a coupling from Octokit.GraphQL.Core ➡️Octokit.GraphQL. This is actually a circular dependency, so 💩.

QuerySerializer needs to know ProjectV2FieldValue is special. I suppose I could solve this by creating a new interface in Core, that I'd slap on to the ProjectV2FieldValue and have the serializer SerializeValue sniff for. Thoughts?

PaulStanos commented 5 months ago

In case others need a workaround for this, the Octokit.GraphQL.Connection class allows you to run a query from a string. OP doesn't mention it specifically, but that's what I assume they did to confirm it works without these null values.

Below is a basic example of how to do this for a 'single select' field, though this should work for other field types, just specify the proper field name when setting up the value. You may also need to tweak the output. In my case, I don't need anything back from the API, so I just get a throwaway value.

var productInformation = new ProductHeaderValue( "your_client_name_here", "x.x.x" );
var gitHubConnection = new Connection( productInformation, "your_PAT_here");
ID projectId = /*<retrieve this from another API call>*/;
ID itemId = /*<retrieve this from another API call>*/;
ID fieldId = /*<retrieve this from another API call>*/;
string singleSelectOptionId = <retrieve this from another API>;

string queryStr = $"{{ \"query\":\"mutation {{updateProjectV2ItemFieldValue(input:{{projectId:\\\"{projectId.Value}\\\", itemId:\\\"{itemId.Value}\\\", fieldId:\\\"{fieldId.Value}\\\", value:{{singleSelectOptionId:\\\"{singleSelectOptionId}\\\"}}, clientMutationId:null}}){{id: projectV2Item{{id}}}}}}\",\"variables\":null}}";
await gitHubConnection.Run( queryStr );
mikeminutillo commented 3 months ago

Is it required to explicitly send null values anywhere in the API?

I see that it is asserted here but I'm not sure if that is verifying that it can serialize with a null property, or if it is explicitly verifying that the null gets serialized.

If it is not required, I have a raised a PR to skip them here https://github.com/octokit/octokit.graphql.net/pull/319

awright18 commented 4 weeks ago

+1 for this, would like to see the #319 PR merged assuming it aligns with the correct version of the spec.