cli: add skeleton tarball for docker build caching

This commit is contained in:
Patrik Oldsberg
2020-09-07 14:58:56 +02:00
parent 2b114fde44
commit 9bfef247cc
3 changed files with 38 additions and 4 deletions
+7 -2
View File
@@ -2,10 +2,15 @@ FROM node:12
WORKDIR /usr/src/app
# Copy repo skeleton first, to avoid unnecessary docker cache invalidation.
# The skeleton contains the package.json of each package in the monorepo,
# and along with yarn.lock and the root package.json, that's enough to run yarn install.
ADD yarn.lock package.json skeleton.tar ./
RUN yarn install --frozen-lockfile --production
# This will copy the contents of the dist-workspace when running the build-image command.
# Do not use this Dockerfile outside of that command, as it will copy in the source code instead.
COPY . .
RUN yarn install --frozen-lockfile --production
CMD ["node", "packages/backend"]
@@ -41,6 +41,7 @@ export default async (cmd: Command) => {
...appConfigs,
{ src: paths.resolveTarget('Dockerfile'), dest: 'Dockerfile' },
],
skeleton: 'skeleton.tar',
});
console.log(`Dist workspace ready at ${tempDistWorkspace}`);
+30 -2
View File
@@ -15,10 +15,14 @@
*/
import fs from 'fs-extra';
import { resolve as resolvePath, relative as relativePath } from 'path';
import {
join as joinPath,
resolve as resolvePath,
relative as relativePath,
} from 'path';
import { paths } from '../paths';
import { run } from '../run';
import tar from 'tar';
import tar, { CreateOptions } from 'tar';
import { tmpdir } from 'os';
type LernaPackage = {
@@ -53,6 +57,12 @@ type Options = {
* If set to true, the target packages are built before they are packaged into the workspace.
*/
buildDependencies?: boolean;
/**
* If set, creates a skeleton tarball that contains all package.json files
* with the same structure as the workspace dir.
*/
skeleton?: 'skeleton.tar';
};
/**
@@ -89,6 +99,24 @@ export async function createDistWorkspace(
const dest = typeof file === 'string' ? file : file.dest;
await fs.copy(paths.resolveTargetRoot(src), resolvePath(targetDir, dest));
}
if (options.skeleton) {
const skeletonFiles = targets.map(target => {
const dir = relativePath(paths.targetRoot, target.location);
return joinPath(dir, 'package.json');
});
await tar.create(
{
file: resolvePath(targetDir, options.skeleton),
cwd: targetDir,
portable: true,
noMtime: true,
} as CreateOptions & { noMtime: boolean },
skeletonFiles,
);
}
return targetDir;
}