Skip to content

Support projects_v2_item changes of scalar values like strings/dates/numbers #725

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

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

DavidBoike
Copy link
Contributor

Fixes a bug that prevents deserialization of projects_v2_item events with action edited when the field mentioned in changes is not a single_select but is instead a scalar value like a string, date, or number.


Before the change?

All changes were assumed to be of a single_select field with a particular structure, but the from and to fields aren't always strings, according to the documentation they can also be strings, dates (as strings), or numbers. All of these options will cause deserialization of the event to fail.

After the change?

Unfortunately, this might be a breaking change:

  • In ChangesFieldValue, I changed the type on From and To from ChangesFieldValueChange to a new abstract base class ChangesFieldValueChangeBase (I am not in love with the name) which ChangesFieldValueChange now inherits from. This covers the object use case.
  • I added a type ChangesFieldValueSclaarChange that also inherits from the base and contains a StringValue and NumericValue property to contain whatever scalar value might be contained.
  • I added a JsonConverter on ChangesFieldValueChangeBase so that the deserializer could decide if it was looking at an object or not and return whichever derived type was appropriate.

Pull request checklist

  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been reviewed and added / updated if needed (for bug fixes / features)

Does this introduce a breaking change?

Please see our docs on breaking changes to help!

  • Yes
  • No

Unfortunately, changing the type on From and To to an abstract base class that contains no properties of its own constitutes a breaking change for anyone already using these properties.

Anyone handling any of the ProjectV2{Action}Event classes and accessing that object's evt.Changes.FieldValue.From or evt.Changes.FieldValue.To will now get an abstract type with no properties. This instance must be tested to see if it is a ChangesFieldValueScalarChange or a ChangesFieldValueChange and then cast appropriately before being able to use (assuming existing working code) the Id, Name, Color, or Description properties.


Copy link

👋 Hi! Thank you for this contribution! Just to let you know, our GitHub SDK team does a round of issue and PR reviews twice a week, every Monday and Friday! We have a process in place for prioritizing and responding to your input. Because you are a part of this community please feel free to comment, add to, or pick up any issues/PRs that are labeled with Status: Up for grabs. You & others like you are the reason all of this works! So thank you & happy coding! 🚀

@softworkz
Copy link

@DavidBoike - Thanks for this PR!

It came just in the perfect moment, as today I've noticed that some field change events are not arriving and being responded with 500 to GH.

I wouldn't be worried about the "breaking" change, because it's the current state which is broken - making it essentially unusable for project item edit events.


BTW: What a horrible API design at the side of GitHub. Bad job, GitHub people!

And then, also: No REST API for ProjectsV2 !?!?
There are two .net client libraries and none of them supports Projectsv2

There are REST APIs for everything but not for ProjectsV2 , so now you are forced use graphql for this, even when you've been using REST APIs for everything so far.
The procedures required for updating project item fields via graphql seem to be a joke! This is so overly complicated, that neither Copilot nor better AI models are able to produce any working code for this.

This is a mess!

Comment on lines 20 to 27
case JsonTokenType.None:
case JsonTokenType.EndObject:
case JsonTokenType.StartArray:
case JsonTokenType.EndArray:
case JsonTokenType.PropertyName:
case JsonTokenType.Comment:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

default catches all these, no need to explicitly specify them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually IDE0010 Populate switch prevents build if they are missing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Weird, but this works

switch (reader)
{
    case { TokenType: JsonTokenType.StartObject }:
        var changeObject = JsonSerializer.Deserialize<ChangesFieldValueChange>(ref reader, options);
        return changeObject;
    case { TokenType: JsonTokenType.String }:
        return new ChangesFieldValueScalarChange { StringValue = reader.GetString() };
    case { TokenType: JsonTokenType.Null }:
        return null;
    case { TokenType: JsonTokenType.Number }:
        return new ChangesFieldValueScalarChange { NumericValue = reader.GetDecimal() };
    default:
        throw new JsonException($"Invalid JsonTokenType {reader.TokenType}");
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you prefer it that way? In that case, with pattern matching, no analyzer can spell out what all the cases would be, so it can't give a diagnostic. The flip side of this way is that if a new JsonTokenType was added that was in some way relevant, you'd have no warning when using pattern matching cases, but would know immediately using the code as it stands right now.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't see a new JsonTokenType being added, and if GitHub allows ChangesField to accept new types then this code will need to be updated regardless of how its written.

@DavidBoike DavidBoike force-pushed the projectv2-changes branch 2 times, most recently from 538243b to ed6a385 Compare August 11, 2025 15:03
@DavidBoike
Copy link
Contributor Author

@JamieMagee a few changes made, comments left for everything else, and branch rebased. Ready for another review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: 🆕 Triage
Development

Successfully merging this pull request may close these issues.

[BUG]: projects_v2_item fails to deserialize when changes contain scalar value
3 participants