fix(scaffolder): Create repository in personal namespace
Signed-off-by: Gabriel Dugny <gabriel.dugny@believe.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend-module-gitlab': patch
|
||||
---
|
||||
|
||||
fix: Creating a repository in a user namespace would always lead to an error
|
||||
@@ -44,6 +44,7 @@ const mockGitlabClient = {
|
||||
},
|
||||
Users: {
|
||||
showCurrentUser: jest.fn(),
|
||||
allProjects: jest.fn(),
|
||||
},
|
||||
ProjectMembers: {
|
||||
add: jest.fn(),
|
||||
@@ -211,7 +212,7 @@ describe('publish:gitlab', () => {
|
||||
expect(mockGitlabClient.ProtectedBranches.protect).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should call the correct Gitlab APIs when the owner is an organization', async () => {
|
||||
it('should call the correct Gitlab APIs when the owner is a group', async () => {
|
||||
mockGitlabClient.Users.showCurrentUser.mockResolvedValue({ id: 12345 });
|
||||
mockGitlabClient.Namespaces.show.mockResolvedValue({ id: 1234 });
|
||||
mockGitlabClient.Groups.allProjects.mockResolvedValue([]);
|
||||
@@ -232,16 +233,18 @@ describe('publish:gitlab', () => {
|
||||
expect(mockGitlabClient.ProtectedBranches.protect).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should call the correct Gitlab APIs when the owner is not an organization', async () => {
|
||||
it('should call the correct Gitlab APIs when the owner is a user', async () => {
|
||||
mockGitlabClient.Namespaces.show.mockResolvedValue({ id: null });
|
||||
mockGitlabClient.Users.showCurrentUser.mockResolvedValue({ id: 12345 });
|
||||
mockGitlabClient.Groups.allProjects.mockResolvedValue([]);
|
||||
mockGitlabClient.Groups.allProjects.mockRejectedValue({});
|
||||
mockGitlabClient.Users.allProjects.mockResolvedValue([]);
|
||||
mockGitlabClient.Projects.create.mockResolvedValue({
|
||||
http_url_to_repo: 'http://mockurl.git',
|
||||
});
|
||||
|
||||
await action.handler(mockContext);
|
||||
|
||||
expect(mockGitlabClient.Groups.allProjects).not.toHaveBeenCalled();
|
||||
expect(mockGitlabClient.Namespaces.show).toHaveBeenCalledWith('owner');
|
||||
expect(mockGitlabClient.Projects.create).toHaveBeenCalledWith({
|
||||
namespaceId: 12345,
|
||||
@@ -253,9 +256,12 @@ describe('publish:gitlab', () => {
|
||||
expect(mockGitlabClient.ProtectedBranches.protect).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not call the creation Gitlab APIs when the repository already exists', async () => {
|
||||
it('should not call the creation Gitlab APIs when the repository already exists in a group', async () => {
|
||||
mockGitlabClient.Users.showCurrentUser.mockResolvedValue({ id: 12345 });
|
||||
mockGitlabClient.Namespaces.show.mockResolvedValue({ id: 1234 });
|
||||
mockGitlabClient.Namespaces.show.mockResolvedValue({
|
||||
id: 1234,
|
||||
kind: 'group',
|
||||
});
|
||||
mockGitlabClient.Groups.allProjects.mockResolvedValue([
|
||||
{
|
||||
path: 'repo',
|
||||
@@ -278,9 +284,41 @@ describe('publish:gitlab', () => {
|
||||
expect(mockGitlabClient.ProtectedBranches.protect).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not call the creation Gitlab APIs when the repository already exists in a user namespace', async () => {
|
||||
mockGitlabClient.Users.showCurrentUser.mockResolvedValue({ id: 12345 });
|
||||
mockGitlabClient.Namespaces.show.mockResolvedValue({
|
||||
id: 12345,
|
||||
kind: 'user',
|
||||
});
|
||||
mockGitlabClient.Users.allProjects.mockResolvedValue([
|
||||
{
|
||||
path: 'repo',
|
||||
http_url_to_repo: 'http://mockurl.git',
|
||||
},
|
||||
{
|
||||
path: 'repo-name',
|
||||
http_url_to_repo: 'http://mockurl.git',
|
||||
},
|
||||
]);
|
||||
|
||||
await action.handler({
|
||||
...mockContext,
|
||||
input: { ...mockContext.input, skipExisting: true },
|
||||
});
|
||||
|
||||
expect(mockGitlabClient.Groups.allProjects).not.toHaveBeenCalled();
|
||||
expect(mockGitlabClient.Namespaces.show).toHaveBeenCalledWith('owner');
|
||||
expect(mockGitlabClient.Projects.create).not.toHaveBeenCalled();
|
||||
expect(mockGitlabClient.Branches.create).not.toHaveBeenCalled();
|
||||
expect(mockGitlabClient.ProtectedBranches.protect).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should call the creation Gitlab APIs when the repository does not yet exists', async () => {
|
||||
mockGitlabClient.Users.showCurrentUser.mockResolvedValue({ id: 12345 });
|
||||
mockGitlabClient.Namespaces.show.mockResolvedValue({ id: 1234 });
|
||||
mockGitlabClient.Namespaces.show.mockResolvedValue({
|
||||
id: 1234,
|
||||
kind: 'group',
|
||||
});
|
||||
mockGitlabClient.Groups.allProjects.mockResolvedValue([
|
||||
{
|
||||
path: 'repo-name',
|
||||
@@ -305,7 +343,10 @@ describe('publish:gitlab', () => {
|
||||
|
||||
it('should call the correct Gitlab APIs when using project settings with override of visibility and topics', async () => {
|
||||
mockGitlabClient.Users.showCurrentUser.mockResolvedValue({ id: 12345 });
|
||||
mockGitlabClient.Namespaces.show.mockResolvedValue({ id: 1234 });
|
||||
mockGitlabClient.Namespaces.show.mockResolvedValue({
|
||||
id: 1234,
|
||||
kind: 'group',
|
||||
});
|
||||
mockGitlabClient.Groups.allProjects.mockResolvedValue([]);
|
||||
mockGitlabClient.Projects.create.mockResolvedValue({
|
||||
http_url_to_repo: 'http://mockurl.git',
|
||||
@@ -327,7 +368,10 @@ describe('publish:gitlab', () => {
|
||||
|
||||
it('should call the correct Gitlab APIs for branches and protectd branches when branch settings provided', async () => {
|
||||
mockGitlabClient.Users.showCurrentUser.mockResolvedValue({ id: 12345 });
|
||||
mockGitlabClient.Namespaces.show.mockResolvedValue({ id: 1234 });
|
||||
mockGitlabClient.Namespaces.show.mockResolvedValue({
|
||||
id: 1234,
|
||||
kind: 'group',
|
||||
});
|
||||
mockGitlabClient.Groups.allProjects.mockResolvedValue([]);
|
||||
mockGitlabClient.Projects.create.mockResolvedValue({
|
||||
id: 123456,
|
||||
@@ -368,7 +412,10 @@ describe('publish:gitlab', () => {
|
||||
|
||||
it('should call the correct Gitlab APIs for variables when their configuration is provided', async () => {
|
||||
mockGitlabClient.Users.showCurrentUser.mockResolvedValue({ id: 12345 });
|
||||
mockGitlabClient.Namespaces.show.mockResolvedValue({ id: 1234 });
|
||||
mockGitlabClient.Namespaces.show.mockResolvedValue({
|
||||
id: 1234,
|
||||
kind: 'group',
|
||||
});
|
||||
mockGitlabClient.Groups.allProjects.mockResolvedValue([]);
|
||||
mockGitlabClient.Projects.create.mockResolvedValue({
|
||||
id: 123456,
|
||||
@@ -401,7 +448,10 @@ describe('publish:gitlab', () => {
|
||||
|
||||
it('should call initRepoAndPush with the correct values', async () => {
|
||||
mockGitlabClient.Users.showCurrentUser.mockResolvedValue({ id: 12345 });
|
||||
mockGitlabClient.Namespaces.show.mockResolvedValue({ id: 1234 });
|
||||
mockGitlabClient.Namespaces.show.mockResolvedValue({
|
||||
id: 1234,
|
||||
kind: 'group',
|
||||
});
|
||||
mockGitlabClient.Groups.allProjects.mockResolvedValue([]);
|
||||
mockGitlabClient.Projects.create.mockResolvedValue({
|
||||
http_url_to_repo: 'http://mockurl.git',
|
||||
@@ -422,7 +472,10 @@ describe('publish:gitlab', () => {
|
||||
|
||||
it('should not call initRepoAndPush when sourcePath is false', async () => {
|
||||
mockGitlabClient.Users.showCurrentUser.mockResolvedValue({ id: 12345 });
|
||||
mockGitlabClient.Namespaces.show.mockResolvedValue({ id: 1234 });
|
||||
mockGitlabClient.Namespaces.show.mockResolvedValue({
|
||||
id: 1234,
|
||||
kind: 'group',
|
||||
});
|
||||
mockGitlabClient.Groups.allProjects.mockResolvedValue([]);
|
||||
mockGitlabClient.Projects.create.mockResolvedValue({
|
||||
http_url_to_repo: 'http://mockurl.git',
|
||||
@@ -446,7 +499,10 @@ describe('publish:gitlab', () => {
|
||||
|
||||
it('should call initRepoAndPush with the correct default branch', async () => {
|
||||
mockGitlabClient.Users.showCurrentUser.mockResolvedValue({ id: 12345 });
|
||||
mockGitlabClient.Namespaces.show.mockResolvedValue({ id: 1234 });
|
||||
mockGitlabClient.Namespaces.show.mockResolvedValue({
|
||||
id: 1234,
|
||||
kind: 'group',
|
||||
});
|
||||
mockGitlabClient.Groups.allProjects.mockResolvedValue([]);
|
||||
mockGitlabClient.Projects.create.mockResolvedValue({
|
||||
http_url_to_repo: 'http://mockurl.git',
|
||||
@@ -502,7 +558,10 @@ describe('publish:gitlab', () => {
|
||||
});
|
||||
|
||||
mockGitlabClient.Users.showCurrentUser.mockResolvedValue({ id: 12345 });
|
||||
mockGitlabClient.Namespaces.show.mockResolvedValue({ id: 1234 });
|
||||
mockGitlabClient.Namespaces.show.mockResolvedValue({
|
||||
id: 1234,
|
||||
kind: 'group',
|
||||
});
|
||||
mockGitlabClient.Groups.allProjects.mockResolvedValue([]);
|
||||
mockGitlabClient.Projects.create.mockResolvedValue({
|
||||
http_url_to_repo: 'http://mockurl.git',
|
||||
@@ -549,7 +608,10 @@ describe('publish:gitlab', () => {
|
||||
});
|
||||
|
||||
mockGitlabClient.Users.showCurrentUser.mockResolvedValue({ id: 12345 });
|
||||
mockGitlabClient.Namespaces.show.mockResolvedValue({ id: 1234 });
|
||||
mockGitlabClient.Namespaces.show.mockResolvedValue({
|
||||
id: 1234,
|
||||
kind: 'group',
|
||||
});
|
||||
mockGitlabClient.Groups.allProjects.mockResolvedValue([]);
|
||||
mockGitlabClient.Projects.create.mockResolvedValue({
|
||||
http_url_to_repo: 'http://mockurl.git',
|
||||
@@ -570,7 +632,10 @@ describe('publish:gitlab', () => {
|
||||
|
||||
it('should call output with the remoteUrl and repoContentsUrl and projectId', async () => {
|
||||
mockGitlabClient.Users.showCurrentUser.mockResolvedValue({ id: 12345 });
|
||||
mockGitlabClient.Namespaces.show.mockResolvedValue({ id: 1234 });
|
||||
mockGitlabClient.Namespaces.show.mockResolvedValue({
|
||||
id: 1234,
|
||||
kind: 'group',
|
||||
});
|
||||
mockGitlabClient.Groups.allProjects.mockResolvedValue([]);
|
||||
mockGitlabClient.Projects.create.mockResolvedValue({
|
||||
http_url_to_repo: 'http://mockurl.git',
|
||||
@@ -610,7 +675,10 @@ describe('publish:gitlab', () => {
|
||||
config: customAuthorConfig,
|
||||
});
|
||||
|
||||
mockGitlabClient.Namespaces.show.mockResolvedValue({ id: 1234 });
|
||||
mockGitlabClient.Namespaces.show.mockResolvedValue({
|
||||
id: 1234,
|
||||
kind: 'group',
|
||||
});
|
||||
mockGitlabClient.Users.showCurrentUser.mockResolvedValue({ id: 12345 });
|
||||
mockGitlabClient.Groups.allProjects.mockResolvedValue([]);
|
||||
mockGitlabClient.Projects.create.mockResolvedValue({
|
||||
|
||||
@@ -379,13 +379,15 @@ export function createPublishGitlabAction(options: {
|
||||
});
|
||||
|
||||
let targetNamespaceId;
|
||||
|
||||
let targetNamespaceKind;
|
||||
try {
|
||||
const namespaceResponse = (await client.Namespaces.show(owner)) as {
|
||||
id: number;
|
||||
kind: string;
|
||||
};
|
||||
|
||||
targetNamespaceId = namespaceResponse.id;
|
||||
targetNamespaceKind = namespaceResponse.kind;
|
||||
} catch (e) {
|
||||
if (e.cause?.response?.status === 404) {
|
||||
throw new InputError(
|
||||
@@ -401,13 +403,16 @@ export function createPublishGitlabAction(options: {
|
||||
|
||||
if (!targetNamespaceId) {
|
||||
targetNamespaceId = userId;
|
||||
targetNamespaceKind = 'user';
|
||||
}
|
||||
|
||||
const existingProjects = await client.Groups.allProjects(owner, {
|
||||
search: repo,
|
||||
});
|
||||
const existingProjects =
|
||||
targetNamespaceKind === 'user'
|
||||
? await client.Users.allProjects(owner, { search: repo })
|
||||
: await client.Groups.allProjects(owner, { search: repo });
|
||||
|
||||
const existingProject = existingProjects.find(
|
||||
searchPathElem => searchPathElem.path === repo,
|
||||
project => project.path === repo,
|
||||
);
|
||||
|
||||
if (!skipExisting || (skipExisting && !existingProject)) {
|
||||
|
||||
Reference in New Issue
Block a user