Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 57 additions & 5 deletions src/server/services/__tests__/build.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -730,6 +730,54 @@ describe('BuildService destroyBuildEnvironment', () => {
});
});

describe('BuildService getEnvironmentsToBuild', () => {
const createService = (foundEnvironment: any) =>
new BuildService(
{
models: {
Environment: {
findOne: jest.fn().mockResolvedValue(foundEnvironment),
// Phase 1 removed Environment.relationMappings.services. The old else-branch called
// Environment.find().withGraphJoined('services'), which throws UnknownRelationError.
find: jest.fn(() => {
throw new Error('Environment.find() must not be called: the DB-service lookup was removed');
}),
},
},
} as any,
{} as any,
{} as any,
{
registerQueue: jest.fn(() => ({ add: jest.fn(), process: jest.fn(), on: jest.fn() })),
} as any
);

beforeEach(() => {
jest.clearAllMocks();
});

test('returns the environment for a known environmentId', async () => {
const environment = { id: 7 };
const service = createService(environment);

await expect((service as any).getEnvironmentsToBuild(7)).resolves.toEqual([environment]);
});

test('returns empty for a null environmentId instead of querying the removed services relation', async () => {
const service = createService(undefined);

await expect((service as any).getEnvironmentsToBuild(null)).resolves.toEqual([]);
expect((service as any).db.models.Environment.find).not.toHaveBeenCalled();
});

test('returns empty when the environment is missing rather than a list holding undefined', async () => {
const service = createService(undefined);

// toStrictEqual: toEqual treats [undefined] as [], which would hide the old push-undefined behaviour.
await expect((service as any).getEnvironmentsToBuild(99)).resolves.toStrictEqual([]);
});
});

describe('BuildService stale deploy reconciliation', () => {
let buildService: BuildService;
let deployableQuery: any;
Expand Down Expand Up @@ -2314,12 +2362,11 @@ describe('BuildService focused changed-line coverage', () => {
expect(deployUpdate.where).toHaveBeenCalledWith('runUUID', 'build-run');
});

test('resolves direct and repository-derived build environments', async () => {
test('resolves direct build environments and no longer derives them from the repository', async () => {
const direct = { id: 5 };
const related = [{ id: 6 }];
const repositoryQuery: any = {
withGraphJoined: jest.fn(() => repositoryQuery),
where: jest.fn().mockResolvedValue(related),
where: jest.fn().mockResolvedValue([{ id: 6 }]),
};
const service = serviceWith({
models: {
Expand All @@ -2330,8 +2377,13 @@ describe('BuildService focused changed-line coverage', () => {
},
});

await expect((service as any).getEnvironmentsToBuild(5, 9)).resolves.toEqual([direct]);
await expect((service as any).getEnvironmentsToBuild(undefined, 9)).resolves.toEqual(related);
await expect((service as any).getEnvironmentsToBuild(5)).resolves.toEqual([direct]);

// The repository-derived lookup joined Environment.services, a relation removed with the
// legacy DB-config path. It is only reachable when the repository has no defaultEnvId, in
// which case no environment could match anyway, so the lookup is gone rather than repaired.
await expect((service as any).getEnvironmentsToBuild(undefined)).resolves.toStrictEqual([]);
expect(repositoryQuery.withGraphJoined).not.toHaveBeenCalled();
});

test('creates missing PR builds with and without a root repository identity', async () => {
Expand Down
18 changes: 7 additions & 11 deletions src/server/services/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2254,7 +2254,7 @@ export default class BuildService extends BaseService {
environmentId,
lifecycleConfig,
}: DeployOptions & { repositoryId: number }) {
const environments = await this.getEnvironmentsToBuild(environmentId, repositoryId);
const environments = await this.getEnvironmentsToBuild(environmentId);

if (!environments.length) {
getLogger().debug('Build: no matching environments');
Expand Down Expand Up @@ -3648,19 +3648,15 @@ export default class BuildService extends BaseService {
/**
* Returns an array of environments to build.
* @param environmentId the default environmentId (if one exists)
* @param repositoryId the repository to use for finding relevant environments, if needed
*/
private async getEnvironmentsToBuild(environmentId: number | undefined, repositoryId: number) {
let environments: Environment[] = [];
if (environmentId != null) {
environments.push(await this.db.models.Environment.findOne({ id: environmentId }));
} else {
environments = environments.concat(
await this.db.models.Environment.find().withGraphJoined('services').where('services.repositoryId', repositoryId)
);
private async getEnvironmentsToBuild(environmentId: number | undefined): Promise<Environment[]> {
if (environmentId == null) {
return [];
}

return environments;
const environment = await this.db.models.Environment.findOne({ id: environmentId });

return environment != null ? [environment] : [];
}

private async updateDeploysImageDetails(
Expand Down
Loading