Skip to content

Implement jira bridge - #250

Merged
MichaelMure merged 21 commits into
git-bug:masterfrom
cheshirekow:cheshirekow-jira
Feb 19, 2020
Merged

MichaelMure merged 21 commits into
git-bug:masterfrom
cheshirekow:cheshirekow-jira

Conversation

@cheshirekow

Copy link
Copy Markdown
Contributor

No description provided.

@cheshirekow

Copy link
Copy Markdown
Contributor Author

Some notes:

I suggest you start with doc/jira_bridge.md as it describes several of the jira-specific issues that are dealt with by the bridge, as well as some (initial) design decisions.

Note that I've tested the import quite a bit, but I've only tested the export with one bug that I created, exported, imported, modified, exported again. I don't want to use my work JIRA instance in case I messed up and export thousands duplicate bugs into our jira (the project I used to test has 6000 issues). One thing that would help a lot is if we could get in touch with Atlassian and request that they donate a license (or a cloud instance) to the git-bug project for testing . I think we really need a mock server for CI,but for dev cycles it would definitely be nice to work with the real thing. AlsoI think we should really test the export a bit before putting this out in the world. I would be happy to try and contact Atlassian, but I think as the project owner they might appreciate more hearing from @MichaelMure.

The bridge currently does nothing to import any of the JIRA fields that don'thave git-bug equivalents ("Assignee", "sprint", "story points", etc). I'm not sure what the right way to go about this is, but it would really be awesomeif git-bug could support all of these fields. I would love to hear thoughts on this for future development.

I don't fully understand what the whole getIdentityClient code is for in the existing plugins. I have a suspicion it's there for future use (the ability to assume different identities and act on behalf of those identities). I tried to keep that stuff around in the JIRA bridge but that code isn't really doinganything right now.

Comment thread bridge/jira/export.go Outdated
Comment thread bridge/jira/import.go Outdated
Comment thread bridge/jira/import.go Outdated
Comment thread bridge/jira/import.go Outdated
Comment thread bridge/jira/import.go Outdated
Comment thread bridge/jira/client.go
Comment thread bridge/jira/config.go Outdated
Comment thread bridge/jira/import.go Outdated
Comment thread bridge/jira/import.go Outdated
Comment thread bridge/jira/export.go Outdated
@MichaelMure

Copy link
Copy Markdown
Contributor

I think we really need a mock server for CI,but for dev cycles it would definitely be nice to work with the real thing. AlsoI think we should really test the export a bit before putting this out in the world. I would be happy to try and contact Atlassian, but I think as the project owner they might appreciate more hearing from @MichaelMure.

Why not using a free plan, hosted by Atlassian ? It's up to 10 seat, "free forever".

The bridge currently does nothing to import any of the JIRA fields that don'thave git-bug equivalents ("Assignee", "sprint", "story points", etc). I'm not sure what the right way to go about this is, but it would really be awesomeif git-bug could support all of these fields. I would love to hear thoughts on this for future development.

I thouched a bit on that here: #241 (comment)

I don't fully understand what the whole getIdentityClient code is for in the existing plugins. I have a suspicion it's there for future use (the ability to assume different identities and act on behalf of those identities). I tried to keep that stuff around in the JIRA bridge but that code isn't really doing anything right now.

Yeah, it doesn't really do anything at the moment but will eventually. The goal is to be able to load as much credential as necessary and being able to use git-bug as a "real" bridge between two bug tracker for a migration. It's not really part of git-bug's end goal but it was a fairly simply architectural change to enable that use case.

@MichaelMure

Copy link
Copy Markdown
Contributor

Huu, sorry for asking that after you wrote that much code, but have you looked at https://github.com/andygrunwald/go-jira ? Wouldn't that simplify a bunch of things in here ?

@cheshirekow

Copy link
Copy Markdown
Contributor Author

Why not using a free plan, hosted by Atlassian ? It's up to 10 seat, "free forever".

For real? Wow awesome. I only found the 30 day server trial. I'll look into this.

I thouched a bit on that here

Ok great, I haven't gotten back to that discussion yet. I've been focused on this bridge :).

Yeah, it doesn't really do anything at the moment but will eventually.

Ok good. I think I've respected the setup and the plumbing is in place for this bridge as well.

