mirror of
https://github.com/renovatebot/renovate.git
synced 2026-11-02 10:33:39 +00:00
ad63dddef7
On 2026-02-20, Atlassian announced that they would be removing the
native issue tracker in Bitbucket Cloud[0].
As of 2026-08-24[1], this change is now complete.
When Renovate attempts to update an existing Dependency Dashboard Issue,
we see:
DEBUG: GET https://api.bitbucket.org/2.0/repositories/some/repo/issues?q=... = (code=ERR_NON_2XX_3XX_RESPONSE, statusCode=410 retryCount=0, duration=87)
WARN: Error finding issues
And when trying to create one, we see:
DEBUG: findIssue(Dependency Dashboard)
DEBUG: Issues are disabled - cannot findIssue
Because it's not possible - until #20568 - to use another source for
Issues on Bitbucket Cloud, we need to remove support for the Dependency
Dashboard.
When we do try and interact with them, we can DEBUG log as to why it's a
no-op (similar to `platform=bitbucket-server`), and reference the deprecation.
As we now don't touch Issues, we can remove the additional permissions
that were previously required.
As there are no longer Issues, we can remove `has_issues` from our
types.
As well as the Dependency Dashboard, this also means that i.e. Config
Warning Issues are no longer available.
[0]: https://developer.atlassian.com/cloud/bitbucket/changelog/#CHANGE-3071
[0]: https://developer.atlassian.com/cloud/bitbucket/changelog/#CHANGE-3401
Co-authored-by: Claude Opus 5 <jamie.tanna+claude-code@mend.io>
105 lines
2.4 KiB
TypeScript
105 lines
2.4 KiB
TypeScript
import { z } from 'zod/v4';
|
|
import { logger } from '../../../logger/index.ts';
|
|
import { regEx } from '../../../util/regex.ts';
|
|
import { LooseArray } from '../../../util/schema-utils/index.ts';
|
|
|
|
const BitbucketSourceType = z.enum(['commit_directory', 'commit_file']);
|
|
|
|
const SourceResults = z.object({
|
|
path: z.string(),
|
|
type: BitbucketSourceType,
|
|
commit: z.object({
|
|
hash: z.string(),
|
|
}),
|
|
});
|
|
|
|
const Paged = z.object({
|
|
page: z.number().optional(),
|
|
pagelen: z.number(),
|
|
size: z.number().optional(),
|
|
next: z.string().optional(),
|
|
});
|
|
|
|
export const PagedSourceResults = Paged.extend({
|
|
values: z.array(SourceResults),
|
|
});
|
|
|
|
export const RepoInfo = z
|
|
.object({
|
|
parent: z.unknown().optional().catch(undefined),
|
|
mainbranch: z.object({
|
|
name: z.string(),
|
|
}),
|
|
uuid: z.string(),
|
|
full_name: z
|
|
.string()
|
|
.regex(
|
|
regEx(/^[^/]+\/[^/]+$/),
|
|
'Expected repository full_name to be in the format "owner/repo"',
|
|
),
|
|
is_private: z.boolean().catch(() => {
|
|
logger.once.warn('Bitbucket: "is_private" field missing from repo info');
|
|
return true;
|
|
}),
|
|
project: z
|
|
.object({
|
|
name: z.string(),
|
|
})
|
|
.nullable()
|
|
.catch(null),
|
|
})
|
|
.transform((repoInfoBody) => {
|
|
const isFork = !!repoInfoBody.parent;
|
|
const [owner, name] = repoInfoBody.full_name.split('/');
|
|
|
|
return {
|
|
isFork,
|
|
owner,
|
|
name,
|
|
mainbranch: repoInfoBody.mainbranch.name,
|
|
mergeMethod: 'merge',
|
|
uuid: repoInfoBody.uuid,
|
|
is_private: repoInfoBody.is_private,
|
|
projectName: repoInfoBody.project?.name,
|
|
};
|
|
});
|
|
export type RepoInfo = z.infer<typeof RepoInfo>;
|
|
|
|
export const Repositories = z
|
|
.object({
|
|
values: LooseArray(RepoInfo),
|
|
})
|
|
.transform((body) => body.values);
|
|
|
|
const TaskState = z.union([z.literal('RESOLVED'), z.literal('UNRESOLVED')]);
|
|
|
|
const PrTask = z.object({
|
|
id: z.number(),
|
|
state: TaskState,
|
|
content: z.object({
|
|
raw: z.string(),
|
|
}),
|
|
});
|
|
|
|
export type PrTask = z.infer<typeof PrTask>;
|
|
|
|
export const UnresolvedPrTasks = z
|
|
.object({
|
|
values: z.array(PrTask),
|
|
})
|
|
.transform((data) =>
|
|
data.values.filter((task) => task.state === 'UNRESOLVED'),
|
|
);
|
|
|
|
const WorkspaceAccess = z.object({
|
|
workspace: z.object({
|
|
slug: z.string(),
|
|
}),
|
|
});
|
|
|
|
export const WorkspaceAccesses = z
|
|
.object({
|
|
values: z.array(WorkspaceAccess),
|
|
})
|
|
.transform((body) => body.values.map(({ workspace }) => workspace.slug));
|