Created
October 17, 2024 13:50
-
-
Save ezzabuzaid/eca657d22a53ab2227de35148c24d03f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import fs, { rm } from 'fs'; | |
import { mkdir, writeFile } from 'fs/promises'; | |
import git from 'isomorphic-git'; | |
import http from 'isomorphic-git/http/node'; | |
import os from 'os'; | |
import { dirname, join } from 'path'; | |
import { Context, Inject, Injectable, ServiceLifetime } from 'tiny-injector'; | |
import { v4 } from 'uuid'; | |
import { safeFail } from '@faslh/utils'; | |
import { bundle } from '@january/generator/bundler'; | |
@Injectable({ | |
lifetime: ServiceLifetime.Scoped, | |
}) | |
class SourceCodeManager { | |
constructor(@Inject(Context) private readonly _context: Context) {} | |
public async getFiles() { | |
return safeFail(() => JSON.parse(this._context.getExtra('files')), []) as { | |
content: string; | |
path: string; | |
}[]; | |
} | |
public async writeFiles(repoPath: string) { | |
const files = await this.getFiles(); | |
for (const file of files) { | |
await mkdir(dirname(join(repoPath, file.path)), { recursive: true }); | |
await writeFile(join(repoPath, file.path), file.content, 'utf-8'); | |
} | |
} | |
public bundle(repoPath: string) { | |
return bundle({ | |
projectRoot: repoPath, | |
entry: join(repoPath, 'src', 'server.ts'), | |
out: join(repoPath, 'build', 'server.js'), | |
}); | |
} | |
} | |
@Injectable({ | |
lifetime: ServiceLifetime.Scoped, | |
}) | |
class Remote { | |
constructor(private readonly _sourceCodeManager: SourceCodeManager) {} | |
async push(config: { message: string; accessToken: string }) { | |
const selectedProject = null as any; | |
if (!selectedProject.repositoryId) { | |
throw new Error('Repository name is not set'); | |
} | |
// Clone the repository first before generating the files so that the generated code sits on top of the latest commit | |
const repoPath = join(os.tmpdir(), v4()); | |
const repoUrl = `https://${config.accessToken}@github.com/${selectedProject.repositoryName}.git`; | |
await git.clone({ | |
fs: fs, | |
http: http, | |
dir: repoPath, | |
url: repoUrl, | |
depth: 1, | |
remote: 'origin', | |
ref: 'main', | |
singleBranch: true, | |
// corsProxy: 'https://cors.isomorphic-git.org', | |
}); | |
const files = await this._sourceCodeManager.getFiles(); | |
await this._sourceCodeManager.writeFiles(repoPath); | |
await this._sourceCodeManager.bundle(repoPath); | |
try { | |
for (const file of [ | |
...files, | |
{ | |
path: join('build', 'server.js'), | |
}, | |
]) { | |
await git.add({ | |
fs, | |
dir: repoPath, | |
filepath: file.path, | |
}); | |
} | |
const sha = await git.commit({ | |
fs, | |
dir: repoPath, | |
message: config.message, | |
author: { | |
name: 'JanuaryLabs', | |
}, | |
}); | |
await git.push({ | |
fs, | |
http, | |
url: repoUrl, | |
dir: repoPath, | |
remote: 'origin', | |
ref: 'main', | |
}); | |
return sha; | |
} finally { | |
rm(repoPath, { recursive: true, force: true }, (error) => { | |
console.error(error); | |
// ignore delete tmp directory error as it is not critical | |
}); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment