runatlantis / atlantis

Terraform Pull Request Automation
https://www.runatlantis.io
Other
7.83k stars 1.06k forks source link

Azure DevOps client and usage of pre-workflow hooks returns 400 when creating pull request status #4274

Open 3bbbeau opened 9 months ago

3bbbeau commented 9 months ago

Community Note


Overview of the Issue

When using the Azure DevOps VCS provider and using the pre_workflow_hooks directive in my server side configuration:

https://github.com/runatlantis/atlantis/blob/31802675da69c632299efd8c1cbd3f47b51a1447/server/events/vcs/azuredevops_client.go#L292-L295

Reproduction Steps

  1. Bootstrap Atlantis with Azure DevOps.
  2. Create a simple server-side repo config using a dummy pre-workflow-hook.
      repos:
      - id: "/.*/"
        pre_workflow_hooks:
          - run: pwd
  3. Invoke Atlantis by opening a PR.
  4. Inspect the logs, as seen below.

Logs

Logs ``` "msg":"Error running pre-workflow hooks creating pull request status: Request to https://dev.azure.com/myOrg/myProject/_apis/git/repositories/myRepo/pullrequests/1/statuses?api-version=5.1-preview.1 responded with status 400.","json":{"repo":"myOrg/myProject/myRepo" β”‚β”‚ ,"pull":"1"},"stacktrace":"github.com/runatlantis/atlantis/server/events.(*DefaultCommandRunner).RunAutoplanCommand\n\tgithub.com/runatlantis/atlantis/server/events/command_runner.go:196"} ```

Environment details

If not already included, please provide the following:

Atlantis server-side config file:

      repos:
      - id: "/.*/"
        pre_workflow_hooks:
          - run: pwd

Repo atlantis.yaml file:

Additional Context

jamengual commented 9 months ago

that is most probably lack of permissions for the atlantis user to change status.

On Wed, Feb 21, 2024 at 3:02β€―PM Beau @.***> wrote:

Community Note

  • Please vote on this issue by adding a πŸ‘ reaction https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/ to the original issue to help the community and maintainers prioritize this request. Searching for pre-existing feature requests helps us consolidate datapoints for identical requirements into a single place, thank you!
  • Please do not leave "+1" or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request.
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment.

Overview of the Issue

When using the Azure DevOps VCS provider and using the pre_workflow_hooks directive in my server side configuration:

  • HTTP 400 response is returned when calling the *Pull Request Status
  • Create* operation on the ADO API.

https://github.com/runatlantis/atlantis/blob/31802675da69c632299efd8c1cbd3f47b51a1447/server/events/vcs/azuredevops_client.go#L292-L295 Reproduction Steps

  1. Bootstrap Atlantis with Azure DevOps https://www.runatlantis.io/docs/deployment.html#azure-devops.

  2. Create a simple server-side repo config using a dummy pre-workflow-hook.

    repos:

    • id: "/.*/" pre_workflow_hooks:
      • run: pwd
  3. Invoke Atlantis by opening a PR.

  4. Inspect the logs, as seen below.

Logs Logs

"msg":"Error running pre-workflow hooks creating pull request status: Request to https://dev.azure.com/myOrg/myProject/_apis/git/repositories/myRepo/pullrequests/1/statuses?api-version=5.1-preview.1 responded with status 400.","json":{"repo":"myOrg/myProject/myRepo" β”‚β”‚ ,"pull":"1"},"stacktrace":"github.com/runatlantis/atlantis/server/events.(DefaultCommandRunner).RunAutoplanCommand\n\tgithub.com/runatlantis/atlantis/server/events/command_runner.go:196 <http://github.com/runatlantis/atlantis/server/events.(DefaultCommandRunner).RunAutoplanCommand%5Cn%5Ctgithub.com/runatlantis/atlantis/server/events/command_runner.go:196>"}

Environment details

If not already included, please provide the following:

Atlantis server-side config file:

  repos:
  - id: "/.*/"
    pre_workflow_hooks:
      - run: pwd

Repo atlantis.yaml file:

  • None.

Additional Context

β€” Reply to this email directly, view it on GitHub https://github.com/runatlantis/atlantis/issues/4274, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAQ3ERC23FCWLJB2QZMUU5LYUZ4HPAVCNFSM6AAAAABDT447ASVHI2DSMVQWIX3LMV43ASLTON2WKOZSGE2DOOBVHEZTKNA . You are receiving this because you are subscribed to this thread.Message ID: @.***>

3bbbeau commented 9 months ago

Hi @jamengual, thanks for your reply.

I tested this by sending a POST request to the endpoint using the same PAT Atlantis uses, sending the bare minimum in the request body -- context.name as the Azure DevOps 5.1 docs advise:

curl -u :PAT -H "Content-Type: application/json" -d '{"context": {"name": "test"}}' 'https://dev.azure.com/myOrg/myProject/_apis/git/repositories/myRepo/pullRequests/1/statuses?api-version=5.1-preview.1' -v

...
< HTTP/2 200 

I can now see this contextual status within the PR checks, so not sure if it's permissions or rather the request is somehow malformed. I'll check again with debugging but I don't believe I can see the request body. image

jamengual commented 9 months ago

it could be that the VCS url/repo URL used is wrong, maybe an additional /?

On Wed, Feb 21, 2024 at 4:30β€―PM Beau @.***> wrote:

Hi @jamengual https://github.com/jamengual, thanks for your reply.

I tested this by sending a POST request to the endpoint using the same PAT Atlantis uses, sending the bare minimum in the request body -- context.name as the Azure DevOps 5.1 docs https://learn.microsoft.com/en-us/rest/api/azure/devops/git/pull-request-statuses/create?view=azure-devops-rest-5.1&tabs=HTTP advise:

curl -u :PAT -H "Content-Type: application/json" -d '{"context": {"name": "test"}}' 'https://dev.azure.com/myOrg/myProject/_apis/git/repositories/myRepo/pullRequests/1/statuses?api-version=5.1-preview.1' -v

... < HTTP/2 200

I can now see this contextual status within the PR checks, so not sure if it's permissions or rather the request is somehow malformed. I'll check again with debugging but I don't believe I can see the request body. image.png (view on web) https://github.com/runatlantis/atlantis/assets/72932978/896113b0-adef-49f0-8942-c3c932cc0452

β€” Reply to this email directly, view it on GitHub https://github.com/runatlantis/atlantis/issues/4274#issuecomment-1958447900, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAQ3ERDTYI57F35KS6JPAW3YU2GUDAVCNFSM6AAAAABDT447ASVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSNJYGQ2DOOJQGA . You are receiving this because you were mentioned.Message ID: @.***>

3bbbeau commented 9 months ago

Hi @jamengual, fortunately I've managed to fix it but not identify yet the root cause in the code. Thank you, you were correct, there was a malformed URL in the request.

Summary

If --atlantis-url or ATLANTIS_ATLANTIS_URL is not set, CreateStatus() is called with a malformed request body (single / in targetURL):

'{"context":{"genre":"Atlantis Bot/atlantis","name":"pre_workflow_hook: Pre workflow hook #0"},"description":"in progress...","state":"pending","targetUrl":"http:/jobs/dd103450-33e1-3a12-addc-d411cb11e42e","iterationId":2}'

(Notice the single slash / in the protocol http:/).

curl -u :PAT -H "Content-Type: application/json" \ 
  -d '{
          "context":{"genre":"Atlantis Bot/atlantis", "name":"pre_workflow_hook: Pre workflow hook #0"},
          "description":"in progress...",
          "state":"pending",
          "targetUrl":"http:/jobs/dd103450-33e1-3a12-addc-d411cb11e42e","iterationId":2}'  \

  'https://dev.azure.com/myOrg/myProject/_apis/git/repositories/myRepo/pullRequests/1/statuses?api-version=5.1-preview.1' -v

...

< HTTP/2 400 

{"$id":"1","innerException":null,"message":"Supplied URI is invalid. The URI should match RelativeOrAbsolute URI kind format.\r\nParameter name: TargetUrl","typeName":"System.ArgumentException, mscorlib","typeKey":"ArgumentException","errorCode":0,"eventId":0}

Once I specified the ATLANTIS_ATLANTIS_URL, it is able to create the PR status fine now. Happy to look into the root cause in more detail when I have some more time, if it isn't immediately obvious to someone reading this.

Additional details

I logged the response in func (r *Router) GenerateProjectWorkflowHookURL(hookID string) (string, error) and see the following:

β”‚ AtlantisURL: http://atlantis-0:4141                                                                                                                                                                            β”‚
β”‚ jobURL: /jobs/dd103450-33e1-3a12-addc-d411cb11e42e                                                                                                                                                             

So somewhere down the chain to the Azure DevOps API request the targetURL is represented as http:/jobs/dd103450-33e1-3a12-addc-d411cb11e42e.