Skip to content

Commit

Permalink
Merge pull request #678 from polywrap/616-build-image-overwrite
Browse files Browse the repository at this point in the history
Build-env image overwriting
  • Loading branch information
dOrgJelli authored Feb 13, 2022
2 parents 220d0fc + e90b2fd commit 969da6d
Show file tree
Hide file tree
Showing 15 changed files with 145 additions and 33 deletions.
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

0 comments on commit 969da6d

Please sign in to comment.