but have you looked at https://github.com/andygrunwald/go-jira

Nope. It's news to me.

Wouldn't that simplify a bunch of things in here ?

I don't think so... I mean it would be a lot less code to use someone else's REST wrapper, if that's what you mean, but I don't think the rest of the bridge implementation changes. If that library looks good I would be happy to swap out for it.

sorry for asking that after you wrote that much code

..meh, the big time sink was studying the API and testing behaviors. Writing the REST wrapper was relatively quick.

@MichaelMure

Copy link
Copy Markdown
Contributor

I mean it would be a lot less code to use someone else's REST wrapper

Having someone else do the maintenance is a big win, at least for me ;)

@MichaelMure MichaelMure left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

That's a lot of code ! Nothing obviously wrong, great start !

Comment thread doc/jira_bridge.md
Comment thread doc/jira_bridge.md
Comment thread doc/jira_bridge.md
Comment thread doc/jira_bridge.md
Comment thread doc/jira_bridge.md
Comment thread bridge/jira/export.go Outdated
Comment thread bridge/jira/export.go Outdated
Comment thread bridge/jira/export.go
Comment thread bridge/jira/export.go Outdated
Comment thread bridge/jira/export.go Outdated
@MichaelMure

Copy link
Copy Markdown
Contributor

For real? Wow awesome. I only found the 30 day server trial. I'll look into this.

I created an instance at https://git-bug.atlassian.net give me an email so I can invite you.

@cheshirekow cheshirekow left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think the github review interface is buggy. I thought it discarded some of my replies, but then I think they may have come back. I apologize if there are duplicates. I put a 👍 on some of your requested changes to acknowledge them. I will comment with "Done" when they are done.

Comment thread bridge/jira/export.go Outdated
Comment thread bridge/jira/export.go
Comment thread bridge/jira/export.go Outdated
Comment thread bridge/jira/export.go Outdated
Comment thread bridge/jira/import.go
Comment thread doc/jira_bridge.md
Comment thread doc/jira_bridge.md
Comment thread doc/jira_bridge.md
Comment thread doc/jira_bridge.md
entry to our git-config:

```
create-issue-defaults = {"issuetype":"10001"}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

For the raw JSON request? No it must be an ID.
For git-bug? Sure it could but there are a couple of considerations:

  1. The mapping can change more easily than the workflow. If a project manager decides that "Open" should be renamed to "Initiated" the textual name will change but the ID and workflow specification will stay the same.
  2. We'll need to lookup the mapping and translate it when we merge the JSON into our outgoing request
  3. Issue types are not namespaced by project, they are global to a JIRA server so all projects share a common pool of names and ids. This may or may not be an issue if the pool is large. I don't know how big the mapping might get. The large company I currently work for has 155 issue types that are visible to me, which is small enough to query once and reuse.

If you feel like it's worthwhile we can go down that path. I would advocate to make this a future enhancement.

Comment thread doc/jira_bridge.md Outdated
You can specify the mapping between `git-bug` status and JIRA status id's using
the following:
```
bug-open-id = 1

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

That's a good point. This should really be a dictionary style mapping.

@cheshirekow

Copy link
Copy Markdown
Contributor Author

For real? Wow awesome. I only found the 30 day server trial. I'll look into this.

I created an instance at https://git-bug.atlassian.net give me an email so I can invite you.

Sent you an email. I'm glad you were able to get one. I've been trying for a few days now and I keep getting an error. Looks like it worked for me today though.

@cheshirekow cheshirekow left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Alright I think I've addressed all the comments so far. I'm out of time for the evening so I will test the changes and push an update to this PR when I get a chance.

Comment thread bridge/jira/export.go Outdated
Comment thread bridge/jira/config.go Outdated
conf[core.KeyTarget] = target
conf[keyServer] = serverURL
conf[keyProject] = project
if choice == 1 {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done.

Comment thread bridge/jira/config.go Outdated
}

// PromptPassword performs interactive input collection to get the user password
func PromptPassword() (string, error) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Moved to input/prompt.go. We can follow up with using it in other bridges (TODO 3cb989e)

