Skip to content
Open
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
55 changes: 33 additions & 22 deletions scripts/checkpoint.mjs
Original file line number Diff line number Diff line change
@@ -1,28 +1,39 @@
import { execSync } from "node:child_process";
import fs from "node:fs/promises";
import { existsSync } from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";

const scriptDir = path.dirname(fileURLToPath(import.meta.url));
const repoRoot = path.resolve(scriptDir, "..");

const run = (cmd) => execSync(cmd, { cwd: repoRoot, encoding: "utf-8" }).trim();

try {
const logPath = '../mainrun/logs/mainrun.log'
if (await fs.pathExists(logPath)) {
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5)
const newLogPath = `../mainrun/logs/mainrun_${timestamp}.log`
await fs.move(logPath, newLogPath)
console.log(`Moved existing log to: mainrun_${timestamp}.log`)
const logPath = path.join(repoRoot, "mainrun", "logs", "mainrun.log");
if (existsSync(logPath)) {
const timestamp = new Date().toISOString().replace(/[:.]/g, "-").slice(0, -5);
const newLogPath = path.join(repoRoot, "mainrun", "logs", `mainrun_${timestamp}.log`);
await fs.rename(logPath, newLogPath);
console.log(`Moved existing log to: mainrun_${timestamp}.log`);
}

await $`git -C .. add .`
const status = await $`git -C .. status --porcelain`
if (status.stdout.trim() === '') {
console.log('No changes to checkpoint')
process.exit(0)
run("git add .");

const status = run("git status --porcelain");
if (status === "") {
console.log("No changes to checkpoint");
process.exit(0);
}
await $`git -C .. commit -m "Mainrun auto checkpoint"`
console.log('Auto checkpoint created')

run('git commit -m "Mainrun auto checkpoint"');
console.log("Auto checkpoint created");
} catch (error) {
if (error.message.includes('nothing to commit')) {
console.log('No changes to checkpoint')
process.exit(0)
if (error.message.includes("nothing to commit")) {
console.log("No changes to checkpoint");
process.exit(0);
}
console.error('Failed to create checkpoint:', error.message)
process.exit(1)
}

console.error("Failed to create checkpoint:", error.message);
process.exit(1);
}
136 changes: 81 additions & 55 deletions scripts/submit.mjs
Original file line number Diff line number Diff line change
@@ -1,64 +1,90 @@
import { execSync } from "node:child_process";
import fs from "node:fs/promises";
import { existsSync } from "node:fs";
import readline from "node:readline/promises";
import { stdin, stdout } from "node:process";
import path from "node:path";
import { fileURLToPath } from "node:url";

const scriptDir = path.dirname(fileURLToPath(import.meta.url));
const repoRoot = path.resolve(scriptDir, "..");

const question = async (prompt) => {
const rl = readline.createInterface({ input: stdin, output: stdout });
const answer = await rl.question(prompt);
rl.close();
return answer;
};

const run = (cmd) => execSync(cmd, { cwd: repoRoot, encoding: "utf-8" }).trim();

try {
let email
const envPath = '../.env'
if (await fs.pathExists(envPath)) {
const envContent = await fs.readFile(envPath, 'utf-8')
const match = envContent.match(/EMAIL=(.+)/)
let email;
const envPath = path.join(repoRoot, ".env");

if (existsSync(envPath)) {
const envContent = await fs.readFile(envPath, "utf-8");
const match = envContent.match(/EMAIL=(.+)/);
if (match) {
email = match[1].trim()
console.log(`Using email: ${email}`)
email = match[1].trim();
console.log(`Using email: ${email}`);
}
}

if (!email) {
email = await question('Please enter your email address: ')
await fs.writeFile(envPath, `EMAIL=${email}\n`)
console.log('Email saved for future submissions')
email = await question("Please enter your email address: ");

await fs.writeFile(envPath, `EMAIL=${email}\n`);
console.log("Email saved for future submissions");
}
console.log('\n' + '='.repeat(60))
console.log('LEGAL NOTICE')
console.log('='.repeat(60))
console.log('\nBy submitting this assessment, you agree that:')
console.log('- All submitted code becomes the property of Maincode Pty Ltd')
console.log('- You assign all intellectual property rights to Maincode Pty Ltd')
console.log('- You have read and agree to the full legal terms')
console.log('\nFull terms: https://github.com/maincodehq/mainrun/blob/main/LEGAL-NOTICE.md')
console.log('='.repeat(60) + '\n')
const confirmation = await question('Do you agree to these terms and want to proceed? (yes/no): ')
if (confirmation.toLowerCase() !== 'yes') {
console.log('Submission cancelled.')
process.exit(0)

console.log("\n" + "=".repeat(60));
console.log("LEGAL NOTICE");
console.log("=".repeat(60));
console.log("\nBy submitting this assessment, you agree that:");
console.log("- All submitted code becomes the property of Maincode Pty Ltd");
console.log("- You assign all intellectual property rights to Maincode Pty Ltd");
console.log("- You have read and agree to the full legal terms");
console.log("\nFull terms: https://github.com/maincodehq/mainrun/blob/main/LEGAL-NOTICE.md");
console.log("=".repeat(60) + "\n");

const confirmation = await question("Do you agree to these terms and want to proceed? (yes/no): ");

if (confirmation.toLowerCase() !== "yes") {
console.log("Submission cancelled.");
process.exit(0);
}

console.log('\nCreating submission zip...')

await $`cd .. && zip -r submission.zip . -x "node_modules/*" -x "mainrun/data/*"`

console.log('Requesting upload URL...')

const response = await $`curl -s "https://api.hanger.maincode.com/api/v1/upload/request?email=${email}&filename=submission.zip"`
const uploadUrl = response.stdout.trim()

if (!uploadUrl || uploadUrl.includes('error')) {
throw new Error(`Failed to get upload URL: ${uploadUrl}`)

console.log("\nCreating submission zip...");

const zipPath = path.join(repoRoot, "submission.zip");
if (existsSync(zipPath)) await fs.unlink(zipPath);

run(
`zip -r submission.zip . -x "node_modules/*" -x "mainrun/data/*" -x "mainrun/.venv/*" -x ".git/*" -x "*.zip" -x "*/__pycache__/*" -x "*.DS_Store"`
);

console.log("Requesting upload URL...");

const uploadUrl = run(
`curl -s "https://api.hanger.maincode.com/api/v1/upload/request?email=${email}&filename=submission.zip"`
);

if (!uploadUrl || uploadUrl.includes("error")) {
throw new Error(`Failed to get upload URL: ${uploadUrl}`);
}

console.log('Uploading submission...')

await $`echo ${uploadUrl} | xargs -I {} curl -X PUT {} --upload-file ../submission.zip`

await $`rm -f ../submission.zip`

console.log('✓ Submission uploaded successfully!')


console.log("Uploading submission...");

run(`curl -X PUT "${uploadUrl}" --upload-file "${zipPath}"`);

await fs.unlink(zipPath);

console.log("✓ Submission uploaded successfully!");
} catch (error) {
await $`rm -f ../submission.zip`.catch(() => {})

console.error('Failed to submit:', error.message)
process.exit(1)
}
const zipPath = path.join(repoRoot, "submission.zip");
if (existsSync(zipPath)) await fs.unlink(zipPath).catch(() => {});

console.error("Failed to submit:", error.message);
process.exit(1);
}