Come for the products,
stay for the community

The Atlassian Community can help you and your team get more value out of Atlassian products and practices.

Atlassian Community about banner
4,298,492
Community Members
 
Community Events
165
Community Groups

Services feature end of support

I received the following email: 

 

"We noticed you are an admin for a Bitbucket Cloud repository that is still utilizing our original Services feature. We had previously announced that we will end support for this feature and recommended migrating repositories to Bitbucket webhooks."

 

That's great, but I have a couple hundred repositories. How do you know which one is using the "Services" feature? Do I have to check every repository??

6 answers

1 accepted

Jeremiah, thanks for this starter script! There are a few optimizations that should fix any insufficient resource issues. For starters, if you use ?role=admin you'll get a smaller subset of all repositories. Also, with BBQL you can restrict the size of the repository response to only include the workspace slug + repository slug. Your new URL should be:

https://bitbucket.org/!api/2.0/repositories?role=admin&pagelen=100&fields=*,values.full_name 


The bigger fix is using our v1.0 API, which is deprecated but can temporarily be queried to check which of your repositories have services that need to be replaced with webhooks. For more information: see our deprecation notice.

https://bitbucket.org/!api/1.0/repositories/${repository.full_name}/services 

 

The script would then look like this:

(async () => {
let repositoriesPage = 1;

const parseRepositoriesResp = async (resp) => {
    console.log(`Fetched repositories page ${repositoriesPage}`);
    const respJSON = await resp.json();

    if (respJSON.next !== undefined) {
        repositoriesPage++;
        return [
            ...respJSON.values,
            ...(await fetch(respJSON.next).then(parseRepositoriesResp)),
        ];
    }
    return respJSON.values;
};

const parseServicesResp = async (resp) => {
    const services = await resp.json();
    if (services.length > 0) {
        return services.filter(service =>
            service.service.type !== "Issues"
        );
    }
}

console.log('Fetching repositories…');

const repositories = await fetch('https://bitbucket.org/!api/2.0/repositories?role=admin&pagelen=100&fields=*,values.full_name')
.then(parseRepositoriesResp);

console.log('Done fetching repositories');

console.log('Checking for usage of Services…');

const servicesUrls = (
    await Promise.all(repositories.map(async (repository) => {
        const adminHooksUrl = `https://bitbucket.org/!api/1.0/repositories/${repository.full_name}/services`;
        // console.log(`Checking ${repository.full_name}…`);
const servicesAdminUrl = `https://bitbucket.org/${repository.full_name}/admin/hooks`; const repositoryServices = await fetch(adminHooksUrl).then(parseServicesResp); if (repositoryServices !== undefined && repositoryServices.length > 0) { // console.log(`Repository ${repository.full_name} has services`, repositoryServices) return servicesAdminUrl; } })) ).filter(repo => repo !== undefined); console.log('Done checking for usage of Services'); console.log('Repositories that use Services:', servicesUrls); })();

 

UPDATE: Please see @Leah Rivkin's amazing answer below, which is much more efficient. Thanks Leah!


I hacked something together to detect which repositories use Services. Open a JavaScript console on a page on bitbucket.org and run the following:

repositoriesPage = 1; parseRepositoriesResp = async (resp) => { console.log(`Fetched repositories page ${repositoriesPage}`); const respJSON = await resp.json(); if (respJSON.next !== undefined) { repositoriesPage++; return [...respJSON.values, ...(await fetch(respJSON.next).then(parseRepositoriesResp))]; } else { return respJSON.values; } }; domParser = new DOMParser(); console.log('Fetching repositories…'); repositories = await fetch('https://bitbucket.org/!api/2.0/repositories?role=member&pagelen=100').then(parseRepositoriesResp); console.log('Done fetching repositories'); console.log('Checking for usage of Services…'); servicesUrls = (await Promise.all(repositories.map(async (repository) => { const adminHooksUrl = `https://bitbucket.org/${repository.workspace.slug}/${repository.slug}/admin/hooks?iframe=true`; console.log(`Checking ${repository.workspace.slug}/${repository.slug}…`); return await fetch(adminHooksUrl).then(async (resp) => { if (!resp.ok) { return; } const respHTML = domParser.parseFromString(await resp.text(), 'text/html'); if (respHTML.getElementsByClassName('hook').length > 0) { return adminHooksUrl; } }); }))).filter(adminHooksUrl => adminHooksUrl !== undefined); console.log('Done checking for usage of Services'); console.log('Repositories that use Services:', servicesUrls);

This will output an array of URLs for repositories that use Services.

Note that you may see HTTP 403 (Forbidden) errors while it's running; you can ignore these.

You sir are a steely-eyed missile man!  Thanks for this.

Like # people like this

it runs but it IDed repos that do not have Services setup, I will try and debug it but it does find one that has it but some that do not.

I have to update, the script runs and it did id all of them correctly, it is just finding stuff that the BiuBucket UI does not list having Services but when you use the URL returned by Jeremiah's script it does show services on.

 

Great job Jeremiah

Like Jeremiah likes this

Ok, now that was Brilliant!  Thanks so much for sharing!!!

Thanks, you are a true JS wizard

Nice, thanks!

Pretty much all of what’s been said about the "helpful" message from Atlassian was what we were discussing in the team this morning…

What even are those Services? And in which of our many repos do we use them??

My colleague then found this thread here and we had a good laugh due to all the comments that stated exactly what we were discussing before.

And then… This script snippet! Ran this in the console and there was the list of (pretty old) repos that use these services. One should think that it should also be possible for Atlassian to generate such a list and inform their users with more details… but yeah.

Thank you very much Jeremiah! Great job.

Thank you Jeremiah, this worked perfectly. Would indeed have been nice if the 'affected' repos were provided by Atlassian or could be found more easily.

Hi.

I usually do not run java scripts, so I am a bit at a loss when things go wrong.

We have a huge Bitbucket instance, and when I try to run the script in the Chrome Console, I get an ERR_INSUFFICIENT_RESOURCES error.

How can I increase the resources for the script to run to the end?

Thanks for your script. I realized that there are a lot of repositories that only have one service: Issues.

Just to save some time to those that would run into the same circumstance, it is good to know that said service is added as a hook when you add a Private (maybe also Public) Issue tracker (the one that comes with BitBucket, not Jira). It also happens when you do it now.... Which seems crazy, since it is done automatically by Atlassian, and it is using something that it is deprecated.

Yeah, I think you can probably disregard the repos that only have the Issues service and no other services since the "Services" link doesn't even show up in the admin UI if that's the case. I could be wrong but I updated the script to filter out those repos.

(async () => {
let repositoriesPage = 1;

const parseRepositoriesResp = async (resp) => {
console.log(`Fetched repositories page ${repositoriesPage}`);
const respJSON = await resp.json();
if (respJSON.next !== undefined) {
repositoriesPage++;
return [
...respJSON.values,
...(await fetch(respJSON.next).then(parseRepositoriesResp)),
];
}

return respJSON.values;
};

const domParser = new DOMParser();
console.log('Fetching repositories…');

const repositories = await fetch('https://bitbucket.org/!api/2.0/repositories?role=member&pagelen=100')
.then(parseRepositoriesResp);
console.log('Done fetching repositories');
console.log('Checking for usage of Services…');
const servicesUrls = (
await Promise.all(repositories.map(async (repository) => {
const adminHooksUrl = `https://bitbucket.org/${repository.workspace.slug}/${repository.slug}/admin/hooks?iframe=true`;
console.log('adminHooksUrl:', adminHooksUrl);
console.log(`Checking ${repository.workspace.slug}/${repository.slug}…`);
return fetch(adminHooksUrl)
.then(async (resp) => {
if (!resp.ok) {
return;
}
const respHTML = domParser.parseFromString(await resp.text(), 'text/html');
const services = Array.from(respHTML.getElementsByClassName('hook-name'))
.map((el) => el.innerText && el.innerText.trim())
.filter((issue) => issue !== 'Issues');
if (services.length) {
return adminHooksUrl;
}
});
}))
).filter((adminHooksUrl) => adminHooksUrl !== undefined);
console.log('Done checking for usage of Services');
console.log('Repositories that use Services:', servicesUrls);
})(); 
Like Patrick Decat likes this

The `net::ERR_INSUFFICIENT_RESOURCES` error seems to only be an issue in Chrome, and does not happen in Firefox.

Like Applied Geographics likes this

Thanx. It worked in Firefox.

Like Patrick Decat likes this

I'm in the same boat. The email is the most unhelpful communication ever. Either it should contain information about the affected repositories, or there should be an easy way to find out which they are.

It would also be useful if it said what these "Original Services" actually are. I've never used them and nor have any of my current colleagues. Presumably a former colleague must have. Searching for "bitbucket services", unsurprisingly, yields nothing relevent and a lot of noise.

Like # people like this

Same with us.  You all stated it perfectly.  Hopefully Atlassian will provide some clarification either on this thread or in a follow-up email. Or if someone else figures out how to see that a repo is at risk, they can post it here.  What a pain to go through several hundred repos though.  We'd have been extremely grateful to get a listing of which of our repos are at risk.

Like # people like this

Ok, we were in the same boat, and here's what I've found by poking around.  The email sent has a link to "previously announced", and I see that end-of-life was originally announced for July 1, 2019.  Again, it refers to some "Services" feature.  When I go to a repo in BitBucket and go to Repository settings under "Workflow", I see "Webhooks" but do not see "Services".  But then I went to one of our oldest repos (made a LONG time ago) and, behold, there IS a "Services" option in the Repository Settings under Workflow.  Under "Webhooks" is "Links" and then after that is "Services".  And, sure enough, there are some really old POST services defined.  Probably a left-over of some old integration we no longer use.

Go to "Repository Settings", and IF there is a menu option "Services" under the "Workflow" menu section, there are items there to be deleted or replaced with Webhooks.

But I sure wish there was a way to get a listing of offending repos.

Found this older announcement - https://bitbucket.org/blog/the-new-bitbucket-webhooks - showing both a screenshot describing what you've found here @Chris Birch as well as a mention of "Services" previously being named "POST and Pull Request POST" hooks.

Like # people like this
seanaty Atlassian Team Nov 03, 2021

But then I went to one of our oldest repos (made a LONG time ago) and, behold, there IS a "Services" option in the Repository Settings under Workflow.

The feature was soft-deprecated in 2019. Effectively making it such that no one could add a new service and also hiding the "Services" section in the UI unless a repository already had one set.

As you can assume from the email announcement, the were never removed after that soft deprecation and we are doing it now.

Like # people like this

We ended up writing a quick WebDriver script to comb through our repos looking for anything with the "Services" link in the left navigation menu...already had a similar script and was easy to repurpose it. I figured there may have been an API that we could have used but was feeling adventurous.

Many thanks to Jeremiah and Applied Geographics for the script, and Leah at Atlassian too. We have now tracked down and removed the offending services from our repos.

Leah and seanaty, perhaps you could feed back to the appropriate people at Atlassian just how lucky they are to have people like Jeremiah and Applied Geographics as customers, to fill in the gaps in their communications. If you haven't already, of course.

It gets even more fuzzy for me when I read this page: https://support.atlassian.com/bitbucket-cloud/docs/view-end-of-support-announcements-for-bitbucket-cloud/?utm_source=alert-email&utm_medium=email&utm_campaign=bb-service-feature_EML-11583&jobid=105241631&subid=1531747445

Do I understand it correctly that pulling and pushing with git from my host machine's terminal will also be suspended? I mean, technically those are Git operations over HTTPS, right?

seanaty Atlassian Team Nov 03, 2021

No. Relevant thread here: https://community.atlassian.com/t5/Bitbucket-questions/What-does-end-of-support-for-passwords-mean-for-me/qaq-p/1851002

Really concise explanation:

You current Atlassian PW will only work for logging into the web UI. Any other auth (API, git over HTTPS) will require you to create a new app password.

Like benzhi86 likes this

Thanks for the explanation!

Suggest an answer

Log in or Sign up to answer
TAGS
Community showcase
Published in Bitbucket

Git push size limits are coming to Bitbucket Cloud starting April 4th, 2022

Beginning on April 4th, we will be implementing push limits. This means that your push cannot be completed if it is over 3.5 GB. If you do attempt to complete a push that is over 3.5 GB, it will fail...

2,229 views 2 9
Read article

Community Events

Connect with like-minded Atlassian users at free events near you!

Find an event

Connect with like-minded Atlassian users at free events near you!

Unfortunately there are no Community Events near you at the moment.

Host an event

You're one step closer to meeting fellow Atlassian users at your local event. Learn more about Community Events

Events near you