Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build-env image overwriting #678

Merged
merged 7 commits into from
Feb 13, 2022
Merged
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
57 changes: 48 additions & 9 deletions packages/cli/src/__tests__/e2e/build.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { clearStyle, w3Cli } from "./utils";
import { runCLI } from "@web3api/test-env-js";
import fs from "fs";
import path from "path";
import { loadBuildManifest } from "../../lib/helpers";

const HELP = `
w3 build [options] [<web3api-manifest>]
Expand Down Expand Up @@ -132,11 +133,41 @@ ${HELP}`);
const sanitizedOutput = clearStyle(output);

expect(code).toEqual(0);
expect(sanitizedOutput).toContain("Artifacts written to ./build from the image `build-env`");
expect(sanitizedOutput).toContain("Manifest written to ./build/web3api.json");
expect(sanitizedOutput).toContain(
"Artifacts written to ./build from the image `polywrap-build-env-"
);
expect(sanitizedOutput).toContain(
"Manifest written to ./build/web3api.yaml"
);
expect(sanitizedOutput).toContain(manifestPath);
});

test("Adds uuid-v4 suffix to build-env image if no build manifest specified", async () => {
const { exitCode: code, stdout: output } = await runCLI(
{
args: ["build", "web3api.nobuild.yaml", "-v"],
cwd: projectRoot,
cli: w3Cli,
},
);

const cacheBuildEnvPath = path.join(projectRoot, ".w3/build/env")
const sanitizedOutput = clearStyle(output);

const cachedBuildManifest = await loadBuildManifest(
path.join(cacheBuildEnvPath, "web3api.build.yaml")
)

const buildImageName = cachedBuildManifest.docker?.name

expect(buildImageName?.length).toBeGreaterThan(36)
expect((buildImageName?.match(/-/g) || []).length).toBeGreaterThanOrEqual(4)
expect(code).toEqual(0);
expect(sanitizedOutput).toContain(
`Artifacts written to ./build from the image \`${buildImageName}\``
);
});

test("Successfully builds project w/ web3api.build.yaml but no dockerfile", async () => {
const { exitCode: code, stdout: output } = await runCLI(
{
Expand All @@ -150,8 +181,12 @@ ${HELP}`);
const sanitizedOutput = clearStyle(output);

expect(code).toEqual(0);
expect(sanitizedOutput).toContain("Artifacts written to ./build from the image `build-env`");
expect(sanitizedOutput).toContain("Manifest written to ./build/web3api.json");
expect(sanitizedOutput).toContain(
"Artifacts written to ./build from the image `polywrap-build-env-"
);
expect(sanitizedOutput).toContain(
"Manifest written to ./build/web3api.yaml"
);
expect(sanitizedOutput).toContain(manifestPath);
});

Expand All @@ -169,7 +204,7 @@ ${HELP}`);

expect(code).toEqual(0);
expect(sanitizedOutput).toContain(
"Artifacts written to ./build from the image `build-env`"
"Artifacts written to ./build from the image `polywrap-build-env-"
);
expect(sanitizedOutput).toContain(
"Manifest written to ./build/web3api.json"
Expand All @@ -190,8 +225,12 @@ ${HELP}`);
const sanitizedOutput = clearStyle(output);

expect(code).toEqual(0);
expect(sanitizedOutput).toContain("Artifacts written to ./build from the image `build-env`");
expect(sanitizedOutput).toContain("Manifest written to ./build/web3api.json");
expect(sanitizedOutput).toContain(
"Artifacts written to ./build from the image `polywrap-build-env-"
);
expect(sanitizedOutput).toContain(
"Manifest written to ./build/web3api.yaml"
);
expect(sanitizedOutput).toContain(manifestPath);
});

