Skip to content

Commit

Permalink
Remove docker-compose version autofix (#1638)
Browse files Browse the repository at this point in the history
  • Loading branch information
zbrydon authored Aug 23, 2024
1 parent 06ad22b commit 6796f5f
Show file tree
Hide file tree
Showing 5 changed files with 185 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/hot-crews-swim.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'skuba': minor
---

lint: Removes obsolete version field from docker-compose.yml files
8 changes: 8 additions & 0 deletions src/cli/__snapshots__/format.int.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ Patch skipped: Move .npmrc out of the .dockerignore managed section - no .docker
Patch skipped: Ensure the pnpm package manager version specified in package.json is used in Dockerfiles - no packageManager declaration in package.json found
Patch skipped: Remove version field from docker-compose files - no docker-compose files found
skuba update complete.
Refreshed .eslintignore. refresh-config-files
Expand Down Expand Up @@ -94,6 +96,8 @@ Patch skipped: Move .npmrc out of the .dockerignore managed section - no .docker
Patch skipped: Ensure the pnpm package manager version specified in package.json is used in Dockerfiles - no packageManager declaration in package.json found
Patch skipped: Remove version field from docker-compose files - no docker-compose files found
skuba update complete.
Refreshed .eslintignore. refresh-config-files
Expand Down Expand Up @@ -166,6 +170,8 @@ Patch skipped: Move .npmrc out of the .dockerignore managed section - no .docker
Patch skipped: Ensure the pnpm package manager version specified in package.json is used in Dockerfiles - no packageManager declaration in package.json found
Patch skipped: Remove version field from docker-compose files - no docker-compose files found
skuba update complete.
Refreshed .eslintignore. refresh-config-files
Expand Down Expand Up @@ -207,6 +213,8 @@ Patch skipped: Move .npmrc out of the .dockerignore managed section - no .docker
Patch skipped: Ensure the pnpm package manager version specified in package.json is used in Dockerfiles - no packageManager declaration in package.json found
Patch skipped: Remove version field from docker-compose files - no docker-compose files found
skuba update complete.
Refreshed .eslintignore. refresh-config-files
Expand Down
10 changes: 10 additions & 0 deletions src/cli/lint/internalLints/upgrade/patches/8.2.1/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { Patches } from '../..';

import { tryPatchDockerComposeFiles } from './patchDockerCompose';

export const patches: Patches = [
{
apply: tryPatchDockerComposeFiles,
description: 'Remove version field from docker-compose files',
},
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import fg from 'fast-glob';
import { readFile, writeFile } from 'fs-extra';

import type { PatchConfig } from '../..';

import { tryPatchDockerComposeFiles } from './patchDockerCompose';
jest.mock('fast-glob');
jest.mock('fs-extra');

describe('patchDockerComposeFile', () => {
afterEach(() => jest.resetAllMocks());

const mockDockerComposeFile = 'docker-compose.yml';
const mockDockerComposeContents =
'services:\n' +
'app:\n' +
"image: ${BUILDKITE_PLUGIN_DOCKER_IMAGE:-''}\n" +
'init: true\n' +
'volumes:';
const mockPatchableDockerComposeContents = `version: '3.8'\n${mockDockerComposeContents}`;

it('should skip if no Dockerfile is found', async () => {
jest.mocked(fg).mockResolvedValueOnce([]);
await expect(
tryPatchDockerComposeFiles({ mode: 'format' } as PatchConfig),
).resolves.toEqual({
result: 'skip',
reason: 'no docker-compose files found',
});
});
it('should patch docker-compose files with version field', async () => {
jest.mocked(fg).mockResolvedValueOnce([mockDockerComposeFile]);
jest
.mocked(readFile)
.mockResolvedValueOnce(mockPatchableDockerComposeContents as never);
await expect(
tryPatchDockerComposeFiles({ mode: 'format' } as PatchConfig),
).resolves.toEqual({
result: 'apply',
});
expect(writeFile).toHaveBeenCalledWith(
'docker-compose.yml',
'services:\n' +
'app:\n' +
"image: ${BUILDKITE_PLUGIN_DOCKER_IMAGE:-''}\n" +
'init: true\n' +
'volumes:',
);
});
it('should skip if no docker-compose files contain a version field', async () => {
jest.mocked(fg).mockResolvedValueOnce([mockDockerComposeFile]);
jest
.mocked(readFile)
.mockResolvedValueOnce(mockDockerComposeContents as never);
await expect(
tryPatchDockerComposeFiles({ mode: 'format' } as PatchConfig),
).resolves.toEqual({
result: 'skip',
reason: 'no docker-compose files to patch',
});
});
it('should not remove intended version in docker compose file', async () => {
jest.mocked(fg).mockResolvedValueOnce([mockDockerComposeFile]);
jest
.mocked(readFile)
.mockResolvedValueOnce(
`${mockPatchableDockerComposeContents}\n version: 7\nversion: 0.2` as never,
);
await expect(
tryPatchDockerComposeFiles({ mode: 'format' } as PatchConfig),
).resolves.toEqual({
result: 'apply',
});
expect(writeFile).toHaveBeenCalledWith(
'docker-compose.yml',
'services:\n' +
'app:\n' +
"image: ${BUILDKITE_PLUGIN_DOCKER_IMAGE:-''}\n" +
'init: true\n' +
'volumes:\n' +
' version: 7\n' +
'version: 0.2',
);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { inspect } from 'util';

import fg from 'fast-glob';
import { readFile, writeFile } from 'fs-extra';

import type { PatchFunction, PatchReturnType } from '../..';
import { log } from '../../../../../../utils/logging';

const DOCKER_COMPOSE_VERSION_REGEX = /^version: ['"]?\d+(\.\d+)*['"]?\n*/m;

const fetchFiles = async (files: string[]) =>
Promise.all(
files.map(async (file) => {
const contents = await readFile(file, 'utf8');

return {
file,
contents,
};
}),
);

const patchDockerComposeFiles: PatchFunction = async ({
mode,
}): Promise<PatchReturnType> => {
const maybeDockerComposeFiles = await Promise.resolve(
fg(['docker-compose*.yml']),
);

if (!maybeDockerComposeFiles.length) {
return {
result: 'skip',
reason: 'no docker-compose files found',
};
}

const dockerComposeFiles = await fetchFiles(maybeDockerComposeFiles);

const dockerComposeFilesToPatch = dockerComposeFiles.filter(({ contents }) =>
contents.match(DOCKER_COMPOSE_VERSION_REGEX),
);

if (!dockerComposeFilesToPatch.length) {
return {
result: 'skip',
reason: 'no docker-compose files to patch',
};
}

if (mode === 'lint') {
return {
result: 'apply',
};
}

await Promise.all(
dockerComposeFilesToPatch.map(async ({ file, contents }) => {
const patchedContents = contents.replace(
DOCKER_COMPOSE_VERSION_REGEX,
'',
);
await writeFile(file, patchedContents);
}),
);

return { result: 'apply' };
};

export const tryPatchDockerComposeFiles: PatchFunction = async (config) => {
try {
return await patchDockerComposeFiles(config);
} catch (err) {
log.warn('Failed to patch pnpm packageManager CI configuration.');
log.subtle(inspect(err));
return { result: 'skip', reason: 'due to an error' };
}
};

0 comments on commit 6796f5f

Please sign in to comment.