Comment thread bridge/jira/export.go Outdated
Comment thread bridge/jira/export.go Outdated
Comment thread bridge/jira/import.go Outdated
targetOpID, err := b.ResolveOperationWithMetadata(
keyJiraID, item.ID)
if err == nil {
self.out <- core.NewImportNothing("", "comment already imported")

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ok, done. Removed the superfluous nothing events. One question though: if we can't import/export a particular operation due to lack of credentials or for some other criteria, should we silently move on or should we emit an error event? Same question as in the exporter above really.

Comment thread bug/op_edit_comment.go Outdated
}

// Convenience function to edit the body of a bug (the first comment)
func EditBody(b Interface, author identity.Interface, unixTime int64, message string) (*EditCommentOperation, error) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done. Also made the same edits in bug_cache.go

Comment thread doc/jira_bridge.md

## Configuration

As mentioned in the notes above, there are a few optional configuration fields

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done

Comment thread doc/jira_bridge.md
entry to our git-config:

```
create-issue-defaults = {"issuetype":"10001"}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Cool. Added TODO b610296 to look into this.

Comment thread doc/jira_bridge.md Outdated
You can specify the mapping between `git-bug` status and JIRA status id's using
the following:
```
bug-open-id = 1

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done.

@MichaelMure

Copy link
Copy Markdown
Contributor

So much teasing and no push ;)

@cheshirekow

Copy link
Copy Markdown
Contributor Author

So much teasing and no push ;)

Ah, yeah sorry. I can push when I am home tonight. I wanted to test and then report on the test results with the next update, but now I have to deal with this:

image

On one hand, it's good they support user API tokens... On the other hand, we'll probably need both code paths because companies are slow to upgrade their JIRA deployments.

@cheshirekow

Copy link
Copy Markdown
Contributor Author

I did a little testing with my jira cloud instance and things are looking good. I did:

  1. create a git-bug with a label, export to jira
  2. add a comment in jira, import to git-bug
  3. edit the description in git-bug, push to jira

I had to hack in support for the new jira token auth. I'll need to review the new git-bug token management API to get that plumbed in correctly (not hacky) though... and do a little more comprehensive testing. Feel free to comment further on the current state of the patch though. I don't think too much will change to get in the token auth support.

@MichaelMure

Copy link
Copy Markdown
Contributor

but now I have to deal with this

Ha bummer :( Github is doing that as well ... https://developer.github.com/changes/2019-11-05-deprecated-passwords-and-authorizations-api/

@MichaelMure MichaelMure left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Just a few things I noticed. Generally look very good, great work :)

As you mentioned, credentials stored through the core and a bit of standardization with the other bridges would be nice.

Automated testing against the jira instance, as it is done with github and gitlab would be very useful as well.

Comment thread bridge/jira/export.go
Comment thread bridge/jira/import.go Outdated
Comment thread bridge/jira/export.go Outdated
@MichaelMure

Copy link
Copy Markdown
Contributor

I'm working on generalizing the credential code in the core so it's easy to add more kind.

@cheshirekow cheshirekow left a comment •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ok, unhackified the two credentials-types jazz. I saw that you created a PR for a new credentials system for the core so I will take a look at that. I believe that all the review comments are addressed at this point. Pushing now...

Edit: here is my list of follow-up work:

8391e86 create unit tests against test instance
1121826 Add unit tests for utilities
0cf5c71 Assign git-bug to jira field on import
c70e22a implement additional query filters for import
8acce9c Download and cache workflow representation
67bf520 After JIRA mock, create integration tests
9ecefaa Create JIRA mock and add REST unit tests
0597088 use OS keyring for credentials
d3e8f79 You shouldn't count on the Total value in paginations

Comment thread bridge/jira/export.go Outdated
Comment thread bridge/jira/export.go
Comment thread bridge/jira/import.go Outdated
)

const (
keyOrigin = "origin"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done

Comment thread bridge/jira/import.go
// Create a bug.Comment from a JIRA comment
func (self *jiraImporter) ensureComment(
repo *cache.RepoCache, b *cache.BugCache, item Comment) error {
// ensure person

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Oh interesting. In the languages I usually work with splitting arguments at different indention would be frowned upon. Good to know though, I'll go ahead and fix this one here and try to follow that moving forward.

Comment thread bridge/jira/import.go Outdated
Comment thread doc/jira_bridge.md
Comment thread bridge/jira/client.go Outdated
password := conf[keyPassword]
if password == "" {
var err error
password, err = input.PromptPassword()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

ineffectual assignment to password (from ineffassign)

@MichaelMure MichaelMure added this to the 0.7.0 milestone Dec 11, 2019
@cheshirekow

Copy link
Copy Markdown
Contributor Author

Did some testing last night and fixed a couple of bugs. I still haven't rebased on the new credential system, so I guess that is up next. Things are looking good so far though and I think will start using this at work to shake out more bugs and inspire a test plan.

I'm going to resolve the open conversations on the review and make sure I didn't miss anything.

@cheshirekow

Copy link
Copy Markdown
Contributor Author

Update #5: I had to fix the git config parser in the core in order to correctly parse out a JSON map as a git config value. I also added the import/export warning events and used them. Lastly, I added a "reverse map" for bug ids, so that git-bug knows how to interpret JIRA statuses on import (if there are many).

@MichaelMure

Copy link
Copy Markdown
Contributor

Hey @cheshirekow what's up with this ? Do you need help ?

@cheshirekow

Copy link
Copy Markdown
Contributor Author

I rebased last week and resolved conflicts but it doesn't build due to interface requirements on the bridge. I guess you changed the bridge API? I haven't had time to dig in further.

As of the last commit all your comments have been addressed I think. It's fully functional and I've been using this branch as my daily driver for some weeks now.

Some help adapting to whatever the upstream changes were would be great!

@MichaelMure

Copy link
Copy Markdown
Contributor

Alright, I'll finish #294 and rebase/merge this.

If you have the time, an automated test similar as the other bridges would be great.

@MichaelMure

Copy link
Copy Markdown
Contributor

First merge, use of the new prompts and some cleanup. This need more work especially on the credential part.

@cheshirekow

Copy link
Copy Markdown
Contributor Author

Thanks for the push. I built this morning and my pull/push from JIRA worked just fine.

@MichaelMure

Copy link
Copy Markdown
Contributor

@cheshirekow do you think it would be possible to detect automatically the credential (session or token) ? That would simplify both the code and the UX.

@MichaelMure

Copy link
Copy Markdown
Contributor

Also, there is a mismatch between the name and value of this constant, what's the good concept ? metaKeyJiraOperationId = "jira-derived-id"

@cheshirekow

Copy link
Copy Markdown
Contributor Author

@cheshirekow do you think it would be possible to detect automatically the credential (session or token) ? That would simplify both the code and the UX.

Your idea in the other thread of trying some query with both credential types and just seeing what works makes sense.

Also, there is a mismatch between the name and value of this constant, what's the good concept ? metaKeyJiraOperationId = "jira-derived-id"

As I mentioned in the other thread, I'm not sure which is better to use, but I'm happy with either. Which do you prefer? I might suggest changing the name of the variable and keeping the metadata key just so I don't have to re-import my 1500-ish bugs that are already using "jira-derived-id" in their metadata. I'll go ahead and make that change.

@cheshirekow

Copy link
Copy Markdown
Contributor Author

Successful import from git-bug.atlassian.net and from my work jira so things look good with your credential changes. Thanks for pulling those in.

@MichaelMure

MichaelMure commented Feb 18, 2020 •

Copy link
Copy Markdown
Contributor

But what if you need to use two different account for two different bridges?

So, that would only matter for importing a private repo. For importing a public repo, any credential would do. For exporting, the bridge will match credentials based on the login, using whatever credential is needed for this specific piece of data.

So what could be done is for the bridges to store an additional information in their config: the login to use when importing (ie, the one used during the configuration). That would make more sense than using the first random one found.

@MichaelMure

Copy link
Copy Markdown
Contributor

So, does that means it's merge time ? What's left to do here ?

@MichaelMure

Copy link
Copy Markdown
Contributor

Ho, at least one thing would be to complete the Readme

@cheshirekow

Copy link
Copy Markdown
Contributor Author

So, does that means it's merge time ? What's left to do here ?

Ready from my end.

Ho, at least one thing would be to complete the Readme

You mean add "Jira" to the tables? Ok, I just pushed a change to do that.

@MichaelMure
MichaelMure merged commit b331833 into git-bug:master Feb 19, 2020
@MichaelMure

Copy link
Copy Markdown
Contributor

Weeeeeeeeeee 🎉 🎉 🎉 🎉 🎉 🎉

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