Expand All @@ -210,8 +249,8 @@ ${HELP}`);
const sanitizedOutput = clearStyle(output);

expect(code).toEqual(0);
expect(sanitizedOutput).toContain("Artifacts written to ./build from the image `build-env`");
expect(sanitizedOutput).toContain("Manifest written to ./build/web3api.json");
expect(sanitizedOutput).toContain("Artifacts written to ./build from the image `polywrap-build-env-");
expect(sanitizedOutput).toContain("Manifest written to ./build/web3api.yaml");
expect(sanitizedOutput).toContain(manifestPath);
expect(sanitizedOutput).toContain(queryPath);
expect(sanitizedOutput).toContain(queryVarPath);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
format: 0.0.1-prealpha.2
docker:
name: build-env
dockerfile: ./Dockerfile
config:
node_version: "14.16.0"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
format: 0.0.1-prealpha.2
docker:
name: build-env
config:
node_version: "14.16.0"
include:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
format: 0.0.1-prealpha.2
docker:
name: build-env
config:
node_version: "14.16.0"
include:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
format: 0.0.1-prealpha.1
docker:
name: build-env
config:
node_version: "14.16.0"
includee:
Expand Down
2 changes: 0 additions & 2 deletions packages/cli/src/__tests__/project/web3api.build.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
format: 0.0.1-prealpha.2
docker:
name: build-env
config:
node_version: "14.16.0"
linked_packages:
Expand Down
9 changes: 9 additions & 0 deletions packages/cli/src/__tests__/project/web3api.nobuild.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
format: 0.0.1-prealpha.5
language: wasm/assemblyscript
modules:
mutation:
schema: ./src/mutation/schema.graphql
module: ./src/mutation/index.ts
query:
schema: ./src/query/schema.graphql
module: ./src/query/index.ts
5 changes: 4 additions & 1 deletion packages/cli/src/lib/Compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
outputManifest,
outputMetadata,
generateDockerfile,
generateDockerImageName,
createBuildImage,
copyArtifactsFromBuildImage,
manifestLanguageToBindLanguage,
Expand Down Expand Up @@ -340,7 +341,9 @@ export class Compiler {
const { project, outputDir } = this._config;
const buildManifestDir = await project.getBuildManifestDir();
const buildManifest = await project.getBuildManifest();
const imageName = buildManifest?.docker?.name || "web3api-build";
const imageName =
buildManifest?.docker?.name ||
generateDockerImageName(await project.getBuildUuid());
let dockerfile = buildManifest?.docker?.dockerfile
? path.join(buildManifestDir, buildManifest?.docker?.dockerfile)
: path.join(buildManifestDir, "Dockerfile");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
format: 0.0.1-prealpha.1
docker:
name: build-env
dockerfile: ./Dockerfile.mustache
config:
node_version: "14.16.0"
Expand Down
4 changes: 4 additions & 0 deletions packages/cli/src/lib/helpers/docker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,3 +150,7 @@ export function generateDockerfile(
writeFileSync(outputFilePath, dockerfile, "utf-8");
return outputFilePath;
}

export function generateDockerImageName(uuid: string): string {
return `polywrap-build-env-${uuid}`;
}
1 change: 1 addition & 0 deletions packages/cli/src/lib/helpers/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from "./path";
export * from "./uuid";
export * from "./manifest";
export * from "./metadata";
export * from "./parameters";
Expand Down
12 changes: 12 additions & 0 deletions packages/cli/src/lib/helpers/uuid.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export const createUUID = (): string => {
let dt = new Date().getTime();
const uuid = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(
/[xy]/g,
function (c) {
const r = (dt + Math.random() * 16) % 16 | 0;
dt = Math.floor(dt / 16);
return (c == "x" ? r : (r & 0x3) | 0x8).toString(16);
}
);
return uuid;
};
33 changes: 25 additions & 8 deletions packages/cli/src/lib/project/Project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import fs from "fs";
import path from "path";
import rimraf from "rimraf";
import copyfiles from "copyfiles";
import { writeFileSync } from "@web3api/os-js";

export interface ProjectConfig {
quiet?: boolean;
Expand Down Expand Up @@ -45,8 +46,17 @@ export abstract class Project {
return path.join(this.getRootDir(), ".w3");
}

public removeCacheDir(subfolder: string): void {
const folderPath = path.join(this.getCacheDir(), subfolder);
rimraf.sync(folderPath);
}

public getCachePath(subpath: string): string {
return path.join(this.getCacheDir(), subpath);
}

public readCacheFile(file: string): string | undefined {
const filePath = path.join(this.getCacheDir(), file);
const filePath = this.getCachePath(file);

if (!fs.existsSync(filePath)) {
return undefined;
Expand All @@ -55,16 +65,23 @@ export abstract class Project {
return fs.readFileSync(filePath, "utf-8");
}

public removeCacheDir(subfolder: string): void {
const folderPath = path.join(this.getCacheDir(), subfolder);
rimraf.sync(folderPath);
}
public writeCacheFile(
subPath: string,
data: unknown,
options?: fs.WriteFileOptions
): void {
const filePath = this.getCachePath(subPath);
const folderPath = path.dirname(filePath);

public getCachePath(subpath: string): string {
return path.join(this.getCacheDir(), subpath);
// Create folders if they don't exist
if (!fs.existsSync(folderPath)) {
fs.mkdirSync(folderPath, { recursive: true });
}

writeFileSync(filePath, data, options);
}

public async copyFilesIntoCache(
public async copyIntoCache(
destSubfolder: string,
sourceFolder: string,
options: copyfiles.Options = {}
Expand Down
45 changes: 41 additions & 4 deletions packages/cli/src/lib/project/Web3ApiProject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ import {
loadWeb3ApiManifest,
loadBuildManifest,
loadMetaManifest,
generateDockerImageName,
createUUID,
ManifestLanguage,
outputManifest,
} from "../helpers";
import { intlMsg } from "../intl";

Expand Down Expand Up @@ -249,14 +252,30 @@ export class Web3ApiProject extends Project {
return this._buildManifest;
}

public async getBuildUuid(): Promise<string> {
// Load the cached build UUID
let uuid = this.readCacheFile("build/uuid");

// If none was present, generate one
if (!uuid) {
uuid = createUUID();
this.writeCacheFile("build/uuid", uuid, "utf-8");
}

return uuid;
}

public async cacheDefaultBuildManifestFiles(): Promise<void> {
if (this._defaultBuildManifestCached) {
return;
}

const language = await this.getManifestLanguage();

const defaultPath = `${__dirname}/../build-envs/${language}/web3api.build.yaml`;
const defaultBuildManifestFilename = "web3api.build.yaml";
const defaultPath = `${__dirname}/../build-envs/${language}/${defaultBuildManifestFilename}`;
const destinationDir = "build/env/";
const buildEnvCachePath = this.getCachePath(destinationDir);

if (!fs.existsSync(defaultPath)) {
throw Error(
Expand All @@ -267,13 +286,31 @@ export class Web3ApiProject extends Project {
);
}

// Update the cache
// Clean the directory
this.removeCacheDir("build/env");
await this.copyFilesIntoCache(
"build/env/",

// Copy default build environment files into cache
await this.copyIntoCache(
destinationDir,
`${__dirname}/../build-envs/${language}/*`,
{ up: true }
);

// Load the default build manifest
const defaultManifest = await loadBuildManifest(defaultPath);

// Set a unique docker image name
defaultManifest.docker = {
...defaultManifest.docker,
name: generateDockerImageName(await this.getBuildUuid()),
};

// Output the modified build manifest
await outputManifest(
defaultManifest,
path.join(buildEnvCachePath, defaultBuildManifestFilename)
);

this._defaultBuildManifestCached = true;
}

Expand Down
2 changes: 1 addition & 1 deletion packages/templates/api/assemblyscript/web3api.build.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
format: 0.0.1-prealpha.1
docker:
name: build-env
name: polywrap-as-build-env
config:
node_version: "14.16.0"
include:
Expand Down