Skip to content

ci: Replace APIGurus as source for IT#7774

Open
WolfgangHG wants to merge 4 commits into
microsoft:mainfrom
WolfgangHG:apigurus
Open

ci: Replace APIGurus as source for IT#7774
WolfgangHG wants to merge 4 commits into
microsoft:mainfrom
WolfgangHG:apigurus

Conversation

@WolfgangHG

Copy link
Copy Markdown
Contributor

This pull request contains the changes suggested in #7495: the OpenAPI specs hosted at APIGurus do not seem to be updated any longer. So pull the recent api specs from official sources where possible.

What do you think? Is this reasonable?

This makes sense in my opinion because it ensures that Kiota is compatible to the most recent version of commonly used APIs (e.g. Twitter). But it has the drawback that errors in the API might cause false errors in Kiota IT, and changes might require additional changes in Kiota.

I also checked the suppressions and exclusions and removed them if I could not reproduce the error (either fixed in a newer API version or a Kiota change resolved it). But maybe I removed too much, if e.g. the error reason was not meaningful enough. So, several tests might fail if this pull request performs the first CI run.
The linked issues in Ruby suppressions did not always make the actual error clear, so maybe I removed too much or the updated issue link does not point to the original error.

I also found one API that should ideally be pulled from Postman (#7495 (comment)), but this is not part of this pull request.

@WolfgangHG WolfgangHG requested a review from a team as a code owner June 9, 2026 19:02

@baywet baywet left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for the contribution!

Comment thread it/config.json Outdated
@WolfgangHG

Copy link
Copy Markdown
Contributor Author

Hope I fixed the failing tests. I had not seen that "integration-tests.yml" and "idempotency-tests.yml" define the old api guru URLs for preloading.

Comment thread .github/workflows/idempotency-tests.yml Outdated
baywet
baywet previously approved these changes Jun 15, 2026
@baywet baywet enabled auto-merge (squash) June 15, 2026 11:15
@baywet

baywet commented Jun 15, 2026

Copy link
Copy Markdown
Member

@WolfgangHG I think something is off with artifacts download/upload and key composition. see https://github.com/microsoft/kiota/actions/runs/27542430722/job/81407904278
Would you mind having a look please?

@WolfgangHG

Copy link
Copy Markdown
Contributor Author

@baywet It seems the docusign json file was not download: https://github.com/microsoft/kiota/actions/runs/27542430722/job/81407737625 (Warning: No files were found with the provided path: it/openapi.yaml. No artifacts will be uploaded.) and thus no artifact was uploaded to the next step.
Actually, all http downloads failed. Do you have an idea?

@baywet

baywet commented Jun 15, 2026

Copy link
Copy Markdown
Member

@WolfgangHG my guess is that this is not specific to this description, but instead this script is silently failing.

Invoke-WebRequest -Uri $descriptionUrl -OutFile $targetOpenapiPath

GitHub typically throttles unauthenticated requests much more than authenticated ones. Kiota automatically does retrial.
We might want to explore:

  • backoff and retry
  • optionally passing a token (from the workflow) to get higher throttling limits

Let me know if you have any additional comments or questions.

@WolfgangHG

Copy link
Copy Markdown
Contributor Author

I think the Invoke-WebRequest prints error messages if something goes wrong. But I don't see anything in the output.

I could add diagnostic output to download-openapi-specs.ps1 and also test afterwards whether the file was written. What do you think?

@baywet

baywet commented Jun 15, 2026

Copy link
Copy Markdown
Member

I've seen many instances where the output behaviour differs on PowerShell between the local and the GHA run environment. And you end up not "seeing" things. So yes, adding additional logging would be a good way to start.

auto-merge was automatically disabled June 15, 2026 18:10

Head branch was pushed to by a user without write access

@WolfgangHG

Copy link
Copy Markdown
Contributor Author

I added several Write-Output / Write-Information to "download-openapi-specs.ps1" just to test whether I see any of them in the github log. They all will all be removed next time.

And I added

$ErrorActionPreference = "Stop"

...because when calling the script from a CMD window, the exit code (echo %errorlevel%) is "0" even if Invoke-WebRequest fails. But I wonder why I did not see an error output from this command.

@baywet Could you start another CI run?

@WolfgangHG

WolfgangHG commented Jun 15, 2026

Copy link
Copy Markdown
Contributor Author

Rather obvious: the upload step always tried to upload "openapi.yaml", but with my changes, there could also be a "openapi.json". Shame on me that I did not see this before ;-). Now I try to upload both files - let's see what happens. Hope that the file is not present from a previous step. Maybe we should delete both files "openapi.json" and "openapi.yaml" in "download-openapi-specs.ps1".

