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

(WIP) Bitbucket integration #525

Closed
wants to merge 21 commits into from
Closed

(WIP) Bitbucket integration #525

wants to merge 21 commits into from

Conversation

zanedev
Copy link

@zanedev zanedev commented Aug 15, 2017

Fixes #234

- Summary

Adds bitbucket api backend support at a basic level.

  • Listing, Saving and Deleting works.
  • Files are pushed to the bitbucket api through their multipart form option.
  • No workflow support yet as it doesn't appear to be possible with the current bitbucket api but I will file another issue for workflow support and keep looking into separately, more important to get it working at all.
  • If workflow is enabled in the config, the app will operate as if workflow wasn't enabled and log a warning to the console.
  • Needs some work with refresh access tokens, currently it is not automatic in the code or ui so you must log out after a while and log back in manually.
  • isContributor check during login is skipped for now unless we want to add the potential of request looping all the user's repos to find it (see comments below)
  • @tech4him1 has tested that netlify.com's provided auth server works. I have been using a custom auth server:

TODO to wrap up this WIP:

  • get refresh token working once it's available on netlify side.
  • double check that we handle workflow setting properly to user
  • implement isContributor with looping paginated requests per @Benaiah

- Test plan

Change your cms admin config.yml file to point to a bitbucket repo. Setup oauth with bitbucket and an oauth server (or possibly netlify's oauth server). see example bitbucket client site project for example cms config

- Description for the changelog

Add basic bitbucket api backend support

- A picture of a cute animal (not mandatory but encouraged)

waranya-mooldee-57761

Photo by Waranya Mooldee on Unsplash

return this.api.deleteFile(path, commitMessage, options);
}

unpublishedEntries() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Should these functions be removed since the API does not support editorial workflow?

Copy link
Author

Choose a reason for hiding this comment

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

Ah good catch I missed those, will remove those and push again.

@tech4him1
Copy link
Contributor

@zanedev I'm not too familiar with the BitBucket API -- How does your implementation check if the user has permission to access the repo (like isCollaborator in the GitHub backend)?

@zanedev
Copy link
Author

zanedev commented Aug 15, 2017

@tech4him1 actually I spent quite a while trying to work out isCollaborator but couldn't figure out a way to do it with the bitbucket api. I found nowhere to check scopes/permissions on a repo like the github implementation. I thought at a minimum then we could list the users projects then querying that but it's a paginated list of all projects, it would take many queries to go through and I wasn't even sure if that meant they had the correct permissions. Anyway I figure we can come back to this when we figure out or they provide how to do it.

@tech4him1
Copy link
Contributor

tech4him1 commented Aug 15, 2017

@zanedev Does this work? You still have to implement pagination, so I don't know if its feasible, but the BB API has permission checking.

  isCollaborator(user) {
    return this.request(`/repositories/${ user.username }`, {
      params: { role: "contributor" },
    }).then((r) => {
      const repos = r.values;
      let contributor = false;
      for (const repo of repos) {
        // You may need to use `${ user.username }/${ repo.name }` here, I haven't tested it yet.
        if (repo.name === this.repo) contributor = true;
      }
      return contributor;
    }).catch(/*TODO*/)
  }

https://developer.atlassian.com/bitbucket/api/2/reference/resource/repositories/%7Busername%7D

@zanedev
Copy link
Author

zanedev commented Aug 15, 2017

@tech4him1 It does get a list of repos for the user but it's paginated by 10 per page, I personally have over 40, so it would need to keep requesting and paging. If you want me to add logic to to keep requesting until it reaches the end of the list I can do that. Just thought there had to be a better way to grab it directly rather than having to page it.

const uploadPromises = [];
const files = mediaFiles.concat(entry);

