Skip to content
This repository was archived by the owner on Jun 28, 2022. It is now read-only.

Commit

Permalink
fix: pipelines commands. Update CICD docs
Browse files Browse the repository at this point in the history
  • Loading branch information
arantespp committed May 14, 2021
1 parent be7ec77 commit a22ab66
Show file tree
Hide file tree
Showing 13 changed files with 200 additions and 54 deletions.
5 changes: 4 additions & 1 deletion cicd/carlin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ export default {
sshKey: './ssh-key',
sshUrl: '[email protected]:ttoss/carlin.git',
taskEnvironment: [
{ Name: 'NPM_TOKEN', Value: fs.readFileSync('./npmtoken', 'utf-8') },
{
name: 'NPM_TOKEN',
value: fs.readFileSync('./npmtoken', 'utf-8'),
},
],
};
33 changes: 20 additions & 13 deletions packages/cli/src/deploy/cicd/cicd.template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export const getCicdTemplate = ({
key: string;
versionId: string;
};
taskEnvironment?: Array<{ Name: string; Value: string }>;
taskEnvironment?: Array<{ name: string; value: string }>;
}): CloudFormationTemplate => {
const resources: CloudFormationTemplate['Resources'] = {};

Expand All @@ -109,14 +109,12 @@ export const getCicdTemplate = ({
};

/**
* #### Elastic Container Registry
*
* The algorithm will clone the repository and will create a Docker image
* to be used to perform commands. [Yarn cache](https://classic.yarnpkg.com/en/docs/cli/cache/)
* will also be saved together with the code to reduce tasks installation
* to be used to perform your commands. [Yarn cache](https://classic.yarnpkg.com/en/docs/cli/cache/)
* will also be saved together with the code to reduce packages installation
* time. The created image will be pushed to [Amazon Elastic Container Registry](https://aws.amazon.com/ecr/).
*
* A expiration rule is also defined. The registry only keeps the latest image.
* with a defined expiration rule is also defined. The registry only keeps
* the latest image.
*/
const getEcrRepositoryResource = () => ({
Type: 'AWS::ECR::Repository',
Expand Down Expand Up @@ -258,6 +256,9 @@ export const getCicdTemplate = ({
// Install Yarn
'RUN npm install -g yarn',

// Install carlin CLI
'RUN npm install -g carlin',

// Configure git
'RUN git config --global user.name carlin',
'RUN git config --global user.email [email protected]',
Expand Down Expand Up @@ -367,10 +368,7 @@ export const getCicdTemplate = ({
};
})();

/**
* API
*/
(() => {
const createApiResources = () => {
resources[API_LOGICAL_ID] = {
Type: 'AWS::Serverless::Api',
Properties: {
Expand Down Expand Up @@ -542,7 +540,9 @@ export const getCicdTemplate = ({
Timeout: 60,
},
};
})();
};

createApiResources();

/**
* ECS
Expand Down Expand Up @@ -635,14 +635,21 @@ export const getCicdTemplate = ({
ContainerDefinitions: [
{
Environment: [
...taskEnvironment,
{
/**
* https://docs.aws.amazon.com/AmazonECS/latest/developerguide/container-metadata.html#enable-metadata
*/
Name: 'ECS_ENABLE_CONTAINER_METADATA',
Value: 'true',
},
{
Name: 'CI',
Value: 'true',
},
...taskEnvironment.map((te) => ({
Name: te.name,
Value: te.value,
})),
],
Image: {
'Fn::Sub': [
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/deploy/cicd/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ export const options = {
*
* ```ts
* Array<{
* Name: string,
* Value: string,
* name: string,
* value: string,
* }>
* ```
*/
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/deploy/cicd/deployCicd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export const deployCicd = async ({
repositoryUpdate?: boolean;
sshKey: string;
sshUrl: string;
taskEnvironment: Array<{ Name: string; Value: string }>;
taskEnvironment: Array<{ name: string; value: string }>;
}) => {
try {
const { stackName } = await handleDeployInitialization({
Expand Down
81 changes: 79 additions & 2 deletions packages/cli/src/deploy/cicd/lambdas/cicdApiV1.handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,83 @@ import { getProcessEnvVariable } from './getProcessEnvVariable';

const codebuild = new CodeBuild({ apiVersion: '2016-10-06' });

/**
* The CI/CD REST API is responsible to update the image of the repository and
* running tasks inside a container using [ECS Fargate](https://aws.amazon.com/fargate/).
* The API URL has the format of an [AWS API Gateway] URL:
*
* ```sh
* https://<api-id>.execute-api.<reegion>.amazonaws.com/v1
* ```
*
* It can be found on the "Outputs" tab if you access the CI/CD stack details
* from AWS Console or by the output `ApiV1Endpoint` that is printed after the
* stack creation.
*
* Such API has the `/cicd` endpoint, that is consumed by a POST method. This
* endpoint has two actions, defined by the `action` property, passed inside
* the body of the POST method.
*
* - **updateRepository**
*
* This action update the repository image on AWS ECR. This command is useful
* to you update your _node_modules_ folder or your [Yarn cache](https://classic.yarnpkg.com/en/docs/cli/cache/).
*
* Body interface:
*
* ```ts
* {
* action: "updateRepository";
* }
* ```
*
* - **executeTask**
*
* This action create an execution of your repository image using [ECS Fargate](https://aws.amazon.com/fargate/).
* The commands that will be executed is passed by the `commands` property,
* which receives an array of commands. You can also provide the following
* properties:
*
* - `cpu`: CPU value reserved for the task.
* - `memory`: memory value reserved for the task.
* - `taskEnvironment`: list of environment variables that can be accessed
* on task execution.
*
* Body interface:
*
* ```ts
* {
* action: "executeTask";
* commands: string[];
* cpu?: string;
* memory?: string;
* taskEnvironment?: Array<{ name: string; value: string }>;
* }
* ```
*
* Example:
*
* ```json
* {
* "action": "executeTask",
* "commands": [
* "git status",
* "git pull origin main",
* "yarn",
* "yarn test"
* ],
* "cpu": "1024",
* "memory": "2048",
* "taskEnvironment": [
* {
* "name": "CI",
* "value": "true"
* }
* ]
* }
* ```
*
*/
export const cicdApiV1Handler: ProxyHandler = async (event) => {
try {
const body = JSON.parse(event.body || JSON.stringify({}));
Expand All @@ -23,13 +100,13 @@ export const cicdApiV1Handler: ProxyHandler = async (event) => {
}

if (body.action === 'executeTask') {
const { commands = [], cpu, memory, environments = [] } = body;
const { commands = [], cpu, memory, taskEnvironment = [] } = body;

if (commands.length === 0) {
throw new Error('Commands were not provided.');
}

response = await executeTasks({ commands, cpu, memory, environments });
response = await executeTasks({ commands, cpu, memory, taskEnvironment });
}

if (response) {
Expand Down
6 changes: 3 additions & 3 deletions packages/cli/src/deploy/cicd/lambdas/executeTasks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@ export const executeTasks = async ({
commands = [],
cpu,
memory,
environments = [],
taskEnvironment = [],
}: {
commands: string[];
cpu?: string;
memory?: string;
environments?: Array<{ name: string; value: string }>;
taskEnvironment?: Array<{ name: string; value: string }>;
}) => {
const command = compileCommands([
/**
Expand Down Expand Up @@ -81,7 +81,6 @@ export const executeTasks = async ({
command: ['sh', '-cv', command],
name: getProcessEnvVariable('ECS_CONTAINER_NAME'),
environment: [
...environments,
{
name: 'CI',
value: 'true',
Expand All @@ -90,6 +89,7 @@ export const executeTasks = async ({
name: 'ECS_ENABLE_CONTAINER_METADATA',
value: 'true',
},
...taskEnvironment,
],
},
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ const putJobDetails = async ({
}) => {
const zip = new AdmZip();

const content = JSON.stringify(details, null, 2);
const content = JSON.stringify(details);

zip.addFile(pipeline, Buffer.alloc(content.length + 1, content));
zip.addFile(pipeline, Buffer.from(content));

return s3
.putObject({
Expand Down
25 changes: 20 additions & 5 deletions packages/cli/src/deploy/cicd/pipelines.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,51 @@ export type Pipeline = Pipelines[number];
export const getPrCommands = ({ branch }: { branch: string }) => [
'git status',
'git fetch',
/**
* Update to the most recent main branch to Lerna performs the diff properly.
*/
'git pull origin main',
`git checkout ${branch}`,
`git pull origin ${branch}`,
'git rev-parse HEAD',
'git status',
'yarn',
'npx lerna ls --since',
'npx lerna ls --since=main',
/**
* Apply lint only on the modified files.
*/
`git diff --name-only HEAD..main | grep -E '\\.(j|t)sx?$' | xargs npx eslint --no-error-on-unmatched-pattern`,
/**
* Execute tests only on the modified packages.
*/
`npx lerna run "test" --since --stream --parallel`,
`npx lerna run "test" --since=main --stream --parallel`,
/**
* Build only modified packages.
*/
`npx lerna run "build" --since --stream --parallel`,
`npx lerna run "build" --since=main --stream --parallel`,
/**
* Deploy only the modified packages.
*/
`npx lerna run "deploy" --since --stream --parallel`,
`npx lerna run "deploy" --since=main --stream --parallel`,
];

export const getClosedPrCommands = ({ branch }: { branch: string }) => [
'git status',
'git fetch',
/**
* Get the most recent main because the PR was approved.
*/
'git pull origin main',
'git rev-parse HEAD',
`export CARLIN_BRANCH=${branch}`,
`npx lerna run "deploy" --since --stream --parallel -- --destroy`,
`npx lerna run "deploy" --stream --parallel -- --destroy`,
];

export const getMainCommands = () => [
'git status',
'git fetch',
'git pull origin main',
'git rev-parse HEAD',
'yarn',
`export CARLIN_ENVIRONMENT=Staging`,
`npx lerna run "test" --stream --parallel`,
Expand All @@ -49,6 +63,7 @@ export const getTagCommands = ({ tag }: { tag: string }) => [
'git status',
'git fetch --tags',
`git checkout tags/${tag} -b ${tag}-branch`,
'git rev-parse HEAD',
'yarn',
`export CARLIN_ENVIRONMENT=Production`,
`npx lerna run "test" --stream --parallel`,
Expand Down
22 changes: 20 additions & 2 deletions packages/website/carlin/comments.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,27 @@ const getComment = ([pathFromDist, longname]) => {
files: path.resolve(process.cwd(), '../cli/dist', pathFromDist),
});

// if (pathFromDist === 'deploy/cicd/cicd.template.js') {
// if (pathFromDist === 'deploy/cicd/lambdas/cicdApiV1.handler.js') {
// const printObj = res
// .map((r) => ({
// longname: r.longname,
// description: r.description,
// }))
// .filter((r) => r.description);

// // eslint-disable-next-line no-console
// console.log(res);
// console.log(printObj);

// // eslint-disable-next-line global-require
// // require('fs').writeFileSync(
// // // eslint-disable-next-line global-require
// // require('path').join(__dirname, 'tmp_comments'),
// // JSON.stringify(
// // res.map((r) => ({ longname: r.longname, description: r.description })),
// // null,
// // 2,
// // ),
// // );
// process.exit(0);
// }

Expand Down
5 changes: 5 additions & 0 deletions packages/website/carlin/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ module.exports = () => {
deployApi: await cliApi('deploy'),
deployStaticAppApi: await cliApi('deploy static-app'),
deployLambdaLayerApi: await cliApi('deploy lambda-layer'),
deployCicdApi: await cliApi('deploy cicd'),

...getComments({
deployComment: ['deploy/cloudFormation.core.js', 'deploy'],
Expand Down Expand Up @@ -105,6 +106,10 @@ module.exports = () => {
'deploy/cicd/cicd.template.js',
'getCicdTemplate~getEcrRepositoryResource',
],
cicdApiV1HandlerComment: [
'deploy/cicd/lambdas/cicdApiV1.handler.js',
'cicdApiV1Handler',
],
}),
stackNameComment: toHtml(
getComment(['deploy/stackName.js', 'getStackName']).split(
Expand Down
11 changes: 11 additions & 0 deletions packages/website/docs/api-reference/deploy-cicd.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
title: deploy cicd
---

import Api from '../../src/components/Api';
import OptionAliasesInline from '../../src/components/OptionAliasesInline';
import OptionHeader from '../../src/components/OptionHeader';

import { deployCicdApi } from '../../.docusaurus/carlin/default/deployCicdApi';

<Api api={deployCicdApi} />
Loading

0 comments on commit a22ab66

Please sign in to comment.