backstage / community-plugins

Community plugins for Backstage
Apache License 2.0
141 stars 141 forks source link

🐛 @backstage/plugin-azure-devops: fron-end request not sending component name #758

Open enryson opened 1 month ago

enryson commented 1 month ago

Plugin Name

@backstage-community/plugin-azure-devops

📜 Description

the following cards: EntityAzureGitTagsContent EntityAzureReadmeCard EntityAzurePullRequestsContent i have try the versions 0.4.4 to 0.4.7 same behavior

image

Are not sending the component name on the request to the backend. http://localhost:3000/api/azure-devops/pull-requests/TEAMPROJECT/undefined?top=25&status=1&entityRef=component%3Adefault%2Ftest.backstageio.service

for some reason we get a undefined on the request.

👍 Expected behavior

the strange part is EntityAzurePipelinesContent is workin normally.

example of the REQUEST: http://localhost:3000/api/azure-devops/builds/TEAMPROJECT?entityRef=component%3Adefault%2Fhiae.core.backstageio.service&definitionName=test.BackstageIO.service&top=26

👎 Actual Behavior with Screenshots

Captura de Tela 2024-07-25 às 17 30 47 Captura de Tela 2024-07-25 às 17 30 57

👟 Reproduction steps

install the plugin on backend and frontend go to a component entity. click on the README

OR install the plugin on backend and frontend go to a component entity. click on the GitTags

OR

install the plugin on backend and frontend go to a component entity. click on the Pull Request

📃 Provide the context for the Bug.

On backstage 1.20.3 i didn't have this issue.. I'm current work-in on a version bump to 1.29.3, i encouter this bug on a brand new backstage implementation.

👀 Have you spent some time to check if this bug has been raised before?

🏢 Have you read the Code of Conduct?

Are you willing to submit PR?

No, but I'm happy to collaborate on a PR with someone else

awanlin commented 1 month ago

Hi @enryson, can you share a few more details: it would be great to get the actual error message, any errors in the backend logs, as well as the results from yarn backstage-cli info, please?

enryson commented 1 month ago

no problem.. the only thing that i changed is the domain and team project for obvious reasons

On the README card: No error message on the backend, the API returns a 404 (probably because the frontend component send the wrong payload)

{ "error": { "name": "NotFoundError", "message": "https://dev.azure.com/COMPANY_NAME/PROJECT/_git/undefined?path=README.md could not be read as https://dev.azure.com/COMPANY_NAME/PROJECT/_apis/git/repositories/undefined/items?api-version=6.0&path=README.md, 404 Not Found", "stack": "NotFoundError: https://dev.azure.com/COMPANY_NAME/PROJECT/_git/undefined?path=README.md could not be read as https://dev.azure.com/COMPANY_NAME/PROJECT/_apis/git/repositories/undefined/items?api-version=6.0&path=README.md, 404 Not Found\n at AzureUrlReader.readUrl (/Users/enryson/Documents/GitHub/newBackstage/backstage/node_modules/@backstage/backend-defaults/src/entrypoints/urlReader/lib/AzureUrlReader.ts:109:13)\n at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n at AzureDevOpsApi.getReadme (/Users/enryson/Documents/GitHub/newBackstage/backstage/node_modules/@backstage-community/plugin-azure-devops-backend/src/api/AzureDevOpsApi.ts:577:22)\n at <anonymous> (/Users/enryson/Documents/GitHub/newBackstage/backstage/node_modules/@backstage-community/plugin-azure-devops-backend/src/service/router.ts:383:20)" }, "request": { "method": "GET", "url": "/readme/PROJECT/undefined?entityRef=component%3Adefault%2Ftest.backstageio.service" }, "response": { "statusCode": 404 } }

on the git tags and Pull Requests is KINDA the same.. but i got a 500 error on this case i got a 500 and a backend error

Captura de Tela 2024-07-25 às 21 38 21

Error log on the backend [1] 2024-07-26T00:37:59.152Z backstage error Request failed with status 500 No repository found for Project "NOT_GONA_SHARE" with Repository "undefined" on host "undefined" under organization "undefined". type=errorHandler stack=Error: No repository found for Project "NOT_GONA_SHARE" with Repository "undefined" on host "undefined" under organization "undefined". [1] at AzureDevOpsApi.getGitTags (/Users/enryson/Documents/GitHub/newBackstage/backstage/node_modules/@backstage-community/plugin-azure-devops-backend/src/api/AzureDevOpsApi.ts:271:13) [1] at process.processTicksAndRejections (node:internal/process/task_queues:95:5) [1] at <anonymous> (/Users/enryson/Documents/GitHub/newBackstage/backstage/node_modules/@backstage-community/plugin-azure-devops-backend/src/service/router.ts:170:21)

Same on the tags 500 on the backend..

For shure this is looking a front end component problem because the weird payload.. is missing the component name (AKA entity name) on the request.. To confirm this i replicate the request but fixing the missing argument on the request. i done this on Insomnia Captura de Tela 2024-07-25 às 21 51 35 Samething on the tags Captura de Tela 2024-07-25 às 21 56 39 Readme

Captura de Tela 2024-07-25 às 22 05 43

to me this confirm as a 100% problem on the front-end plugin.. this 3 requests are missing the "entity name"on the request. /api/azure-devops/readme/TEAMPROJECT/undefined /api/azure-devops/git-tags/TEAMPROJECT/undefined /api/azure-devops/pull-requests/TEAMPROJECT/undefined The correct way is like this /api/azure-devops/readme/TEAMPROJECT/test.BackstageIO.service /api/azure-devops/git-tags/TEAMPROJECT/test.BackstageIO.service /api/azure-devops/pull-requests/TEAMPROJECT/test.BackstageIO.service

So far the only front-end component workin fine is the azure CI-CD

yarn backstage-cli info `yarn run v1.22.22 $ /Users/enryson/Documents/GitHub/newBackstage/backstage/node_modules/.bin/backstage-cli info OS: Darwin 23.5.0 - darwin/arm64 node: v18.16.1 yarn: 1.22.22 cli: 0.26.11 (installed) backstage: 1.29.2

Dependencies: @backstage/app-defaults 1.5.9 @backstage/backend-app-api 0.8.0 @backstage/backend-common 0.23.3 @backstage/backend-defaults 0.4.1 @backstage/backend-dev-utils 0.1.4 @backstage/backend-openapi-utils 0.1.15 @backstage/backend-plugin-api 0.6.21, 0.7.0 @backstage/backend-tasks 0.5.27 @backstage/backend-test-utils 0.4.4 @backstage/catalog-client 1.6.5 @backstage/catalog-model 1.5.0 @backstage/cli-common 0.1.14 @backstage/cli-node 0.2.7 @backstage/cli 0.26.11 @backstage/config-loader 1.8.1 @backstage/config 1.2.0 @backstage/core-app-api 1.14.1 @backstage/core-compat-api 0.2.7 @backstage/core-components 0.14.9 @backstage/core-plugin-api 1.9.3 @backstage/e2e-test-utils 0.1.1 @backstage/errors 1.2.4 @backstage/eslint-plugin 0.1.8 @backstage/frontend-plugin-api 0.6.7 @backstage/integration-aws-node 0.1.12 @backstage/integration-react 1.1.29 @backstage/integration 1.13.0 @backstage/plugin-api-docs 0.11.7 @backstage/plugin-app-backend 0.3.71 @backstage/plugin-app-node 0.1.22 @backstage/plugin-auth-backend-module-atlassian-provider 0.2.3 @backstage/plugin-auth-backend-module-aws-alb-provider 0.1.14 @backstage/plugin-auth-backend-module-azure-easyauth-provider 0.1.5 @backstage/plugin-auth-backend-module-bitbucket-provider 0.1.5 @backstage/plugin-auth-backend-module-cloudflare-access-provider 0.1.5 @backstage/plugin-auth-backend-module-gcp-iap-provider 0.2.17 @backstage/plugin-auth-backend-module-github-provider 0.1.19 @backstage/plugin-auth-backend-module-gitlab-provider 0.1.19 @backstage/plugin-auth-backend-module-google-provider 0.1.19 @backstage/plugin-auth-backend-module-guest-provider 0.1.8 @backstage/plugin-auth-backend-module-microsoft-provider 0.1.17 @backstage/plugin-auth-backend-module-oauth2-provider 0.2.3 @backstage/plugin-auth-backend-module-oauth2-proxy-provider 0.1.15 @backstage/plugin-auth-backend-module-oidc-provider 0.2.3 @backstage/plugin-auth-backend-module-okta-provider 0.0.15 @backstage/plugin-auth-backend-module-onelogin-provider 0.1.3 @backstage/plugin-auth-backend 0.22.9 @backstage/plugin-auth-node 0.4.17 @backstage/plugin-auth-react 0.1.4 @backstage/plugin-bitbucket-cloud-common 0.2.21 @backstage/plugin-catalog-backend-module-logs 0.0.1 @backstage/plugin-catalog-backend-module-scaffolder-entity-model 0.1.20 @backstage/plugin-catalog-backend 1.24.0 @backstage/plugin-catalog-common 1.0.25 @backstage/plugin-catalog-graph 0.4.7 @backstage/plugin-catalog-import 0.12.1 @backstage/plugin-catalog-node 1.12.4 @backstage/plugin-catalog-react 1.12.2 @backstage/plugin-catalog 1.21.1 @backstage/plugin-events-node 0.3.8 @backstage/plugin-org 0.6.27 @backstage/plugin-permission-backend-module-allow-all-policy 0.1.19 @backstage/plugin-permission-backend 0.5.46 @backstage/plugin-permission-common 0.7.14, 0.8.0 @backstage/plugin-permission-node 0.7.32, 0.8.0 @backstage/plugin-permission-react 0.4.24 @backstage/plugin-proxy-backend 0.5.3 @backstage/plugin-scaffolder-backend-module-azure 0.1.14 @backstage/plugin-scaffolder-backend-module-bitbucket-cloud 0.1.12 @backstage/plugin-scaffolder-backend-module-bitbucket-server 0.1.12 @backstage/plugin-scaffolder-backend-module-bitbucket 0.2.12 @backstage/plugin-scaffolder-backend-module-gerrit 0.1.14 @backstage/plugin-scaffolder-backend-module-gitea 0.1.12 @backstage/plugin-scaffolder-backend-module-github 0.4.0 @backstage/plugin-scaffolder-backend-module-gitlab 0.4.4 @backstage/plugin-scaffolder-backend 1.23.0 @backstage/plugin-scaffolder-common 1.5.4 @backstage/plugin-scaffolder-node 0.4.8 @backstage/plugin-scaffolder-react 1.10.0 @backstage/plugin-scaffolder 1.23.0 @backstage/plugin-search-backend-module-catalog 0.1.28 @backstage/plugin-search-backend-module-pg 0.5.32 @backstage/plugin-search-backend-module-techdocs 0.1.27 @backstage/plugin-search-backend-node 1.2.27 @backstage/plugin-search-backend 1.5.14 @backstage/plugin-search-common 1.2.13 @backstage/plugin-search-react 1.7.13 @backstage/plugin-search 1.4.14 @backstage/plugin-signals-react 0.0.4 @backstage/plugin-techdocs-backend 1.10.9 @backstage/plugin-techdocs-module-addons-contrib 1.1.12 @backstage/plugin-techdocs-node 1.12.8 @backstage/plugin-techdocs-react 1.2.6 @backstage/plugin-techdocs 1.10.7 @backstage/plugin-user-settings-common 0.0.1 @backstage/plugin-user-settings 0.8.10 @backstage/release-manifests 0.0.11 @backstage/test-utils 1.5.9 @backstage/theme 0.5.6 @backstage/types 1.1.1 @backstage/version-bridge 1.0.8`

awanlin commented 1 month ago

Thanks @enryson, one last thing, I forgot it's not included in the info results any more, can you share the versions of the Azure DevOps plugin packages you are using? Also, what is you azureDevOps config look like in your app-config and what annotations are on the entity.

More generally, the Azure DevOps plugin has seen several changes since December 2023 (that's when the 1.20.x release of Backstage came out) and I might suggest doing a full reinstall of the plugin following the current docs. There might be a change there that you haven't made.

I'm going to dig into this on my end but there hasn't been many recent changes that would account for this 🤔

enryson commented 1 month ago

I have try the 0.4.4, 0.4.5 and 0.4.7 (frontend)versions.. same behaviour. The backend i'm on 0.6.9 my integrations is ok on the app-config

integrations:
  azure:
    - host: dev.azure.com
      credentials:
        - personalAccessToken: ${PERSONAL_ACCESS_TOKEN}

with

azureDevOps: host: dev.azure.com organization: my-company

I do no think this is the problem, because on the backend side of this plugin, things are fine.. with the correct payload i can get the data of all the plugins from the backend side. So far this is looking to be a fron-end bug.. Even because the CI-CD is working fine...

i will try some diferent things, and post the results.

awanlin commented 1 month ago

That's fair, I don't disagree with you assessment but I want all the details to reproduce as I don't have this issue if I run this in the repo right now and I don't suspect I will have issues with doing this net new.

Can you share the annotations you are using? That will help me as well.

enryson commented 1 month ago

Oww boy... i manage to debug this more.. and found the issue. the problem lies on ..

my entity code

    backstage.io/techdocs-ref: url:https://dev.azure.com/........../........../_git/TEST.BackstageIO.service
    dev.azure.com/project-repo: TEST/TEST.BackstageIO.service
    dev.azure.com/project: TEST
    dev.azure.com/build-definition: TEST.BackstageIO.service

because the dev.azure.com/project annotation, the method getAnnotationValuesFromEntity did not return the important stuff. this method return almost all parameters undefined

definition: "TEST.BackstageIO.service"
host: undefined
org: undefined
project: "TEST"
readmePath : undefined

getAnnotationValuesFromEntity.ts

const project =
    entity.metadata.annotations?.[AZURE_DEVOPS_PROJECT_ANNOTATION]; //if he found this

if (definition) {
    console.log('definition:', definition); // he steps into here.. causing missing parameters..
    if (project) {
      console.log('project:', project);
      return {
        project,
        definition,
        readmePath: readmePath,
        ...hostOrg,
      };
    }
    if (projectRepo.project) {
      return {
        project: projectRepo.project,
        repo: projectRepo.repo,
        definition,
        readmePath: readmePath,
        ...hostOrg,
      };
    }
    throw new Error(
      `Value for annotation "${AZURE_DEVOPS_PROJECT_ANNOTATION}" was not found`,
    );
  }

This causes the behavior that i describe.. After i removed the "dev.azure.com/project: " from the entity yaml this fixes the problem..

The reason to the CI-CD worked is because the request is little diferent..

so far on my side i will remove this "dev.azure.com/project: " parameters from the entities.

i do not know this code, but is normal to return only this when the project tag is defined?

 return {
        project,
        definition,
        readmePath: readmePath,
        ...hostOrg,
      };
awanlin commented 1 month ago

Thanks again for digging into this. That makes more sense to me as to why this would fail. There's a lot of tests for this function but we must have missed this when expand this feature to support other cases. There is a test for those three annotations:

https://github.com/backstage/community-plugins/blob/70079c5191b1a42c89b48bb854efcd708761dde8/workspaces/azure-devops/plugins/azure-devops/src/utils/getAnnotationValuesFromEntity.test.ts#L432-L457

Not sure what we missed but glad we have this narrowed down.

awanlin commented 1 month ago

This is the issue related to this feature: https://github.com/backstage/backstage/issues/22082 and this is the PR: https://github.com/backstage/backstage/pull/22153

@R-Beck-2020 @afscrome - do you have any feedback on this? Are you using the annotations in the same way? Is it working for you?

afscrome commented 1 month ago

If your pipelines aren't in a separate project to your build definition, then I strongly recommend you don't set the project attribute at all. Even if things "should" work, it adds a whole bunch of ambiguity and potential for things to go wrong. At my company I don't think any of our apps use this annotation since we don't have any pipelines in seperate projects to the code repo.

Similarly, I'd advise against setting build-definition if the auto detection logic for pipelines doesn't work. (Either because you have more than one application in the same repo, or your pipelines are in a different project).

How to calculate the project when both project and project-repo annotations are set is a bit ambiguous - should the project from the project-repo annotation be used, or should the project from project be used. It sort of depends on the context, but since getAnnotationValuesFromEntity is shared by all contexts, it's hard to differentiate. I forget exactly why we chose that test case in the end - looking at it fresh now, I'd expect project-repo to trump project + definition. IF I had to guess, I'd say we were trying to maintain the behavior prior to our Pr, but from quickly scanning the Pr it looks like project-repo would have won prior to our PR.

Personally, I'd like to see the project annotation retired due to the ambiguity it brings. I'd rather see it renamed todefinition-repo to make it clear it only applies to pipelines, or allow build-definition to be prefixed by a project (e.g. my-definition or PROJECT\my-definition). That in turn has some more knock on effects as now getAnnotaitonValuesFromEntity can no longer return a single project as it doesn't know whether it being called to get repo data (in which case repo-project should win) or for pipeline data (in which case the pipeline project should win).

Alternatively, this problem only occurs if you have your pipeline in a separate project to your repos, whilst this can theoretically be done, I've never seen it in the wild. Given this is the first problem been reported in 6 months, you could say the problem is worth solving. (Especially as based on the sample data provided, both project-repo and project use the same project, so the problem could be solved by removing the project annotation. In which case, maybe the solution is to remove the project annotation completely?