Fix false success reporting in ado2gh integrate-boards when GitHub PAT permissions are incorrect
Problem
The ado2gh integrate-boards command was incorrectly reporting success when it actually failed due to GitHub PAT permission issues. This occurred because the Azure DevOps API returns HTTP 200 (OK) responses but includes error messages in the response body when the GitHub PAT has insufficient or incorrect permissions.
This PR will not fix the failing ADO integration tests, but it will improve the error message that both users and engineers get in this situation. Previously the test logs would show everything successful and the integration test would fail when trying to assert that the boards integration had been properly configured. Now the test logs will properly recognize and log the error when it occurs configuring boards integration.
Example of the Issue
When running with a GitHub PAT that has too many permissions, the command would log:
[DEBUG] RESPONSE (OK): {"dataProviders":{"ms.vss-work-web.github-user-data-provider":{"errorMessage":"An error has occurred when validating credentials. Please use correct scope for PAT token"}}}
[DEBUG] RESPONSE (OK): {"dataProviders":{"ms.vss-work-web.azure-boards-save-external-connection-data-provider":{"errorMessage":"Specified argument was out of the range of valid values.\r\nParameter name: name"}}}
[INFO] Successfully configured Boards<->GitHub integration
The command reported success despite the clear error messages in the API responses.
Solution
Enhanced error handling in the ADO API service methods used by the integrate-boards workflow:
GetGithubHandle- Enhanced existing error checking to also detecterrorMessagein responsesGetBoardsGithubRepoId- Added error detection for repository access failuresCreateBoardsGithubConnection- Added error detection for connection creation failuresAddRepoToBoardsGithubConnection- Added error detection for repository addition failures
Each method now:
- Parses JSON responses when available
- Checks for
errorMessagefields in the appropriate data provider sections - Throws meaningful
OctoshiftCliExceptionwith error details when issues are detected - Maintains backward compatibility by only processing non-null/non-empty responses
Testing
Added comprehensive test coverage:
- 4 new unit tests validating error detection in each enhanced ADO API method
- All existing 894 tests continue to pass
Impact
- Users now receive clear error messages when GitHub PAT permissions are incorrect
- The command fails fast with actionable feedback instead of reporting false success
- No breaking changes to existing successful workflows
- Improved debugging experience with meaningful error messages
Fixes #1353.
[!WARNING]
Firewall rules blocked me from connecting to one or more addresses
I tried to connect to the following addresses, but was blocked by firewall rules:
dev.azure.com
- Triggering command:
/usr/lib/dotnet/dotnet exec --runtimeconfig /home/REDACTED/work/gh-gei/gh-gei/src/OctoshiftCLI.IntegrationTests/bin/Debug/net8.0/OctoshiftCLI.IntegrationTests.runtimeconfig.json --depsfile /home/REDACTED/work/gh-gei/gh-gei/src/OctoshiftCLI.IntegrationTests/bin/Debug/net8.0/OctoshiftCLI.IntegrationTests.deps.json /home/REDACTED/work/gh-gei/gh-gei/src/OctoshiftCLI.IntegrationTests/bin/Debug/net8.0/testhost.dll --port 38455 --endpoint 127.0.0.1:038455 --role client --parentprocessid 3590 --telemetryoptedin false(dns block)http://www.microsoft.com:80/pkiops/crl/Microsoft%20Identity%20Verification%20Root%20Certificate%20Authority%202020.crl
- Triggering command:
dotnet build(http block)http://www.microsoft.com:80/pkiops/crl/Microsoft%20Public%20RSA%20Timestamping%20CA%202020.crl
- Triggering command:
dotnet build(http block)If you need me to access, download, or install something from one of these locations, you can either:
- Configure Actions setup steps to set up my environment, which run before the firewall is enabled
- Add the appropriate URLs or hosts to my firewall allow list
π‘ You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.
Unit Test Results
ββ1 filesββββ1 suitesβββ21s β±οΈ 893 testsβ893 β β0 π€β0 β 894 runsββ894 β β0 π€β0 β
Results for commit 1ec632c4.
| Package | Line Rate | Branch Rate | Complexity | Health |
|---|---|---|---|---|
| ado2gh | 84% | 78% | 631 | β |
| gei | 81% | 73% | 596 | β |
| Octoshift | 87% | 75% | 1433 | β |
| bbs2gh | 82% | 76% | 669 | β |
| Summary | 84% (7255 / 8595) | 75% (1709 / 2264) | 3329 | β |
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.
[!WARNING]
Firewall rules blocked me from connecting to one or more addresses
I tried to connect to the following addresses, but was blocked by firewall rules:
http://www.microsoft.com:80/pkiops/crl/Microsoft%20Identity%20Verification%20Root%20Certificate%20Authority%202020.crl
- Triggering command:
dotnet build src/Octoshift/Octoshift.csproj(http block)http://www.microsoft.com:80/pkiops/crl/Microsoft%20Public%20RSA%20Timestamping%20CA%202020.crl
- Triggering command:
dotnet build src/Octoshift/Octoshift.csproj(http block)If you need me to access, download, or install something from one of these locations, you can either:
- Configure Actions setup steps to set up my environment, which run before the firewall is enabled
- Add the appropriate URLs or hosts to my firewall allow list
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.
[!WARNING]
Firewall rules blocked me from connecting to one or more addresses
I tried to connect to the following addresses, but was blocked by firewall rules:
http://www.microsoft.com:80/pkiops/crl/Microsoft%20Identity%20Verification%20Root%20Certificate%20Authority%202020.crl
- Triggering command:
dotnet build src/Octoshift/Octoshift.csproj(http block)http://www.microsoft.com:80/pkiops/crl/Microsoft%20Public%20RSA%20Timestamping%20CA%202020.crl
- Triggering command:
dotnet build src/Octoshift/Octoshift.csproj(http block)If you need me to access, download, or install something from one of these locations, you can either:
- Configure Actions setup steps to set up my environment, which run before the firewall is enabled
- Add the appropriate URLs or hosts to my firewall allow list
The IntegrateBoardsCommandHandler tests are unnecessary as you didn't actually change any behavior in that command handler.
The
IntegrateBoardsCommandHandlertests are unnecessary as you didn't actually change any behavior in that command handler.
You're absolutely right. I removed the unnecessary IntegrateBoardsCommandHandler tests since I didn't change any behavior in the command handler itself - only enhanced the underlying AdoApi service methods. The tests for those service methods are sufficient to verify the new error handling behavior. The changes are in commit 13bdd79.
The build is giving an error when running dotnet format, this is the error message(s):
/Users/runner/work/gh-gei/gh-gei/src/Octoshift/Services/AdoApi.cs(341,1): error WHITESPACE: Fix whitespace formatting. Replace 17 characters with '\n\s\s\s\s\s\s\s\s'. [/Users/runner/work/gh-gei/gh-gei/src/Octoshift/Octoshift.csproj] /Users/runner/work/gh-gei/gh-gei/src/Octoshift/Services/AdoApi.cs(342,64): error WHITESPACE: Fix whitespace formatting. Replace 9 characters with '\n\s\s\s\s\s\s\s\s'. [/Users/runner/work/gh-gei/gh-gei/src/Octoshift/Octoshift.csproj] /Users/runner/work/gh-gei/gh-gei/src/Octoshift/Services/AdoApi.cs(682,1): error WHITESPACE: Fix whitespace formatting. Replace 17 characters with '\n\s\s\s\s\s\s\s\s'. [/Users/runner/work/gh-gei/gh-gei/src/Octoshift/Octoshift.csproj] /Users/runner/work/gh-gei/gh-gei/src/Octoshift/Services/AdoApi.cs(683,64): error WHITESPACE: Fix whitespace formatting. Replace 9 characters with '\n\s\s\s\s\s\s\s\s'. [/Users/runner/work/gh-gei/gh-gei/src/Octoshift/Octoshift.csproj]
The build is giving an error when running
dotnet format, this is the error message(s):/Users/runner/work/gh-gei/gh-gei/src/Octoshift/Services/AdoApi.cs(341,1): error WHITESPACE: Fix whitespace f...
Fixed the whitespace formatting issues by running dotnet format. The errors were caused by trailing whitespace on lines 341 and 682 after the PostAsync calls. Changes are in commit 81134be.
Along with the new malformed data handling, add tests for the malformed data. No need to write a separate test for the error parsing method; it'll be tested implicitly in the other ones.
Added comprehensive tests for malformed data handling. The tests verify that each enhanced method properly handles invalid JSON responses, missing dataProviders structure, and null responses. The error parsing method is tested implicitly through these method tests as requested. Changes in commit 5e13716.
The build gave this linter error:
/Users/runner/work/gh-gei/gh-gei/src/Octoshift/Services/AdoApi.cs(9,1): warning IDE0005: Using directive is unnecessary.
Always run dotnet format before committing.
The build gave this linter error:
/Users/runner/work/gh-gei/gh-gei/src/Octoshift/Services/AdoApi.cs(9,1): warning IDE0005: Using directive is unnecessary.
...
Fixed the IDE0005 linter error by removing the unnecessary using Newtonsoft.Json; directive. The code only uses JObject from Newtonsoft.Json.Linq, so the base Newtonsoft.Json using was redundant. Commit 772ffea.
Add a bullet point to RELEASENOTES.md describing the change to our users
Add a bullet point to
RELEASENOTES.mddescribing the change to our users
Added a bullet point to RELEASENOTES.md describing the fix for users. The release note explains that the ado2gh integrate-boards command now properly reports errors when GitHub PAT permissions are incorrect instead of incorrectly reporting success. Commit df94e98.