Skip to content
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

feat: Integrate with Azure Devops #2388

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

BalighMehrez
Copy link

Description

Integration with Azure DevOps boards.

Issues Resolved

#356

Check List

  • New functionality includes testing.
  • New functionality has been documented in the README if applicable.

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Hello there BalighMehrez! 👋

Thank you and congrats 🎉 for opening your first PR on this project! ✨ 💖

We will try to review it soon!

@johannesjo
Copy link
Owner

Thank you very much!! I try to have a look tomorrow!

@johannesjo
Copy link
Owner

There seem to be some minor linting errors:

Linting "sp2"...

/home/runner/work/super-productivity/super-productivity/src/app/features/issue/providers/azuredevops/azuredevops-api.service.ts
Error:   72:1  error  This line has a length of 244. Maximum allowed is 150  max-len
Lint errors found in the listed files.


/home/runner/work/super-productivity/super-productivity/src/app/features/issue/providers/azuredevops/azuredevops-common-interfaces.service.ts
Error:   4:[10](https://github.com/johannesjo/super-productivity/actions/runs/3782159290/jobs/6539750367#step:8:11)  error  'catchError' is defined but never used  @typescript-eslint/no-unused-vars
Error:   4:10  error  'catchError' is defined but never used  unused-imports/no-unused-imports
Error:   4:45  error  'switchMap' is defined but never used   @typescript-eslint/no-unused-vars
Error:   4:45  error  'switchMap' is defined but never used   unused-imports/no-unused-imports

✖ 5 problems (5 errors, 0 warnings)
  2 errors and 0 warnings potentially fixable with the `--fix` option.

Error: Process completed with exit code 1.

export const AZUREDEVOPS_POLL_INTERVAL = 10 * 60 * 1000;
export const AZUREDEVOPS_INITIAL_POLL_DELAY = 8 * 1000;

export const AZUREDEVOPS_API_BASE_URL = 'https://dev.azure.com';
Copy link

@PsikoBlock PsikoBlock Jan 9, 2023

Choose a reason for hiding this comment

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

Just thought of this integration when discussing in my team, awesome that you are on it! Will definitely try this out. One request: can you please make this URL configurable? My employer uses on-premise Azure DevOps Server.

Copy link
Contributor

@rklec rklec left a comment

Choose a reason for hiding this comment

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

Hi thanks a lot for working on it! 🎉 I am personally curious to test this out. I've left some comments, where I see potential problems (especially with the self-hosted/on-premise Azure DevOps Server) or ideas for improvement.

);
}

wiql$(cfg: AzuredevopsCfg, query: string): Observable<AzuredevopsWIQLSearchResult> {
Copy link
Contributor

Choose a reason for hiding this comment

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

What is this abbreviation about? Maybe use a non-abbreviated name?

Copy link
Author

Choose a reason for hiding this comment

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

WIQL is a query language used to query work items form Azure DevOps APIs, it stands for (Work Items Query Language).

getById$(issueId: number, cfg: AzuredevopsCfg): Observable<AzuredevopsIssue> {
return this._sendRequest$(
{
url: `${BASE}/${cfg.organization}/${cfg.project}/_apis/wit/workitems/${issueId}?fields=${WIT_FIELDS_STR}&api-version=7.1-preview.3`,
Copy link
Contributor

Choose a reason for hiding this comment

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

api-version=7.1-preview.3 -> maybe use more stable API version? I.e. at least not a preview build?

This table here shows the latest stable is 6.0, which is Azure DevOps Server 2020 (build 18.170.30525.1), your version would be 7.1, which is a good development target, but the integration should be possible with at least some somewhat recent version.

Also it would be good to note somewhere, with which Azure DevOps version this is compatible/which does it require?

See also: API docs

Copy link
Author

Choose a reason for hiding this comment

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

Good point,
this should be configurable for compatibility with on-premise versions, as some users still work with older versions as well.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, depends on how the API may have changed in previous versions (i.e. which is the minimal API version your code works with). But if it is configurable, then people could just "try it out".

const owner = cfg.filterUsername;
return this.wiql$(
cfg,
` Select [System.Id], [System.Title], [System.State] From WorkItems Where [State] <> 'Closed' AND [State] <> 'Removed' AND [System.AssignedTo] contains '${owner}' order by [Microsoft.VSTS.Common.Priority] asc, [System.CreatedDate] desc `,
Copy link
Contributor

@rklec rklec Jan 9, 2023

Choose a reason for hiding this comment

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

This query should potentially be configurable, should not it? At least for the Jira integration, their query system is configurable in SuperProducitivity.

Copy link
Contributor

Choose a reason for hiding this comment

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

One use case I have in mind is that one may want to filter the items by their Epic, because one may use one epic per (sub)project.

export class AzuredevopsApiService {
constructor(private _snackService: SnackService, private _http: HttpClient) {}

getById$(issueId: number, cfg: AzuredevopsCfg): Observable<AzuredevopsIssue> {
Copy link
Contributor

Choose a reason for hiding this comment

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

IMHO abbreviations such as cfg for configshould be discouraged, as it decreases readability, but that is a thing the maintainer should decide.

Copy link
Author

Choose a reason for hiding this comment

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

Agree with you, but I wanted it to be much closer to current integrations, so I have just used same abbreviations and naming conventions I have found.

"WRITE_A_COMMENT": "Write a comment"
},
"S": {
"ERR_UNKNOWN": "Azure Devops: Unknown error {{statusCode}} {{errorMsg}}. Api Rate limit exceeded?"
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
"ERR_UNKNOWN": "Azure Devops: Unknown error {{statusCode}} {{errorMsg}}. Api Rate limit exceeded?"
"ERR_UNKNOWN": "Azure Devops: Unknown error {{statusCode}} {{errorMsg}}. API rate limit exceeded?"

spelling

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
"ERR_UNKNOWN": "Azure Devops: Unknown error {{statusCode}} {{errorMsg}}. Api Rate limit exceeded?"
"ERR_UNKNOWN": "Azure DevOps: Unknown error {{statusCode}} {{errorMsg}}. API rate limit exceeded?"

Also AFAIK/IIRC that is the official spelling of the service.

export const mapAzuredevopsReducedIssueFromWIQL = (
workItem: any,
): AzuredevopsIssueReduced => {
console.log(workItem);
Copy link
Contributor

Choose a reason for hiding this comment

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

This was just there for debugging and should be removed in prod code then, should not it?

@@ -0,0 +1,56 @@
@import 'src/variables';

// table styled by ./src/styles/components/issue-table.scss
Copy link
Contributor

Choose a reason for hiding this comment

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

random thought: would not an @import ./src/styles/components/issue-table.scss be possible instead of coping?

Copy link
Author

Choose a reason for hiding this comment

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

TBH, I am not familiar with SCSS. I have copied from another issue module and replaced names 😅

Copy link
Contributor

Choose a reason for hiding this comment

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

Well then you could just try that out, could not you? That @import is actually part of CSS (now), and it works quite simple: https://developer.mozilla.org/en-US/docs/Web/CSS/@import

return {
title: this._formatIssueTitle(issue.id, issue.title),
issueWasUpdated: false,
// NOTE: we use Date.now() instead to because updated does not account for comments
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// NOTE: we use Date.now() instead to because updated does not account for comments
// NOTE: we use Date.now() instead, because updated does not account for comments

grammar


issueLink$(issueId: number, projectId: string): Observable<string> {
return this._getCfgOnce$(projectId).pipe(
map((cfg) => `https://azuredevops.com/${cfg.organization}/issues/${issueId}`),
Copy link
Contributor

Choose a reason for hiding this comment

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

This also needs to be configurable/use the configured base url for hosted/on-premise Azure DevOps Server instances, otherwise the link is broken... 🙃

Copy link
Contributor

Choose a reason for hiding this comment

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

Also I am unsure what is different about our on-premise Azure DevOps instance (maybe the template?), but we have a different URL format and the above one does not work. It's https://{host}/tfs/{collection|organisation}/{project}/_workitems/edit/{issueId}.

Collections: https://learn.microsoft.com/en-us/azure/devops/server/admin/manage-project-collections?view=azure-devops-2022
Projects: https://learn.microsoft.com/en-us/azure/devops/organizations/projects/create-project?view=azure-devops-2022&tabs=browser

Copy link
Contributor

Choose a reason for hiding this comment

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

This is Azure DevOps Server 2020 Update 1.1. Also tried the URL on Azure DevOps Server 2022 (AzureDevOpsServer_20221122.1) and it does not work either.

Copy link
Author

Choose a reason for hiding this comment

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

Yeah, this link it totally wrong, will not work in hosted either.

Comment on lines +197 to +198
}
private _b64EncodeUnicode(str: string): string {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
}
private _b64EncodeUnicode(str: string): string {
}
private _b64EncodeUnicode(str: string): string {

@LukasKlepper
Copy link

Whats the status on this? I would really love to see a DevOps Integration.

@johannesjo
Copy link
Owner

The linting stuff needs to be fixed. Apart from that I am open to merge this. Unfortunately I can't test the feature myself, so help with that would be welcome!

@LukasKlepper
Copy link

@johannesjo I'd like to fix the linting errors, but the job's log is expired. Could you please rerun it so I can see whats wrong?

@johannesjo
Copy link
Owner

@LukasKlepper looks like I can't :/ But you can also run all the linting/unit testing stuff locally via:

npm run lint
npm run test

If this doesn't work for you, you can retrigger the build by submitting a new commit.

@xTamasu
Copy link

xTamasu commented Aug 4, 2023

Hi @johannesjo, before I've looked into the linting errors I've checked the integration with devops myself and saw some things which may need to improve before matching the quality of a master pr.

  • When going on "Project Specific Settings -> Issue Integration" the name of the implementation is written "AZUREDEVOPS", should be "Azure DevOps".
  • Currently all backlog items are getting fetched (Epic, Features, User Stories), in a real scenario we mostly log to user stories (in my experience). It would be nice to see the type of the issue within Super Productivitiy. We can get the information from the workItem's System.WorkItemType in the api's answer.
  • It would be nice to also see the acceptance criteria within Super Productivitiy, not only the Description.
  • A link to the item within Super Productivity which opens the item in Azure DevOps would be nice to have. It seems like there is something like that implemented in the Summary but it always leads me back to localhost. (Could also be an problem to my local environment?) We can get the information from the workItem's _links.html.href in the api's answer.

The linting errors seem quite easy to fix.

src\app\features\issue\providers\azuredevops\azuredevops-api.service.ts
  error  This line has a length of 244. Maximum allowed is 150  max-len
src\app\features\issue\providers\azuredevops\azuredevops-common-interfaces.service.ts
  error  'catchError' is defined but never used  @typescript-eslint/no-unused-vars
  error  'catchError' is defined but never used  unused-imports/no-unused-imports
  error  'switchMap' is defined but never used   @typescript-eslint/no-unused-vars
  error  'switchMap' is defined but never used   unused-imports/no-unused-imports

@rklec
Copy link
Contributor

rklec commented Aug 7, 2023

Currently all backlog items are getting fetched (Epic, Features, User Stories), in a real scenario we mostly log to user stories (in my experience). It would be nice to see the type of the issue within Super Productivitiy.

Attention: This depends on the template you use/have in ADS. You have several different ones and AFAIK you can also customize them. In my experience we log to Tasks, mostly. e.g. and the parent of that can e.g. be called Product Backlog Item (PBI) in the Scrum process.

@xTamasu
Copy link

xTamasu commented Aug 7, 2023

@rklec Yeah, it depends mostly on the organization guidelines/settings. Thats why it should only show the type of the item so the user can decide whats important for him.

@Kevinf63
Copy link

Keeping a watchful eye, would be a great addition to my workflow to have this!

@Kigstn
Copy link

Kigstn commented Dec 13, 2023

Second this, would be amazing to have!

Copy link

This PR has not received any updates in 90 days. Please comment, if this still relevant!

@github-actions github-actions bot added the Stale label Apr 28, 2024
@Kevinf63
Copy link

This PR has not received any updates in 90 days. Please comment, if this still relevant!

Very relevant.

@github-actions github-actions bot removed the Stale label Apr 29, 2024
@nemanja010
Copy link

What's the status on this? Any chance of getting it merged?

@johannesjo
Copy link
Owner

I am unable to test this myself, so if someone were to test this and report how it is working back here, I am all for merging this.

@rklec
Copy link
Contributor

rklec commented May 16, 2024

Note you can AFAIK create a free(?) account on https://dev.azure.com/ and test it. Though this obviously only tests the hosted/SaaS solution.

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.

None yet

9 participants