Same fix should be applied to "integration-tests.yml".

And about logging: Write-Output works ;-). I will remove it when we have fixed CI.

@baywet Another CI run please.

@WolfgangHG

Copy link
Copy Markdown
Contributor Author

Seems the upload of both openapi.json and openapi.yaml in one step works.

New error happens in ./it/compare-generation.ps1 (https://github.com/microsoft/kiota/actions/runs/27572392069/job/81636616228), which always accessed "openapi.yaml" and thus failed with json files.

@baywet I committed a fix, could you start CI again?

@WolfgangHG

Copy link
Copy Markdown
Contributor Author

Another change: "get-description-artifact-key.ps1" always returned DESCRIPTION_PATH=./description/openapi.yaml.

@baywet it is your turn again.

And all of this only because I changed "openapi.yaml" to "openapi.json" for json files (as part of the "default values" changes) - I considered it wrong to have a json file with wrong extension though this did not cause problems when invoking kiota ;-)

@WolfgangHG

Copy link
Copy Markdown
Contributor Author

I think we make progress - this time most idempotency tests worked.

I applied the fix from "idempotency-tests.yml" also to "integration-tests.yml": after downloading the api description, try also to upload "openapi.json".

@baywet One more time....

One of the failing idempotency tests seems to have run into a real error, maybe due to a newer api description..

@WolfgangHG

Copy link
Copy Markdown
Contributor Author

@baywet I digged through the idempotency tests. Here are the errors:

Problem 1:
idempotency (python, https://developers.notion.com/openapi.json)
https://github.com/microsoft/kiota/actions/runs/27618422969/job/81666134243

==>There was a change in file "models\partial_user_object_response.py":
First one:

@dataclass
class PartialUserObjectResponse(Parsable):
    """
    The user who created the data source.
    """

Second one:

@dataclass
class PartialUserObjectResponse(Parsable):
    """
    User who created the page.
    """

Maybe there was a change to the online api descriptions between test run 1 and 2. But this should not happen, as the test uses one single artifact that was downloaded before by this job: https://github.com/microsoft/kiota/actions/runs/27618422969/job/81665975879.
Do you see a point where the scripts might have fallen back to downloading api description (and picking a new one that was updating between first and second call) instead of using the artifact?


Problem 2:
idempotency (typescript, https://developers.notion.com/openapi.json)
https://github.com/microsoft/kiota/actions/runs/27618422969/job/81666131203

Error:
      System.InvalidOperationException: Namespace not found for return type
         at Kiota.Builder.Writers.TypeScript.CodeFunctionWriter.FindFunctionInNameSpace(String functionName, CodeElement codeElement, CodeType returnType) in ... kiota\src\Kiota.Builder\Writers\TypeScript\CodeFunctionWriter.cs:line 443
         at Kiota.Builder.Writers.TypeScript.CodeFunctionWriter.GetDeserializerFunctionName(CodeElement codeElement, CodeType returnType) in ... kiota\src\Kiota.Builder\Writers\TypeScript\CodeFunctionWriter.cs:line 436
         at Kiota.Builder.Writers.TypeScript.CodeFunctionWriter.WriteComposedTypeDeserializer(CodeFunction codeElement, LanguageWriter writer, CodeParameter composedParam, CodeFile codeFile) in ... kiota\src\Kiota.Builder\Writers\TypeScript\CodeFunctionWriter.cs:line 154
         at Kiota.Builder.Writers.TypeScript.CodeFunctionWriter.WriteDeserializerFunction(CodeFunction codeFunction, CodeFile codeFile, LanguageWriter writer) in ... kiota\src\Kiota.Builder\Writers\TypeScript\CodeFunctionWriter.cs:line 667
         at Kiota.Builder.Writers.TypeScript.CodeFunctionWriter.WriteCodeElement(CodeFunction codeElement, LanguageWriter writer) in ... kiota\src\Kiota.Builder\Writers\TypeScript\CodeFunctionWriter.cs:line 115
         at Kiota.Builder.Writers.LanguageWriter.Write[T](T code) in ... kiota\src\Kiota.Builder\Writers\LanguageWriter.cs:line 149
         at Kiota.Builder.CodeRenderers.CodeRenderer.RenderCode(LanguageWriter writer, CodeElement element) in ... kiota\src\Kiota.Builder\CodeRenderers\CodeRenderer.cs:line 83
         at Kiota.Builder.CodeRenderers.CodeRenderer.RenderCode(LanguageWriter writer, CodeElement element) in ... kiota\src\Kiota.Builder\CodeRenderers\CodeRenderer.cs:line 88
         at Kiota.Builder.CodeRenderers.CodeRenderer.RenderCodeNamespaceToSingleFileAsync(LanguageWriter writer, CodeElement codeElement, String outputFile, CancellationToken cancellationToken) in ... kiota\src\Kiota.Builder\CodeRenderers\CodeRenderer.cs:line 35
         at Kiota.Builder.CodeRenderers.CodeRenderer.RenderCodeNamespaceToSingleFileAsync(LanguageWriter writer, CodeElement codeElement, String outputFile, CancellationToken cancellationToken) in ... kiota\src\Kiota.Builder\CodeRenderers\CodeRenderer.cs:line 37
         at Kiota.Builder.CodeRenderers.CodeRenderer.RenderCodeNamespaceToFilePerClassAsync(LanguageWriter writer, CodeNamespace currentNamespace, CancellationToken cancellationToken) in ... kiota\src\Kiota.Builder\CodeRenderers\CodeRenderer.cs:line 55
         at Kiota.Builder.CodeRenderers.CodeRenderer.RenderCodeNamespaceToFilePerClassAsync(LanguageWriter writer, CodeNamespace currentNamespace, CancellationToken cancellationToken) in ... kiota\src\Kiota.Builder\CodeRenderers\CodeRenderer.cs:line 59
         at Kiota.Builder.CodeRenderers.CodeRenderer.RenderCodeNamespaceToFilePerClassAsync(LanguageWriter writer, CodeNamespace currentNamespace, CancellationToken cancellationToken) in ... kiota\src\Kiota.Builder\CodeRenderers\CodeRenderer.cs:line 59
         at Kiota.Builder.CodeRenderers.CodeRenderer.RenderCodeNamespaceToFilePerClassAsync(LanguageWriter writer, CodeNamespace currentNamespace, CancellationToken cancellationToken) in ... kiota\src\Kiota.Builder\CodeRenderers\CodeRenderer.cs:line 59
         at Kiota.Builder.KiotaBuilder.CreateLanguageSourceFilesAsync(GenerationLanguage language, CodeNamespace generatedCode, CancellationToken cancellationToken) in ... kiota\src\Kiota.Builder\KiotaBuilder.cs:line 668
         at Kiota.Builder.KiotaBuilder.<>c__DisplayClass21_0.<<GenerateClientAsync>b__0>d.MoveNext() in ... kiota\src\Kiota.Builder\KiotaBuilder.cs:line 311
      --- End of stack trace from previous location ---
         at Kiota.Builder.KiotaBuilder.GenerateConsumerAsync(Func`5 innerGenerationSteps, CancellationToken cancellationToken) in ... kiota\src\Kiota.Builder\KiotaBuilder.cs:line 348
         at Kiota.Builder.KiotaBuilder.GenerateConsumerAsync(Func`5 innerGenerationSteps, CancellationToken cancellationToken) in ... kiota\src\Kiota.Builder\KiotaBuilder.cs:line 368
         at Kiota.Builder.KiotaBuilder.GenerateClientAsync(CancellationToken cancellationToken) in ... kiota\src\Kiota.Builder\KiotaBuilder.cs:line 285
         at kiota.Handlers.KiotaGenerateCommandHandler.InvokeAsync(ParseResult parseResult, CancellationToken cancellationToken) in ... kiota\src\kiota\Handlers\KiotaGenerateCommandHandler.cs:line 166

This is probably a new error due to changes in the api description since the apigurus version. Do we add a exclusion?


Problem 3:
idempotency (typescript, https://raw.githubusercontent.com/github/rest-api-description/refs/heads...
https://github.com/microsoft/kiota/actions/runs/27618422969/job/81666131202

      error generating the client: Function deserializeIntoWithPath not found in namespace app.client.models
      System.InvalidOperationException: Function deserializeIntoWithPath not found in namespace app.client.models
         at Kiota.Builder.Writers.TypeScript.CodeFunctionWriter.FindFunctionInNameSpace(String functionName, CodeElement codeElement, CodeType returnType) in ... kiota\src\Kiota.Builder\Writers\TypeScript\CodeFunctionWriter.cs:line 447
         at Kiota.Builder.Writers.TypeScript.CodeFunctionWriter.GetDeserializerFunctionName(CodeElement codeElement, CodeType returnType) in ... kiota\src\Kiota.Builder\Writers\TypeScript\CodeFunctionWriter.cs:line 436
         at Kiota.Builder.Writers.TypeScript.CodeFunctionWriter.WriteDiscriminatorInformation(CodeFunction codeElement, CodeParameter parseNodeParameter, LanguageWriter writer) in ... kiota\src\Kiota.Builder\Writers\TypeScript\CodeFunctionWriter.cs:line 398
         at Kiota.Builder.Writers.TypeScript.CodeFunctionWriter.WriteFactoryMethodBody(CodeFunction codeElement, String returnType, CodeFile codeFile, LanguageWriter writer) in ... kiota\src\Kiota.Builder\Writers\TypeScript\CodeFunctionWriter.cs:line 357
         at Kiota.Builder.Writers.TypeScript.CodeFunctionWriter.WriteFactoryMethod(CodeFunction codeElement, CodeFile codeFile, LanguageWriter writer) in ... kiota\src\Kiota.Builder\Writers\TypeScript\CodeFunctionWriter.cs:line 342
         at Kiota.Builder.Writers.TypeScript.CodeFunctionWriter.WriteCodeElement(CodeFunction codeElement, LanguageWriter writer) in ... kiota\src\Kiota.Builder\Writers\TypeScript\CodeFunctionWriter.cs:line 121
         at Kiota.Builder.Writers.LanguageWriter.Write[T](T code) in ... kiota\src\Kiota.Builder\Writers\LanguageWriter.cs:line 149
         at Kiota.Builder.CodeRenderers.CodeRenderer.RenderCode(LanguageWriter writer, CodeElement element) in ... kiota\src\Kiota.Builder\CodeRenderers\CodeRenderer.cs:line 83
         at Kiota.Builder.CodeRenderers.CodeRenderer.RenderCode(LanguageWriter writer, CodeElement element) in ... kiota\src\Kiota.Builder\CodeRenderers\CodeRenderer.cs:line 88
         at Kiota.Builder.CodeRenderers.CodeRenderer.RenderCodeNamespaceToSingleFileAsync(LanguageWriter writer, CodeElement codeElement, String outputFile, CancellationToken cancellationToken) in ... kiota\src\Kiota.Builder\CodeRenderers\CodeRenderer.cs:line 35
         at Kiota.Builder.CodeRenderers.CodeRenderer.RenderCodeNamespaceToSingleFileAsync(LanguageWriter writer, CodeElement codeElement, String outputFile, CancellationToken cancellationToken) in ... kiota\src\Kiota.Builder\CodeRenderers\CodeRenderer.cs:line 37
         at Kiota.Builder.CodeRenderers.CodeRenderer.RenderCodeNamespaceToFilePerClassAsync(LanguageWriter writer, CodeNamespace currentNamespace, CancellationToken cancellationToken) in ... kiota\src\Kiota.Builder\CodeRenderers\CodeRenderer.cs:line 55
         at Kiota.Builder.CodeRenderers.CodeRenderer.RenderCodeNamespaceToFilePerClassAsync(LanguageWriter writer, CodeNamespace currentNamespace, CancellationToken cancellationToken) in ... kiota\src\Kiota.Builder\CodeRenderers\CodeRenderer.cs:line 59
         at Kiota.Builder.CodeRenderers.CodeRenderer.RenderCodeNamespaceToFilePerClassAsync(LanguageWriter writer, CodeNamespace currentNamespace, CancellationToken cancellationToken) in ... kiota\src\Kiota.Builder\CodeRenderers\CodeRenderer.cs:line 59
         at Kiota.Builder.CodeRenderers.CodeRenderer.RenderCodeNamespaceToFilePerClassAsync(LanguageWriter writer, CodeNamespace currentNamespace, CancellationToken cancellationToken) in ... kiota\src\Kiota.Builder\CodeRenderers\CodeRenderer.cs:line 59
         at Kiota.Builder.CodeRenderers.CodeRenderer.RenderCodeNamespaceToFilePerClassAsync(LanguageWriter writer, CodeNamespace currentNamespace, CancellationToken cancellationToken) in ... kiota\src\Kiota.Builder\CodeRenderers\CodeRenderer.cs:line 59
         at Kiota.Builder.CodeRenderers.CodeRenderer.RenderCodeNamespaceToFilePerClassAsync(LanguageWriter writer, CodeNamespace currentNamespace, CancellationToken cancellationToken) in ... kiota\src\Kiota.Builder\CodeRenderers\CodeRenderer.cs:line 59
         at Kiota.Builder.CodeRenderers.CodeRenderer.RenderCodeNamespaceToFilePerClassAsync(LanguageWriter writer, CodeNamespace currentNamespace, CancellationToken cancellationToken) in ... kiota\src\Kiota.Builder\CodeRenderers\CodeRenderer.cs:line 59
         at Kiota.Builder.CodeRenderers.CodeRenderer.RenderCodeNamespaceToFilePerClassAsync(LanguageWriter writer, CodeNamespace currentNamespace, CancellationToken cancellationToken) in ... kiota\src\Kiota.Builder\CodeRenderers\CodeRenderer.cs:line 59
         at Kiota.Builder.KiotaBuilder.CreateLanguageSourceFilesAsync(GenerationLanguage language, CodeNamespace generatedCode, CancellationToken cancellationToken) in ... kiota\src\Kiota.Builder\KiotaBuilder.cs:line 668
         at Kiota.Builder.KiotaBuilder.<>c__DisplayClass21_0.<<GenerateClientAsync>b__0>d.MoveNext() in ... kiota\src\Kiota.Builder\KiotaBuilder.cs:line 311
      --- End of stack trace from previous location ---
         at Kiota.Builder.KiotaBuilder.GenerateConsumerAsync(Func`5 innerGenerationSteps, CancellationToken cancellationToken) in ... kiota\src\Kiota.Builder\KiotaBuilder.cs:line 348
         at Kiota.Builder.KiotaBuilder.GenerateConsumerAsync(Func`5 innerGenerationSteps, CancellationToken cancellationToken) in ... kiota\src\Kiota.Builder\KiotaBuilder.cs:line 368
         at Kiota.Builder.KiotaBuilder.GenerateClientAsync(CancellationToken cancellationToken) in ... kiota\src\Kiota.Builder\KiotaBuilder.cs:line 285
         at kiota.Handlers.KiotaGenerateCommandHandler.InvokeAsync(ParseResult parseResult, CancellationToken cancellationToken) in ... kiota\src\kiota\Handlers\KiotaGenerateCommandHandler.cs:line 166

Same question as problem 2....

@baywet

baywet commented Jun 17, 2026

Copy link
Copy Markdown
Member

Hi @WolfgangHG
Thank you for the additional information.

Looking at the CI results, it seems the issues are not just limited to TypeScript and Python? Do you have more context here? or is the python class description issue propagated to more languages?

It'd be interesting to share the component definition here, and the references to it to understand how does the generator get into that race condition.

For TypeScript, to me that sounds like a bug in the TypeScript generation, I'd log a detailed bug and suppress for later investigation.

Let me know if you have any additional comments or questions.

@WolfgangHG

WolfgangHG commented Jun 17, 2026

Copy link
Copy Markdown
Contributor Author

Added suppression/exclusion for the two failing typescript clients.

@baywet Could you start another CI run? Maybe the python idempotency problem was a random error.

@WolfgangHG

Copy link
Copy Markdown
Contributor Author

I worked through six more apis/language errors and added suppressions/exclusions.

For Java/Github api, there is mock server test ("\it\java\gh\src\test\java\GHAPITest.java") that did not compile with recent api. I think I fixed it - Github apparently changed a parameter name.

Also reverted the NOTION.com/PHP suppression after the fix of #7809

@baywet Could you give CI another run? There should still be five or six errors remaining.

@WolfgangHG

Copy link
Copy Markdown
Contributor Author

@baywet I think I am done with all failing tests and flooded the repo with a lot of new issues ;-)
Could you launch other CI run?

@WolfgangHG

Copy link
Copy Markdown
Contributor Author

Last CI run failed with the test "typescript and GITHUB api" - I had a typo in the suppression rule. This is fixed now - another test run please 😄 !

@gavinbarron

Copy link
Copy Markdown
Contributor

@WolfgangHG it seems there is a conflict that needs to be resolved before we can run tests

@WolfgangHG WolfgangHG force-pushed the apigurus branch 2 times, most recently from 36f3157 to 9408fe9 Compare July 7, 2026 09:56
@WolfgangHG

Copy link
Copy Markdown
Contributor Author

@gavinbarron I rebased.

The conflicting change from #7859 to "it/Readme.md" introduced a chapter "Surface area / DOM diff test" that was put in the middle of the integration test description (the next chapter "Mock server tests" belongs to "Running the Integration Tests"). It seems that "Surface area / DOM diff test" is not related to the integration tests stuff, so I suggest to move it either to the beginning or the end of the file. What do you think?

@gavinbarron

Copy link
Copy Markdown
Contributor

it's an integration test for another purpose, putting it to the end of the of the file makes sense to me.

@WolfgangHG

WolfgangHG commented Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

The failing idempotency test https://github.com/microsoft/kiota/actions/runs/28884299669/job/85681452557 shows exactly the same error that happened three weeks ago, see analysis in #7774 (comment) (section "Problem 1"), even with the same code diff.
@gavinbarron Do you have any idea? It will probably work if the test is run another time, but maybe it fails randomly some time later.

@gavinbarron

Copy link
Copy Markdown
Contributor

Yeah, rerunning that job got it to pass, one thing that might help isolate what's going on with that flaky test is to output the kiota lock files when there is a failure.

@WolfgangHG

Copy link
Copy Markdown
Contributor Author

@gavinbarron I changed the section order in "it/Readme.md" and moved the "Surface area / DOM diff test" part to the end. Hope it is OK for you?

As in the previous test run a bunch of other NOTION.COM idempotency tests failed, I added code to "compare-generation.ps1" (with the help of Copilot) that reports the files that are different. Hope this makes it easier to track down the differences next time.

About your comment

...one thing that might help isolate what's going on with that flaky test is to output the kiota lock files when there is a failure.

Previously, those files were deleted before computing the hash. I changed the code and added them to the exclusion of Get-ChildItem -Exclude @("kiota-lock.json",".kiota.log").

Could you start another test run, just to see whether an idempotency test fails and whether my new code helps analyzing the problem? Maybe I introduced an error when changing the download urls and missed something....

@WolfgangHG

Copy link
Copy Markdown
Contributor Author

The recent changes to "compare-generation.ps1" revealed that "kiota-lock.json" contains the same description hash for both files, though there are differences in the result. So, the same API description was picked for both runs.
The file ".kiota.log" is still missing from the uploaded artifact. "Compress-Archive" skips hidden files (starting with a dot) on linux. I could rename the file to "kiota.log" to make it part of the upload.

But I think I found the reason for the idempotency errors and created #7927 - could we continue discussion there?

@baywet

baywet commented Jul 12, 2026

Copy link
Copy Markdown
Member

For the logs, instead of uploading them in the zip, which is going to make them difficult to access, we should instead merge them into the action logs with something like this

- name: Run tool and merge logs on failure
  if: always()
  run: |
    if [ -f my-file.log ]; then
      echo "::group::Tool Logs (Post-Execution)"
      cat my-file.log
      echo "::endgroup::"
    fi

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants