Skip to content

Commit

Permalink
feature(website-builder): First initial commit for website builder cl… (
Browse files Browse the repository at this point in the history
#1)

* feature(website-builder): First initial commit for website builder closes: #851

* bug(website-builder): refactored code and added suggested changes.

* Update index.js

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* refactor(website-builder): removed comments, updated .env and gitignore.

* bug(website-builder): updated .env.example

* fix(website-builder): removed the check for the `the-one` branch, and fixed the copying the build file to the respective output directory. Also added a wrapper method for executing the commands

* bug-fix(website-builder): Added configurable project path & destination path. Also added example variable in .env for documentaiton-website & mindmap. Also added the getBranchStatus back as it was needed to check for the `the-one` branch commit.

---------

Co-authored-by: Hussain Ali <[email protected]>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored May 13, 2024
1 parent 569e5cb commit afa8404
Show file tree
Hide file tree
Showing 5 changed files with 987 additions and 0 deletions.
16 changes: 16 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
PORT = your_port_here

GITHUB_SECRET = github_secret_you_enter_while_creating_webhhok

BRANCH_NAME = the-one

DOCUMENTATION_WEBSITE_PATH = ~/Desktop/documentation-website/
DOCUMENTATION_WEBSITE_DEST_PATH = ~/documentation-website-build/

MINDMAP_PATH = ~/Desktop/mindmap/
MINDMAP_DEST_PATH = ~/Desktop/mindmap-build/

MINDMAP_UPDATE_TIME_INTERVAL = 300000
DOCUMENTATION_WEBSITE_UPDATE_TIME_INTERVAL = 600000
CONTRIBUTORS_UPDATE_TIME_INTERVAL = 10000

130 changes: 130 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# Snowpack dependency directory (https://snowpack.dev/)
web_modules/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional stylelint cache
.stylelintcache

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local

# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache

# Next.js build output
.next
out

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# vuepress build output
.vuepress/dist

# vuepress v2.x temp and cache directory
.temp
.cache

# Docusaurus cache and generated files
.docusaurus

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TernJS port file
.tern-port

# Stores VSCode versions used for testing VSCode extensions
.vscode-test

# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
106 changes: 106 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import express from "express";
import {exec} from "child_process";
import crypto from "crypto";
import dotenv from "dotenv";

dotenv.config();

const app = express();
const port = process.env.PORT || 3000;

let isDocumentationWebsiteUpdated = false;
let isMindmapUpdated = false;
let contributorsBuildRequired = false;

let documentationWebsiteBuildTime = 0;
let mindmapBuildTime = 0;
let contributorsBuildTime = 0;

app.use(express.json());

app.post("/webhook", async (req, res) => {
console.log("req receieved");
const signature = req.headers["x-hub-signature"];
const payload = JSON.stringify(req.body);

const hmac = crypto.createHmac("sha1", process.env.GITHUB_SECRET);
const calculatedSignature = `sha1=${hmac.update(payload).digest("hex")}`;

if (crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(calculatedSignature))) {
const { result, respMessage } = await getBranchStatus();
console.log("Result: ", result);
res.status(result).send(respMessage);
} else {
res.status(400).send("Invalid Github signature");
}
});

app.listen(process.env.PORT, () => {
console.log(`Server listening on port ${port}`);
});

const executeCmd = async (cmd) => {
try {
const { stdout, stderr } = await exec(cmd);
return stderr + "\n" + stdout;
} catch (error) {
console.error(`exec error: ${error}`);
throw new Error(stderr + "\n" + stdout);
}
};

const getBranchStatus = async (req) => {
console.log("Webhook received successfully");

const branchName = req.body?.ref?.split("/").pop();
if (!branchName) {
return 400, "Branch name not found in the request.";
}
return branchName === process.env.BRANCH_NAME ? await buildProject() : 202, "Build not required.";
};

const isUpdateRequired = () => {
const currentTime = Date.now();
isMindmapUpdated = (currentTime - mindmapBuildTime) / 1000 / 60 > process.env.MINDMAP_UPDATE_TIME_INTERVAL ? true : false;
isDocumentationWebsiteUpdated = (currentTime - documentationWebsiteBuildTime) / 1000 / 60 > process.env.DOCUMENTATION_WEBSITE_UPDATE_TIME_INTERVAL ? true : false;
return isMindmapUpdated || isDocumentationWebsiteUpdated;
};

const buildProject = async () => {
const currentTime = Date.now();
if (!isUpdateRequired()) {
if (contributorsBuildRequired || (currentTime - contributorsBuildTime) / 1000 / 60 > process.env.CONTRIBUTORS_UPDATE_TIME_INTERVAL) {
console.log("No update required, updating the contributors only");
await initiateBuild("npm run contributor-build", process.env.DOCUMENTATION_WEBSITE_PATH, process.env.DOCUMENTATION_WEBSITE_DEST_PATH);
contributorsBuildTime = currentTime;
contributorsBuildRequired = false;
return 200;
} else {
contributorsBuildRequired = true;
return 202, "Contributors build will be done after the next build.";
}
}
if (isMindmapUpdated) {
console.log("Building Mindmap");
await initiateBuild("npm run build", process.env.MINDMAP_PATH, process.env.MINDMAP_DEST_PATH);
mindmapBuildTime = currentTime;
isMindmapUpdated = false;
}

if (isDocumentationWebsiteUpdated) {
console.log("Building Documentation Website");
await initiateBuild("npm run build", process.env.DOCUMENTATION_WEBSITE_PATH, process.env.DOCUMENTATION_WEBSITE_DEST_PATH);
documentationWebsiteBuildTime = currentTime;
contributorsBuildTime = currentTime;
isDocumentationWebsiteUpdated = false;
}

return 200, "Build has been created.";
};

const initiateBuild = async (command, projectPath, destPath) => {
await executeCmd(`cd ${projectPath}/ && git pull`);
await executeCmd(`cd ${projectPath}/ && npm ci`);
await executeCmd(`cd ${projectPath}/ && ${command}`);
await executeCmd(`cp -r ${projectPath}/dist/ ${destPath}/`);
};
Loading

0 comments on commit afa8404

Please sign in to comment.