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

Feat/zn 514 host components on s3 #8

Merged
merged 13 commits into from
Nov 20, 2023
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
Empty file added .env.dist
Empty file.
26 changes: 26 additions & 0 deletions .github/workflows/deploy-components.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Deploy components to S3
on:
workflow_dispatch:

jobs:
deploy:
runs-on: ubuntu-latest
environment: staging
steps:
- uses: actions/checkout@v2
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Setup Node.js 18
uses: actions/setup-node@v3
with:
node-version: 18
- name: get-npm-version
id: package-version
uses: martinbeentjes/npm-get-version-action@v1.3.1
- name: Deploy Components
run:
aws s3 sync ./packages/components s3://${{ secrets.S3_BUCKET_COMPONENT_ITEMS }}/${{steps.package-version.outputs.current-version}} --delete
5 changes: 1 addition & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,5 @@ npn run build-cli
It will transform Typescript source code of CLI to Javascript and copy components directory to `dist`.

### Storybook hosting

[![Netlify Status](https://api.netlify.com/api/v1/badges/7a89d9c3-1e97-493c-9ce4-14538ef3fe6e/deploy-status)](https://app.netlify.com/sites/tangerine-valkyrie-6f47b8/deploys)


Storybook is currently hosted at https://tangerine-valkyrie-6f47b8.netlify.app
Storybook is currently hosted at https://dz6s1m3491km4.cloudfront.net/
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"license": "ISC",
"description": "TSH Frontend Components",
"private": true,
"version": "0.0.0",
"version": "1.0.0",
"type": "module",
"scripts": {
"test": "jest --passWithNoTests",
Expand Down
48 changes: 35 additions & 13 deletions packages/cli/commands/buildSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import { Command } from 'commander';
import fs from 'fs';
import path from 'path';

import { __dirname, componentsDirectoryPath, defaultEncoding, schemaFileName } from '../shared/constants';
import { getDirectories } from '../utils/getDirectories';
import { __dirname, COMPONENT_ITEMS_BUCKET, EXCLUDED_BASE_S3_PATHS, schemaFileName } from '../shared/constants';
import { SchemaComponent } from '../types';
import { logger } from '../utils/logger';
import { getS3Object } from '../utils/getS3Object';
import { getBucketContent } from '../utils/getBucketContent';

export const buildSchema = new Command();

Expand All @@ -15,20 +16,41 @@ buildSchema
.action(async () => {
const components: SchemaComponent[] = [];

getDirectories(componentsDirectoryPath).forEach((dirName) => {
const schemaPath = path.resolve('../components', dirName, schemaFileName);
const isSchemaDefined = fs.existsSync(schemaPath);
try {
const { pathList, Contents } = await getBucketContent();

if (!isSchemaDefined) {
logger.error(`Couldn't build CLI, schema.json is missing for ${dirName} component`);
if (!pathList) {
logger.error(`Couldn't find list of folders with components in S3`);
process.exit(0);
}

const component = JSON.parse(fs.readFileSync(schemaPath, defaultEncoding)) as SchemaComponent;
components.push(component);
});
for (const element of pathList) {
if (!element || EXCLUDED_BASE_S3_PATHS.includes(element)) {
continue;
}

const schemaJsonFile = JSON.stringify({ components });
const destinationPath = path.join(__dirname, schemaFileName);
fs.writeFileSync(destinationPath, schemaJsonFile);
const schemaPath = `${element}/${schemaFileName}`;
const getSchema = Contents?.find((content) => content.Key === schemaPath);
const dirName = element?.split(path.sep).at(-1);

if (!getSchema || !getSchema?.Key) {
logger.error(`Couldn't build CLI, schema.json is missing for path ${dirName}`);
process.exit(0);
}

const getObjectItem = await getS3Object(COMPONENT_ITEMS_BUCKET, getSchema.Key);

if (getObjectItem) {
const component = JSON.parse(getObjectItem);
components.push(component);
}
}

const schemaJsonFile = JSON.stringify({ components });
const destinationPath = path.join(__dirname, schemaFileName);

fs.writeFileSync(destinationPath, schemaJsonFile);
} catch (error) {
logger.error("Couldn't find selected component, try again");
}
});
82 changes: 53 additions & 29 deletions packages/cli/commands/copy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,30 @@ import { logger } from '../utils/logger';
import {
settingsJsonOutputPath,
defaultEncoding,
componentsDirectoryPath,
jsonFileExtenstion,
storiesFileExtenstion,
jsonFileExtension,
storiesFileExtension,
packageVersion,
} from '../shared/constants';
import { generatePath } from '../utils/generatePath';
import { installDependencies } from '../utils/installDependencies';
import { isDirectoryEmpty } from '../utils/isDirectoryEmpty';
import { copyDirectoryWithExclusion } from '../utils/copyDirectoryWithExclusion';
import { PromptSelectChoices, PromptsNames, SettingsFile } from '../types/index';
import { promptsMap } from '../shared/prompts';
import { copyAwsFolderWithExclusion } from '../utils/copyAwsFolderWithExclusion';
import { getBucketContent } from '../utils/getBucketContent';
import { installComponentsDependencies } from '../utils/installComponentsDependencies';

const getCopyPrompts = ({
projectsChoices,
componentsChoices,
}: Record<string, PromptSelectChoices>): PromptObject<string>[] => {
const prompts = [promptsMap[PromptsNames.SrcPath](componentsChoices), promptsMap[PromptsNames.ShouldIncludeStories]];
const prompts = [];

if (projectsChoices.length > 1) {
prompts.unshift(promptsMap[PromptsNames.Project](projectsChoices));
prompts.push(promptsMap[PromptsNames.Project](projectsChoices));
}

prompts.push(promptsMap[PromptsNames.SrcPath](componentsChoices), promptsMap[PromptsNames.ShouldIncludeStories]());

return prompts;
};

Expand Down Expand Up @@ -58,10 +61,12 @@ copy
const componentsChoices: PromptSelectChoices = [];
const { components, getComponentByName } = getSchema();

const { pathList, Contents } = await getBucketContent();

try {
components.forEach(({ name, directoryName }) => {
const directoryPath = generatePath({ basePath: componentsDirectoryPath, targetPath: directoryName });
const isEmpty = isDirectoryEmpty(directoryPath);
const directoryPath = generatePath({ basePath: `${packageVersion}/`, targetPath: directoryName });
const isEmpty = !pathList?.includes(directoryPath);

if (isEmpty) return;

Expand All @@ -80,34 +85,53 @@ copy
}

const copyPrompts = getCopyPrompts({ projectsChoices, componentsChoices });

const results = await prompts(copyPrompts, { onCancel: () => process.exit(0) });
const { path: outputPath, packageManager } = results.project ?? projectsChoices[0].value;
const destinationDirectory = `${outputPath}/${path.basename(results.srcPath)}`;
const excludedExtensions = !results.shouldIncludeStories
? [jsonFileExtenstion, storiesFileExtenstion]
: [jsonFileExtenstion];

try {
copyDirectoryWithExclusion({
sourceDirectory: results.srcPath,
destinationDirectory,
excludedExtensions,
});

logger.success(`Component was successfully copied to: ${destinationDirectory}`);
} catch (error) {
logger.error("Couldn't copy selected component, try again");
if (results.srcPath.length === 0) {
logger.error('No component has been selected, try again');
process.exit(0);
}

const copiedComponentName = componentsChoices.find(({ value }) => value === results.srcPath)?.title;
for (const resultSrcPath of results.srcPath) {
const destinationDirectory = `${outputPath}/${path.basename(resultSrcPath)}`;
const excludedExtensions = !results.shouldIncludeStories
? [jsonFileExtension, storiesFileExtension]
: [jsonFileExtension];

try {
await copyAwsFolderWithExclusion({
Contents,
folderPath: resultSrcPath,
destinationDirectory,
excludedExtensions,
});

if (typeof copiedComponentName !== 'string') return;
logger.success(`Component was successfully copied to: ${destinationDirectory}`);
} catch (error) {
logger.error("Couldn't copy selected component, try again");
process.exit(0);
}

const copiedComponentName = componentsChoices.find(({ value }) => value === resultSrcPath)?.title;

if (typeof copiedComponentName !== 'string') return;

const component = getComponentByName(copiedComponentName);

const component = getComponentByName(copiedComponentName);
if (!component || !pathList) return;

if (!component) return;
await installDependencies({
component,
packageManager,
});

await installDependencies({ component, outputPath, packageManager });
await installComponentsDependencies({
component,
packageManager,
Contents,
pathList,
destinationDirectory,
});
}
});
Loading
Loading