files.forEach((file) => {
Copy link
Contributor

@tech4him1 tech4him1 Aug 15, 2017

Choose a reason for hiding this comment

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

@zanedev This has been discussed before, and there are obviously pros and cons to both sides, but I wonder if it would be best to upload all the media files first, then upload the entry. That way, if there is a problem with one of the media files, the entry would not be broken. But that is an opinion, some people may prefer to have the content saved first. Anyone else?

Copy link
Author

Choose a reason for hiding this comment

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

I see no problem with doing media files first. I feel like all of these backend implementations need to be refactored to have some shared code to avoid code/logic duplication however.. Maybe it's best to do it all at once for all backends so they follow the same logic and we don't further spaghetti weave it.

Copy link
Contributor

Choose a reason for hiding this comment

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

@tortilaman and I were actually already talking about combining the backends: https://gitter.im/netlify/NetlifyCMS?at=5989e0e91c8697534a9c1a7d, as I totally think that is an awesome idea. He was going to make an issue for it, but I'm not sure if he got around to that yet.

Copy link
Author

Choose a reason for hiding this comment

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

Yeah I think someone would have to own it across the board to do that it would be a big effort requiring ongoing maintenance and way more testing etc. Not sure if it's worth it yet. But some sort of shared interface would be a good start at least. Typescript might be a good fit for something this delicate.

@Benaiah Benaiah changed the title Bitbucket integration (WIP) Bitbucket integration Aug 15, 2017
@tech4him1
Copy link
Contributor

tech4him1 commented Aug 15, 2017

A basic setup is working for me!

@zanedev zanedev self-assigned this Aug 15, 2017
@zanedev
Copy link
Author

zanedev commented Aug 22, 2017

isCollaborator is implemented and a graceful way to handle backends with unsupported workflow. Let me know if you have other ideas about unsupported workflow, wasn't sure the best way.

return this.request("/user");
}

isCollaborator(user) {
Copy link
Contributor

@tech4him1 tech4him1 Aug 22, 2017

Choose a reason for hiding this comment

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

isCollaborator was changed to hasWriteAccess in #543.

Copy link
Author

Choose a reason for hiding this comment

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

Ok will update and push again

Copy link
Contributor

Choose a reason for hiding this comment

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

It was kind of a last minute thing, thanks!

Copy link
Author

Choose a reason for hiding this comment

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

np renamed and pushed, looking at token refresh stuff now

@@ -277,6 +278,13 @@ class Backend {
entry.data[filterRule.get('field')] === filterRule.get('value')
));
}

supportsWorkflow() {
if(typeof this.implementation.supportsWorkflow === "function")
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if it would be better to just add this function to all the backends instead of this?

Copy link
Author

Choose a reason for hiding this comment

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

Yeah not sure just thought it was more self contained this way at the time but since there are a few backends that don't support workflow now (unfortunately) then it makes sense to add it to all of them. btw, I hope that we can implement workflow for bitbucket and gitlab sooner than later, I think we should create separate issues so they don't fall through the cracks.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, I think we need to figure out which way is best so that we can keep our PR's the same.

Copy link
Contributor

@erquhart erquhart Aug 30, 2017

Choose a reason for hiding this comment

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

I prefer this approach, but it takes us halfway to what we really need, which is some sort of capabilities record for each backend, of which editorial workflow would be one. For now, I think @tech4him1's approach is ideal in its simplicity.

Copy link
Contributor

Choose a reason for hiding this comment

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

@zanedev The code that I had just checks to see if editorial workflow is enabled, the user doesn't have to have any other config value.

Copy link
Contributor

@tech4him1 tech4him1 Aug 30, 2017

Choose a reason for hiding this comment

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

Well, it is an actual config.yml value, but it is just the one that is used to enable editorial workflow anyway (publish_mode: editorial_workflow). Do you think there is a better way @zanedev?

Copy link
Author

Choose a reason for hiding this comment

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

yep I was mistaken in my original comment.. already pushed a version that matches yours.

Copy link
Contributor

Choose a reason for hiding this comment

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

OK, great. I think we should move to something more like what you had down the road, though, it just seems a little complicated for integrating right now.

Copy link
Contributor

Choose a reason for hiding this comment

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

btw, I hope that we can implement workflow for bitbucket and gitlab sooner than later, I think we should create separate issues so they don't fall through the cracks.

@zanedev I made an issue at #568 for discussing how to do EW on these backends.

Copy link
Author

Choose a reason for hiding this comment

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

thanks i've been meaning to do that..

@scher200
Copy link

@tech4him1 @tech4him1 you guys rock. Is there anything I can help with?

@kristyjy
Copy link

Is this close to being ready to merge in? If I can help at all I'm willing to do so. I'd like to use Netlify CMS and not have to move our repo. :)

