@nizza/devkit 0.1.3-beta.3 → 0.2.0-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/executors/deploy/helpers.cjs +23 -10
- package/dist/cjs/executors/deploy/index.cjs +29 -7
- package/dist/cjs/executors/deploy/schema.json +22 -20
- package/dist/cjs/executors/environments/index.cjs +1 -3
- package/dist/cjs/executors/shared/utils.cjs +2 -1
- package/dist/esm/executors/deploy/helpers.mjs +22 -10
- package/dist/esm/executors/deploy/index.mjs +31 -9
- package/dist/esm/executors/deploy/schema.json +22 -20
- package/dist/esm/executors/environments/index.mjs +1 -3
- package/dist/esm/executors/shared/utils.mjs +2 -1
- package/package.json +1 -1
|
@@ -13,6 +13,12 @@ async function copyAssetsToS3(s3BucketPath, projectRoot) {
|
|
|
13
13
|
await utils.runCommand(`aws s3 cp ${projectRoot}/dist ${s3BucketPath} --recursive`);
|
|
14
14
|
devkit.logger.info('🚚 Assets files copied.');
|
|
15
15
|
}
|
|
16
|
+
async function copyTypingsToS3(s3BucketPath, projectRoot) {
|
|
17
|
+
const typingsPath = `${projectRoot}/dist`;
|
|
18
|
+
devkit.logger.info(`📦 Copying typings to S3 bucket at ${s3BucketPath}...`);
|
|
19
|
+
await utils.runCommand(`aws s3 cp ${typingsPath} ${s3BucketPath} --recursive --exclude "*" --include "*.d.ts"`);
|
|
20
|
+
devkit.logger.info('🚚 Typings files copied.');
|
|
21
|
+
}
|
|
16
22
|
async function createCloudFrontInvalidation(distributionId, invalidationPaths) {
|
|
17
23
|
const pathsString = invalidationPaths.map((path)=>`"${path}"`).join(' ');
|
|
18
24
|
const command = `aws cloudfront create-invalidation --distribution-id ${distributionId} --paths ${pathsString}`;
|
|
@@ -20,21 +26,28 @@ async function createCloudFrontInvalidation(distributionId, invalidationPaths) {
|
|
|
20
26
|
await utils.runCommand(command);
|
|
21
27
|
devkit.logger.info('🔄 CloudFront invalidation created.');
|
|
22
28
|
}
|
|
23
|
-
function
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
function buildS3Path(args) {
|
|
30
|
+
const slash = (s)=>s ? `/${s}` : '';
|
|
31
|
+
const rootDir = args.rootDir !== undefined ? args.rootDir : args.name;
|
|
32
|
+
const assetsDir = args.assetsDir !== undefined ? args.assetsDir : args.name;
|
|
33
|
+
const s3Bucket = `s3://${args.s3Bucket}`;
|
|
34
|
+
const s3Path = `${rootDir}${slash(assetsDir)}`;
|
|
35
|
+
const s3FullPath = `${s3Bucket}${slash(s3Path)}`;
|
|
36
|
+
const cloudFrontInvalidationPaths = [
|
|
37
|
+
`${slash(s3Path)}/*`
|
|
38
|
+
];
|
|
31
39
|
return {
|
|
32
|
-
|
|
40
|
+
rootDir,
|
|
41
|
+
assetsDir,
|
|
42
|
+
s3Bucket,
|
|
43
|
+
s3Path,
|
|
44
|
+
s3FullPath,
|
|
33
45
|
cloudFrontInvalidationPaths
|
|
34
46
|
};
|
|
35
47
|
}
|
|
36
48
|
|
|
49
|
+
exports.buildS3Path = buildS3Path;
|
|
37
50
|
exports.cleanS3Bucket = cleanS3Bucket;
|
|
38
51
|
exports.copyAssetsToS3 = copyAssetsToS3;
|
|
52
|
+
exports.copyTypingsToS3 = copyTypingsToS3;
|
|
39
53
|
exports.createCloudFrontInvalidation = createCloudFrontInvalidation;
|
|
40
|
-
exports.validateCustomPath = validateCustomPath;
|
|
@@ -1,20 +1,42 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var devkit = require('@nx/devkit');
|
|
3
4
|
var utils = require('../shared/utils.cjs');
|
|
4
5
|
var helpers = require('./helpers.cjs');
|
|
5
6
|
|
|
6
7
|
async function deployExecutor(opts, ctx) {
|
|
7
8
|
try {
|
|
9
|
+
const { cloudFrontId, skipBuild = false, typings = false, ignoreConfigs = [], dryRun = false } = opts;
|
|
10
|
+
const success = ()=>{
|
|
11
|
+
const now = new Date().toLocaleString();
|
|
12
|
+
return utils.ok(`✨ Build completed successfully on ${now}`);
|
|
13
|
+
};
|
|
14
|
+
if (ctx.configurationName && ignoreConfigs.includes(ctx.configurationName)) {
|
|
15
|
+
devkit.logger.info(`❗ Configuration ignored: ${ctx.configurationName}`);
|
|
16
|
+
return success();
|
|
17
|
+
}
|
|
8
18
|
const { root, name } = utils.getProjectConfig(ctx);
|
|
9
|
-
const { cloudFrontDistributionId, skipBuild = false } = opts;
|
|
10
19
|
const buildTarget = `${name}:${opts.buildTarget}`;
|
|
11
|
-
const {
|
|
20
|
+
const { s3FullPath, cloudFrontInvalidationPaths } = helpers.buildS3Path({
|
|
21
|
+
...opts,
|
|
22
|
+
name
|
|
23
|
+
});
|
|
24
|
+
if (dryRun) {
|
|
25
|
+
devkit.logger.info('😉 Dry run mode enabled');
|
|
26
|
+
devkit.logger.info(` - s3Path: ${s3FullPath}`);
|
|
27
|
+
devkit.logger.info(` - cloudFrontInvalidationPaths: ${cloudFrontInvalidationPaths.join(', ')}`);
|
|
28
|
+
devkit.logger.info(` - buildTarget: ${buildTarget}`);
|
|
29
|
+
return success();
|
|
30
|
+
}
|
|
12
31
|
if (!skipBuild) await utils.runCommand(`nx run ${buildTarget}`);
|
|
13
|
-
await helpers.cleanS3Bucket(
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
32
|
+
await helpers.cleanS3Bucket(s3FullPath);
|
|
33
|
+
if (typings) {
|
|
34
|
+
await helpers.copyTypingsToS3(s3FullPath, root);
|
|
35
|
+
} else {
|
|
36
|
+
await helpers.copyAssetsToS3(s3FullPath, root);
|
|
37
|
+
}
|
|
38
|
+
await helpers.createCloudFrontInvalidation(cloudFrontId, cloudFrontInvalidationPaths);
|
|
39
|
+
return success();
|
|
18
40
|
} catch (error) {
|
|
19
41
|
return utils.err(error, '❌ Error when executing deploy command');
|
|
20
42
|
}
|
|
@@ -5,26 +5,21 @@
|
|
|
5
5
|
"description": "Deploys project assets to an AWS S3 bucket and invalidates CloudFront distribution cache",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"properties": {
|
|
8
|
-
"
|
|
8
|
+
"s3Bucket": {
|
|
9
9
|
"type": "string",
|
|
10
|
-
"description": "The AWS S3 bucket path where the project assets will be deployed.
|
|
10
|
+
"description": "The AWS S3 bucket path where the project assets will be deployed. Ie: 'bucket-name'"
|
|
11
11
|
},
|
|
12
|
-
"
|
|
12
|
+
"rootDir": {
|
|
13
13
|
"type": "string",
|
|
14
|
-
"description": "
|
|
14
|
+
"description": "root directory in s3Bucket, by default it's the name of the project: Ie: pmx run ssv-script:deploy:custom --buildTarget build:prod --rootDir your-root-dir"
|
|
15
15
|
},
|
|
16
|
-
"
|
|
16
|
+
"assetsDir": {
|
|
17
17
|
"type": "string",
|
|
18
|
-
"description": "
|
|
18
|
+
"description": "assets directory for store dist files, by default it's the name of the project: Ie: pmx run ssv-script:deploy:custom --buildTarget build:prod --rootDir your-root-dir"
|
|
19
19
|
},
|
|
20
|
-
"
|
|
21
|
-
"type": "
|
|
22
|
-
"description": "
|
|
23
|
-
"items": {
|
|
24
|
-
"type": "string"
|
|
25
|
-
},
|
|
26
|
-
"uniqueItems": true,
|
|
27
|
-
"minItems": 1
|
|
20
|
+
"cloudFrontId": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"description": "The ID of the AWS CloudFront distribution for cache invalidation, ensuring updated assets are served."
|
|
28
23
|
},
|
|
29
24
|
"buildTarget": {
|
|
30
25
|
"type": "string",
|
|
@@ -34,12 +29,19 @@
|
|
|
34
29
|
"type": "boolean",
|
|
35
30
|
"description": "It allows to omit the Build process and assumes that it was already done",
|
|
36
31
|
"default": false
|
|
32
|
+
},
|
|
33
|
+
"typings": {
|
|
34
|
+
"type": "boolean",
|
|
35
|
+
"description": "Flag to indicate whether to upload .d.ts files for specific libraries",
|
|
36
|
+
"default": false
|
|
37
|
+
},
|
|
38
|
+
"ignoreConfigs": {
|
|
39
|
+
"type": "array",
|
|
40
|
+
"description": "List of configs to ignore",
|
|
41
|
+
"items": {
|
|
42
|
+
"type": "string"
|
|
43
|
+
}
|
|
37
44
|
}
|
|
38
45
|
},
|
|
39
|
-
"required": [
|
|
40
|
-
"s3BucketPath",
|
|
41
|
-
"cloudFrontDistributionId",
|
|
42
|
-
"cloudFrontInvalidationPaths",
|
|
43
|
-
"buildTarget"
|
|
44
|
-
]
|
|
46
|
+
"required": ["s3Bucket", "cloudFrontId", "buildTarget"]
|
|
45
47
|
}
|
|
@@ -10,12 +10,10 @@ const ENV_DIR = 'src/environments';
|
|
|
10
10
|
const ENV_DEV_FILE = 'environment.ts';
|
|
11
11
|
const ENV_LOCAL_FILE = 'environment.local.ts';
|
|
12
12
|
const ENV_PROD_FILE = 'environment.prod.ts';
|
|
13
|
-
const ENV_STAGING_FILE = 'environment.staging.ts';
|
|
14
13
|
const environmentFiles = [
|
|
15
14
|
ENV_DEV_FILE,
|
|
16
15
|
ENV_LOCAL_FILE,
|
|
17
|
-
ENV_PROD_FILE
|
|
18
|
-
ENV_STAGING_FILE
|
|
16
|
+
ENV_PROD_FILE
|
|
19
17
|
];
|
|
20
18
|
/**
|
|
21
19
|
* The executor function to create environment files.
|
|
@@ -37,12 +37,13 @@ const execAsync = util.promisify(child_process.exec);
|
|
|
37
37
|
* Retrieves the project configuration for the current execution context.
|
|
38
38
|
*
|
|
39
39
|
* @param {ExecutorContext} ctx - The execution context containing project information.
|
|
40
|
-
* @returns {
|
|
40
|
+
* @returns {MyProjectConfiguration} - The configuration object for the current project.
|
|
41
41
|
* @throws {Error} If the project configuration is invalid or not found.
|
|
42
42
|
*/ function getProjectConfig(ctx) {
|
|
43
43
|
const projectName = ctx.projectName || '';
|
|
44
44
|
const projectConfig = ctx.projectsConfigurations?.projects?.[projectName];
|
|
45
45
|
if (!projectConfig) throw new Error('Invalid project configuration.');
|
|
46
|
+
if (!projectConfig.name) throw new Error('Invalid project name.');
|
|
46
47
|
return projectConfig;
|
|
47
48
|
}
|
|
48
49
|
async function runCommand(command, cwd) {
|
|
@@ -11,6 +11,12 @@ async function copyAssetsToS3(s3BucketPath, projectRoot) {
|
|
|
11
11
|
await runCommand(`aws s3 cp ${projectRoot}/dist ${s3BucketPath} --recursive`);
|
|
12
12
|
logger.info('🚚 Assets files copied.');
|
|
13
13
|
}
|
|
14
|
+
async function copyTypingsToS3(s3BucketPath, projectRoot) {
|
|
15
|
+
const typingsPath = `${projectRoot}/dist`;
|
|
16
|
+
logger.info(`📦 Copying typings to S3 bucket at ${s3BucketPath}...`);
|
|
17
|
+
await runCommand(`aws s3 cp ${typingsPath} ${s3BucketPath} --recursive --exclude "*" --include "*.d.ts"`);
|
|
18
|
+
logger.info('🚚 Typings files copied.');
|
|
19
|
+
}
|
|
14
20
|
async function createCloudFrontInvalidation(distributionId, invalidationPaths) {
|
|
15
21
|
const pathsString = invalidationPaths.map((path)=>`"${path}"`).join(' ');
|
|
16
22
|
const command = `aws cloudfront create-invalidation --distribution-id ${distributionId} --paths ${pathsString}`;
|
|
@@ -18,18 +24,24 @@ async function createCloudFrontInvalidation(distributionId, invalidationPaths) {
|
|
|
18
24
|
await runCommand(command);
|
|
19
25
|
logger.info('🔄 CloudFront invalidation created.');
|
|
20
26
|
}
|
|
21
|
-
function
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
function buildS3Path(args) {
|
|
28
|
+
const slash = (s)=>s ? `/${s}` : '';
|
|
29
|
+
const rootDir = args.rootDir !== undefined ? args.rootDir : args.name;
|
|
30
|
+
const assetsDir = args.assetsDir !== undefined ? args.assetsDir : args.name;
|
|
31
|
+
const s3Bucket = `s3://${args.s3Bucket}`;
|
|
32
|
+
const s3Path = `${rootDir}${slash(assetsDir)}`;
|
|
33
|
+
const s3FullPath = `${s3Bucket}${slash(s3Path)}`;
|
|
34
|
+
const cloudFrontInvalidationPaths = [
|
|
35
|
+
`${slash(s3Path)}/*`
|
|
36
|
+
];
|
|
29
37
|
return {
|
|
30
|
-
|
|
38
|
+
rootDir,
|
|
39
|
+
assetsDir,
|
|
40
|
+
s3Bucket,
|
|
41
|
+
s3Path,
|
|
42
|
+
s3FullPath,
|
|
31
43
|
cloudFrontInvalidationPaths
|
|
32
44
|
};
|
|
33
45
|
}
|
|
34
46
|
|
|
35
|
-
export { cleanS3Bucket, copyAssetsToS3,
|
|
47
|
+
export { buildS3Path, cleanS3Bucket, copyAssetsToS3, copyTypingsToS3, createCloudFrontInvalidation };
|
|
@@ -1,18 +1,40 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { logger } from '@nx/devkit';
|
|
2
|
+
import { ok, getProjectConfig, runCommand, err } from '../shared/utils.mjs';
|
|
3
|
+
import { buildS3Path, cleanS3Bucket, copyTypingsToS3, copyAssetsToS3, createCloudFrontInvalidation } from './helpers.mjs';
|
|
3
4
|
|
|
4
5
|
async function deployExecutor(opts, ctx) {
|
|
5
6
|
try {
|
|
7
|
+
const { cloudFrontId, skipBuild = false, typings = false, ignoreConfigs = [], dryRun = false } = opts;
|
|
8
|
+
const success = ()=>{
|
|
9
|
+
const now = new Date().toLocaleString();
|
|
10
|
+
return ok(`✨ Build completed successfully on ${now}`);
|
|
11
|
+
};
|
|
12
|
+
if (ctx.configurationName && ignoreConfigs.includes(ctx.configurationName)) {
|
|
13
|
+
logger.info(`❗ Configuration ignored: ${ctx.configurationName}`);
|
|
14
|
+
return success();
|
|
15
|
+
}
|
|
6
16
|
const { root, name } = getProjectConfig(ctx);
|
|
7
|
-
const { cloudFrontDistributionId, skipBuild = false } = opts;
|
|
8
17
|
const buildTarget = `${name}:${opts.buildTarget}`;
|
|
9
|
-
const {
|
|
18
|
+
const { s3FullPath, cloudFrontInvalidationPaths } = buildS3Path({
|
|
19
|
+
...opts,
|
|
20
|
+
name
|
|
21
|
+
});
|
|
22
|
+
if (dryRun) {
|
|
23
|
+
logger.info('😉 Dry run mode enabled');
|
|
24
|
+
logger.info(` - s3Path: ${s3FullPath}`);
|
|
25
|
+
logger.info(` - cloudFrontInvalidationPaths: ${cloudFrontInvalidationPaths.join(', ')}`);
|
|
26
|
+
logger.info(` - buildTarget: ${buildTarget}`);
|
|
27
|
+
return success();
|
|
28
|
+
}
|
|
10
29
|
if (!skipBuild) await runCommand(`nx run ${buildTarget}`);
|
|
11
|
-
await cleanS3Bucket(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
30
|
+
await cleanS3Bucket(s3FullPath);
|
|
31
|
+
if (typings) {
|
|
32
|
+
await copyTypingsToS3(s3FullPath, root);
|
|
33
|
+
} else {
|
|
34
|
+
await copyAssetsToS3(s3FullPath, root);
|
|
35
|
+
}
|
|
36
|
+
await createCloudFrontInvalidation(cloudFrontId, cloudFrontInvalidationPaths);
|
|
37
|
+
return success();
|
|
16
38
|
} catch (error) {
|
|
17
39
|
return err(error, '❌ Error when executing deploy command');
|
|
18
40
|
}
|
|
@@ -5,26 +5,21 @@
|
|
|
5
5
|
"description": "Deploys project assets to an AWS S3 bucket and invalidates CloudFront distribution cache",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"properties": {
|
|
8
|
-
"
|
|
8
|
+
"s3Bucket": {
|
|
9
9
|
"type": "string",
|
|
10
|
-
"description": "The AWS S3 bucket path where the project assets will be deployed.
|
|
10
|
+
"description": "The AWS S3 bucket path where the project assets will be deployed. Ie: 'bucket-name'"
|
|
11
11
|
},
|
|
12
|
-
"
|
|
12
|
+
"rootDir": {
|
|
13
13
|
"type": "string",
|
|
14
|
-
"description": "
|
|
14
|
+
"description": "root directory in s3Bucket, by default it's the name of the project: Ie: pmx run ssv-script:deploy:custom --buildTarget build:prod --rootDir your-root-dir"
|
|
15
15
|
},
|
|
16
|
-
"
|
|
16
|
+
"assetsDir": {
|
|
17
17
|
"type": "string",
|
|
18
|
-
"description": "
|
|
18
|
+
"description": "assets directory for store dist files, by default it's the name of the project: Ie: pmx run ssv-script:deploy:custom --buildTarget build:prod --rootDir your-root-dir"
|
|
19
19
|
},
|
|
20
|
-
"
|
|
21
|
-
"type": "
|
|
22
|
-
"description": "
|
|
23
|
-
"items": {
|
|
24
|
-
"type": "string"
|
|
25
|
-
},
|
|
26
|
-
"uniqueItems": true,
|
|
27
|
-
"minItems": 1
|
|
20
|
+
"cloudFrontId": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"description": "The ID of the AWS CloudFront distribution for cache invalidation, ensuring updated assets are served."
|
|
28
23
|
},
|
|
29
24
|
"buildTarget": {
|
|
30
25
|
"type": "string",
|
|
@@ -34,12 +29,19 @@
|
|
|
34
29
|
"type": "boolean",
|
|
35
30
|
"description": "It allows to omit the Build process and assumes that it was already done",
|
|
36
31
|
"default": false
|
|
32
|
+
},
|
|
33
|
+
"typings": {
|
|
34
|
+
"type": "boolean",
|
|
35
|
+
"description": "Flag to indicate whether to upload .d.ts files for specific libraries",
|
|
36
|
+
"default": false
|
|
37
|
+
},
|
|
38
|
+
"ignoreConfigs": {
|
|
39
|
+
"type": "array",
|
|
40
|
+
"description": "List of configs to ignore",
|
|
41
|
+
"items": {
|
|
42
|
+
"type": "string"
|
|
43
|
+
}
|
|
37
44
|
}
|
|
38
45
|
},
|
|
39
|
-
"required": [
|
|
40
|
-
"s3BucketPath",
|
|
41
|
-
"cloudFrontDistributionId",
|
|
42
|
-
"cloudFrontInvalidationPaths",
|
|
43
|
-
"buildTarget"
|
|
44
|
-
]
|
|
46
|
+
"required": ["s3Bucket", "cloudFrontId", "buildTarget"]
|
|
45
47
|
}
|
|
@@ -8,12 +8,10 @@ const ENV_DIR = 'src/environments';
|
|
|
8
8
|
const ENV_DEV_FILE = 'environment.ts';
|
|
9
9
|
const ENV_LOCAL_FILE = 'environment.local.ts';
|
|
10
10
|
const ENV_PROD_FILE = 'environment.prod.ts';
|
|
11
|
-
const ENV_STAGING_FILE = 'environment.staging.ts';
|
|
12
11
|
const environmentFiles = [
|
|
13
12
|
ENV_DEV_FILE,
|
|
14
13
|
ENV_LOCAL_FILE,
|
|
15
|
-
ENV_PROD_FILE
|
|
16
|
-
ENV_STAGING_FILE
|
|
14
|
+
ENV_PROD_FILE
|
|
17
15
|
];
|
|
18
16
|
/**
|
|
19
17
|
* The executor function to create environment files.
|
|
@@ -35,12 +35,13 @@ const execAsync = promisify(exec);
|
|
|
35
35
|
* Retrieves the project configuration for the current execution context.
|
|
36
36
|
*
|
|
37
37
|
* @param {ExecutorContext} ctx - The execution context containing project information.
|
|
38
|
-
* @returns {
|
|
38
|
+
* @returns {MyProjectConfiguration} - The configuration object for the current project.
|
|
39
39
|
* @throws {Error} If the project configuration is invalid or not found.
|
|
40
40
|
*/ function getProjectConfig(ctx) {
|
|
41
41
|
const projectName = ctx.projectName || '';
|
|
42
42
|
const projectConfig = ctx.projectsConfigurations?.projects?.[projectName];
|
|
43
43
|
if (!projectConfig) throw new Error('Invalid project configuration.');
|
|
44
|
+
if (!projectConfig.name) throw new Error('Invalid project name.');
|
|
44
45
|
return projectConfig;
|
|
45
46
|
}
|
|
46
47
|
async function runCommand(command, cwd) {
|