Skip to content

Commit

Permalink
Deploy using repository URL(fixes #58) (#59)
Browse files Browse the repository at this point in the history
* Added git in dockerfile (#58)

* Remove incorrect and incomplete old implementation (#58)

* Deploy using repository url complete (#58)

* used fs.rm to clean repo (#58)
  • Loading branch information
HeeManSu authored Aug 9, 2024
1 parent 4dfe98b commit b306612
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 41 deletions.
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ RUN npm install \
FROM base as faas

RUN apt-get update \
&& apt-get install wget ca-certificates -y --no-install-recommends \
&& apt-get install wget ca-certificates git -y --no-install-recommends \
&& wget -O - https://raw.githubusercontent.com/metacall/install/master/install.sh | sh

COPY --from=deps /metacall/node_modules node_modules
Expand All @@ -52,5 +52,5 @@ CMD ["node", "dist/index.js"]
FROM base AS test

RUN apt-get update \
&& apt-get install curl ca-certificates jq -y --no-install-recommends \
&& apt-get install curl ca-certificates jq git -y --no-install-recommends \
&& npm install -g @metacall/deploy
3 changes: 0 additions & 3 deletions src/controller/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ export const deploy = catchAsync(
next: NextFunction
) => {
try {
// TODO: Implement repository
// req.body.resourceType == 'Repository'

const application = Applications[req.body.suffix];

// Check if the application exists and it is stored
Expand Down
102 changes: 66 additions & 36 deletions src/controller/repository.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { NextFunction, Request, Response } from 'express';
import { promises as fs } from 'fs';
import { join } from 'path';
import { Application, Applications, Resource } from '../app';
import AppError from '../utils/appError';
import { appsDirectory } from '../utils/config';
import { exec } from '../utils/exec';
Expand All @@ -18,7 +19,7 @@ type FetchBranchListBody = {
};

const dirName = (gitUrl: string): string =>
String(gitUrl.split('/')[gitUrl.split('/').length - 1]).replace('.git', '');
String(gitUrl.split('/').pop()).replace('.git', '');

const deleteRepoFolderIfExist = async <Path extends string>(
path: Path,
Expand All @@ -37,6 +38,11 @@ export const fetchFilesFromRepo = catchAsync(
next: NextFunction
) => {
const { branch, url } = req.body;
const resource: Resource = {
id: '',
path: '',
jsons: []
};

try {
await deleteRepoFolderIfExist(appsDirectory, url);
Expand All @@ -49,15 +55,30 @@ export const fetchFilesFromRepo = catchAsync(
);
}

await exec(
`cd ${appsDirectory} && git clone --single-branch --depth=1 --branch ${branch} ${url} `
);
try {
// Clone the repository into the specified directory
await exec(
`git clone --single-branch --depth=1 --branch ${branch} ${url} ${join(
appsDirectory,
dirName(url)
)}`
);
} catch (err) {
return next(
new AppError('Error occurred while cloning the repository', 500)
);
}

const id = dirName(req.body.url);

// TODO: This method is wrong
// deployment.id = id;
// deployment.path = `${appsDir}/${id}`;
resource.id = id;
resource.path = join(appsDirectory, id);

// Create a new Application instance and assign the resource to it
const application = new Application();
application.resource = Promise.resolve(resource);

Applications[id] = application;

return res.status(201).send({ id });
}
Expand All @@ -66,21 +87,26 @@ export const fetchFilesFromRepo = catchAsync(
export const fetchBranchList = catchAsync(
async (
req: Omit<Request, 'body'> & { body: FetchBranchListBody },
res: Response
res: Response,
next: NextFunction
) => {
const { stdout } = await exec(`git ls-remote --heads ${req.body.url}`);
try {
const { url } = req.body;

const branches: string[] = [];
// list remote branches for the repository
const { stdout } = await exec(`git ls-remote --heads ${url}`);

JSON.stringify(stdout.toString())
.split('\\n')
.forEach(el => {
if (el.trim().length > 1) {
branches.push(el.split('refs/heads/')[1]);
}
});
// Parse branches from the command output
const branches = stdout
.trim()
.split('\n')
.map(line => line.split('refs/heads/')[1])
.filter(Boolean);

return res.send({ branches });
return res.status(200).json({ branches });
} catch (err) {
next(new AppError('Error fetching branch list', 500));
}
}
);

Expand All @@ -90,28 +116,32 @@ export const fetchFileList = catchAsync(
res: Response,
next: NextFunction
) => {
const { url, branch } = req.body;
const repoDir = dirName(url);
const repoPath = `${appsDirectory}/${repoDir}`;

try {
await deleteRepoFolderIfExist(appsDirectory, req.body.url);
} catch (err) {
next(
new AppError(
'error occurred in deleting repository directory',
500
)
// Delete existing repo folder if it exists
await deleteRepoFolderIfExist(appsDirectory, url);

// Clone the repository
await exec(`git clone ${url} ${repoPath} --depth=1 --no-checkout`);

// List files in the specified branch
const { stdout } = await exec(
`cd ${repoPath} && git ls-tree -r ${branch} --name-only`
);
}
await exec(
`cd ${appsDirectory} ; git clone ${req.body.url} --depth=1 --no-checkout`
);

const dirPath = `${appsDirectory}/${dirName(req.body.url)}`;
const files = stdout.trim().split('\n').filter(Boolean);

const { stdout } = await exec(
`cd ${dirPath} ; git ls-tree -r ${req.body.branch} --name-only; cd .. ; rm -r ${dirPath}`
);
// Clean up the cloned repository
await fs.rm(repoPath, { recursive: true, force: true });

return res.send({
files: JSON.stringify(stdout.toString()).split('\\n')
});
return res.status(200).json({ files });
} catch (err) {
return next(
new AppError('Error fetching file list from repository', 500)
);
}
}
);

0 comments on commit b306612

Please sign in to comment.