@erquhart
Copy link
Contributor

Hi @scher200, @kristyjy - we definitely want to get this in, it just slowed up because focus has been on prepping 1.0, which is slated for early December.

We've also discussed having a beta release line so that work like this can get out in the wild for those that want it before it's ready to hit master. But yes, by all means come pitch in! There are some TODO items in the summary up top that I'll re-paste here:

TODO to wrap up this WIP:

  • get refresh token working once it's available on netlify side.
  • double check that we handle workflow setting properly to user
  • implement isContributor with looping paginated requests per @Benaiah

I'm not up to speed on the refresh token issue, but it basically means the CMS stops working when your token expires, and the user has to know to log out and log back in when this occurs. I believe @biilmann had some ideas on how we might get around this, but it's been a while.

I'm not really sure what isContributor has to do with pagination, @Benaiah can you shed some light on that?

@tech4him1
Copy link
Contributor

@erquhart Once we get #560 merged, that would provide at least a manual token refresh, though we would probably still want to work on an automatic one.

@mikestopcontinues
Copy link

Hey, what's the status of this PR? Do you need any help?

@scher200
Copy link

@mikestopcontinues sorry men, I stopped bothering about this, and switched git provider.

@tech4him1
Copy link
Contributor

@mikestopcontinues @scher200 Now that 1.0 has been released, this will be one of our primary focuses.

@mikestopcontinues
Copy link

@tech4him1, awesome! Thanks!

@zanedev
Copy link
Author

zanedev commented Dec 12, 2017

Yeah the only major blocker here is token refresh. @mikestopcontinues If you want to use it now there is a sample auth server repo linked in the description but you'd need to modify it to work with your bitbucket settings. And the PR is a bit out of date so you'd probably need to merge in master/1.0 code to stay up to date.

@maniflames
Copy link

Hi, is the merge working out?
I would like to use netlify cms with bitbucket and am willing to help!

@george-oakling
Copy link

Hi, me too. I am also willing to help with anything :)

@tech4him1
Copy link
Contributor

@zanedev If you are interested in integrating it, there is working code for a manual re-auth popup in #560.

@zanedev
Copy link
Author

zanedev commented Jan 5, 2018

@tech4him1 sounds cool unfortunately I'm swamped for the next month or two.. I'll try to to get some time to at least get this PR up to date with master but there will still be the refresh token issue so not sure it's worth doing anything until that is provided on the netlify side somehow..

@tech4him1
Copy link
Contributor

@zanedev No problem at all! #560 would be a "manual" type fix for the refresh token issue.

@erquhart erquhart force-pushed the bitbucket-integration branch from b413033 to 7b4ed27 Compare February 2, 2018 18:42
@verythorough
Copy link
Contributor

verythorough commented Feb 2, 2018

Deploy preview for netlify-cms-www ready!

Built with commit 0dd1495

https://deploy-preview-525--netlify-cms-www.netlify.com

@erquhart erquhart force-pushed the bitbucket-integration branch from 1476eac to 0dd1495 Compare February 2, 2018 19:23
@erquhart
Copy link
Contributor

erquhart commented Feb 2, 2018

Update: rebased and updated for 1.x compatibility.

@verythorough
Copy link
Contributor

Deploy preview for cms-demo ready!

Built with commit 0dd1495

https://deploy-preview-525--cms-demo.netlify.com

@george-oakling
Copy link

I made some updates to Bitbucket integration API and implementation (media and hasWriteAccess), where should I post my code please? I never got it how to update foreign pull-request, so if somebody can help me with that :)

@tech4him1
Copy link
Contributor

@george-oakling You can make a new PR, and set the base branch to bitbucket-integration instead of master.

@george-oakling
Copy link

#1098

@woutrbe
Copy link

woutrbe commented Mar 18, 2018

Is there any timeline to get this released?

@erquhart
Copy link
Contributor

@Benaiah you mentioned Bitbucket and GitLab support coming once we have the minimal required improvements in place, can you give a rough estimate?

@Benaiah
Copy link
Contributor

Benaiah commented Mar 22, 2018

It's well past time for an update on the progress of this and the GitLab PR - apologies for the radio silence. With that said, I've laid out the current plan for this PR below.

Before merge

I'll check these off as they're addressed by PRs, and link to any PRs implementing them. Most of these steps are shared with those of the GitLab backend, since they are modifications of code that's used by both.

  • Add actions and reducers to support cursor traversal
    • next
    • previous
    • first
    • last
  • Add capabilities functionality to determine data available and controls shown.
  • Refactor backend API in backend.js to allow backends to return a cursor (currently only integrations can return pagination information from listEntries)
  • Refactor entry listing methods in existing BitBucket backend to ignore cursors (if necessary).
  • Add cursor traversal functions to BitBucket backend
    • Refactor request to allow functions calling it to retrieve headers.
    • Return a cursor from entry listing functions (backend.js must be refactored first to allow returning anything other than entries).
    • Implement cursor capabilities and traversal functions
  • Ensure new cursor structure is compatible with editorial workflow (cursors won't be implemented for that immediately)
  • Ensure new cursor structure does not break integrations
  • Create pagination UI
  • Refresh token and auth improvements

Rough timeline

The dates are approximate, but this is a rough idea of when I think certain updates will happen:

  • Today: Actions and reducers mostly finished, backend.js cursor support is in progress. About to start refactoring currently merged backends to "support" (i.e., ignore) the cursor API in listEntries.
  • Mar 26-30: Release PR for actions, reducers, backend.js refactor, and merged backends modifications.
  • Apr 2-6: Update GitLab PR with cursor support.
  • Apr 2-6: Update BitBucket PR with cursor support.
  • Apr ~13: Release PR for pagination UI.
  • Apr ~20: Merge BitBucket and GitLab.

The work on the new backend design will be concurrent with this, but pre-merge work is the priority.

After merge

  • Git Gateway
  • Editorial workflow

@Benaiah
Copy link
Contributor

Benaiah commented Apr 17, 2018

Update

This is still underway, but it's now planned to merge the GitLab backend first and then update and merge this PR. Quoting from my comment on the GitLab PR:

I still believe the end of April is a realistic goal for merging GitLab, but the BitBucket backend hasn't received quite as much attention yet. Once GitLab and the refactoring it's based on are merged, finishing my updates to the BitBucket PR will be my top priority. If all goes well in the implementation, it shouldn't take more than a week or two to get it updated and merged once we reach that point.

@pogo19
Copy link

pogo19 commented Apr 17, 2018

I still want to use NetlifyCMS with Gatsby and BitBucket. I will be happy to help with some testing.

@gouravsood
Copy link

I am also interested in using NetlifyCMS with Bitbucket. I can be beta tester of the this PR 👍

@erquhart
Copy link
Contributor

To all watchers: keep an eye on the current GitLab PR, as the underlying work is prerequisite to Bitbucket support.

@FullstackJack
Copy link

Yes, I'd also like to test this with React-Static

@jaredmorgs
Copy link

OMG I'm so excited to see that the GitLab support has been released. Great work team on getting this out.

Can't wait to see what's remaining now the Bitbucket side, because I would totally select NetlifyCMS over Forestry.io

I really like the editorial flow in Netlify CMS compared to Forestry.io, so I'm keen as to test it out in beta and help resolve the PR.

@lukeblair
Copy link

Any progress update on this? We've got a team of people that'd love to use this CMS, but bitbucket integration is a prerequisite for our use case.

@erquhart
Copy link
Contributor

Closing in favor of #1504.

@erquhart erquhart closed this Jul 20, 2018
@erezrokah erezrokah deleted the bitbucket-integration branch February 7, 2021 15:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Netlify CMS on Bitbucket