Skip to content

Commit

Permalink
Publish
Browse files Browse the repository at this point in the history
  • Loading branch information
thedrlambda committed Dec 17, 2024
1 parent df02a4d commit ccadac8
Show file tree
Hide file tree
Showing 24 changed files with 233 additions and 91 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@
## Fixes and improvements
-

# 4.5.0
## Added features
- `repo` option to `duplicate` an existing repo
- `hosting` asks which bitbucket branch should be the release branch
## Fixes and improvements
- Breadcrumb is again printing "mm" or "mmk" instead of "undefined"
- Fix `deploy` fails with "origin/main not found" on the first deploy
- More space for change message in `deploy`
- Fix `sim` fails on Mac when started inside group or repo
- Merge the sequential choices "template vs empty" and "language"

# 4.4.4
## Fixes and improvements
- Simulator serves bytes correctly
Expand Down
30 changes: 17 additions & 13 deletions Execute.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ function timedOutput(str, prefix) {
spacerTimer = setTimeout(() => console.log(""), 10000);
}
function prep(folder, runCommand, env, displayFolder) {
const runCmd = runCommand(folder);
const runCmd = runCommand(folder.toString());
const [cmd, ...args] = runCmd.split(" ");
const options = {
cwd: folder,
cwd: folder.toString(),
env,
shell: "sh",
};
Expand Down Expand Up @@ -97,8 +97,8 @@ function execute(handle, pathToRoot, group, repo, action, envelope, payload) {
server.listen(() => { });
const env = process.env || {};
env.RAPIDS = `localhost:${server.address().port}`;
if (fs.existsSync(pathToRoot + "/" + group + "/env.kv")) {
fs.readFileSync(pathToRoot + "/" + group + "/env.kv", "utf-8")
if (fs.existsSync(pathToRoot.with(group).with("env.kv").toString())) {
fs.readFileSync(pathToRoot.with(group).with("env.kv").toString(), "utf-8")
.split(/\r?\n/)
.forEach((x) => {
if (!x.includes("="))
Expand All @@ -107,16 +107,16 @@ function execute(handle, pathToRoot, group, repo, action, envelope, payload) {
env[b[0]] = b[1];
});
}
const folder = `${pathToRoot}/${group}/${repo}`;
const type = detectProjectType(folder);
const folder = pathToRoot.with(group).with(repo);
const type = detectProjectType(folder.toString());
const runCommand = RUN_COMMAND[type];
const p = prep(folder, runCommand, env, `${envelope.traceId}:${group}/${repo}`);
return run(p, action, envelope, payload);
}
function parseMerrymakeJson(folder, event) {
if (!fs.existsSync(`${folder}/merrymake.json`))
if (!fs.existsSync(folder.with("merrymake.json").toString()))
throw "Missing merrymake.json";
const config = JSON.parse(fs.readFileSync(`${folder}/merrymake.json`, "utf-8"));
const config = JSON.parse(fs.readFileSync(folder.with("merrymake.json").toString(), "utf-8"));
return Object.keys(config.hooks)
.filter((x) => x.endsWith(`/${event}`))
.map((x) => {
Expand All @@ -127,18 +127,22 @@ function parseMerrymakeJson(folder, event) {
}
function processFolders(pathToRoot, event) {
const rivers = {};
fs.readdirSync(pathToRoot, { withFileTypes: true })
fs.readdirSync(pathToRoot.toString(), { withFileTypes: true })
.filter((x) => x.isDirectory() &&
!x.name.startsWith("(deleted) ") &&
!x.name.endsWith(".DS_Store"))
.forEach((g) => {
const group = g.name;
fs.readdirSync(`${pathToRoot}/${group}`)
fs.readdirSync(pathToRoot.with(group).toString())
.filter((x) => !x.startsWith("(deleted) ") && !x.endsWith(".DS_Store"))
.forEach((repo) => {
if (!fs.existsSync(`${pathToRoot}/${group}/${repo}/merrymake.json`))
if (!fs.existsSync(pathToRoot
.with(group)
.with(repo)
.with("merrymake.json")
.toString()))
return;
parseMerrymakeJson(`${pathToRoot}/${group}/${repo}`, event).forEach(([river, action]) => {
parseMerrymakeJson(pathToRoot.with(group).with(repo), event).forEach(([river, action]) => {
if (rivers[river] === undefined)
rivers[river] = [];
rivers[river].push({ group, repo, action });
Expand Down Expand Up @@ -369,7 +373,7 @@ ${NORMAL_COLOR}`);
sessionId = "s" + Math.random();
resp.cookie("sessionId", sessionId);
}
const api_json = JSON.parse(fs.readFileSync(`${this.pathToRoot}/event-catalogue/api.json`, "utf-8"));
const api_json = JSON.parse(fs.readFileSync(this.pathToRoot.with("event-catalogue").with("api.json").toString(), "utf-8"));
const conf = api_json[event];
const traceId = generateString(3, all);
this.pendingReplies[traceId] = {
Expand Down
50 changes: 31 additions & 19 deletions Execute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
generateString,
printWithPrefix,
} from "./utils.js";
import { PathTo, PathToOrganization, PathToRepository } from "./types.js";

interface Envelope {
messageId: string;
Expand Down Expand Up @@ -50,15 +51,15 @@ function timedOutput(str: string, prefix?: string) {
}

function prep(
folder: string,
folder: PathToRepository,
runCommand: (folder: string) => string,
env: NodeJS.ProcessEnv,
displayFolder: string
) {
const runCmd = runCommand(folder);
const runCmd = runCommand(folder.toString());
const [cmd, ...args] = runCmd.split(" ");
const options: ExecOptions = {
cwd: folder,
cwd: folder.toString(),
env,
shell: "sh",
};
Expand Down Expand Up @@ -109,7 +110,7 @@ function pack(...buffers: Buffer[]) {

function execute(
handle: (event: string, payload: Buffer) => void,
pathToRoot: string,
pathToRoot: PathToOrganization,
group: string,
repo: string,
action: string,
Expand Down Expand Up @@ -161,17 +162,17 @@ function execute(
server.listen(() => {});
const env = process.env || {};
env.RAPIDS = `localhost:${(server.address() as net.AddressInfo).port}`;
if (fs.existsSync(pathToRoot + "/" + group + "/env.kv")) {
fs.readFileSync(pathToRoot + "/" + group + "/env.kv", "utf-8")
if (fs.existsSync(pathToRoot.with(group).with("env.kv").toString())) {
fs.readFileSync(pathToRoot.with(group).with("env.kv").toString(), "utf-8")
.split(/\r?\n/)
.forEach((x) => {
if (!x.includes("=")) return;
const b = x.split("=");
env[b[0]] = b[1];
});
}
const folder = `${pathToRoot}/${group}/${repo}`;
const type = detectProjectType(folder);
const folder = pathToRoot.with(group).with(repo);
const type = detectProjectType(folder.toString());
const runCommand = RUN_COMMAND[type];
const p = prep(
folder,
Expand All @@ -182,11 +183,11 @@ function execute(
return run(p, action, envelope, payload);
}

function parseMerrymakeJson(folder: string, event: string) {
if (!fs.existsSync(`${folder}/merrymake.json`))
function parseMerrymakeJson(folder: PathTo, event: string) {
if (!fs.existsSync(folder.with("merrymake.json").toString()))
throw "Missing merrymake.json";
const config: MerrymakeJson = JSON.parse(
fs.readFileSync(`${folder}/merrymake.json`, "utf-8")
fs.readFileSync(folder.with("merrymake.json").toString(), "utf-8")
);
return Object.keys(config.hooks)
.filter((x) => x.endsWith(`/${event}`))
Expand All @@ -197,11 +198,11 @@ function parseMerrymakeJson(folder: string, event: string) {
});
}

function processFolders(pathToRoot: string, event: string) {
function processFolders(pathToRoot: PathToOrganization, event: string) {
const rivers: {
[river: string]: { group: string; repo: string; action: string }[];
} = {};
fs.readdirSync(pathToRoot, { withFileTypes: true })
fs.readdirSync(pathToRoot.toString(), { withFileTypes: true })
.filter(
(x) =>
x.isDirectory() &&
Expand All @@ -210,12 +211,20 @@ function processFolders(pathToRoot: string, event: string) {
)
.forEach((g) => {
const group = g.name;
fs.readdirSync(`${pathToRoot}/${group}`)
fs.readdirSync(pathToRoot.with(group).toString())
.filter((x) => !x.startsWith("(deleted) ") && !x.endsWith(".DS_Store"))
.forEach((repo) => {
if (!fs.existsSync(`${pathToRoot}/${group}/${repo}/merrymake.json`))
if (
!fs.existsSync(
pathToRoot
.with(group)
.with(repo)
.with("merrymake.json")
.toString()
)
)
return;
parseMerrymakeJson(`${pathToRoot}/${group}/${repo}`, event).forEach(
parseMerrymakeJson(pathToRoot.with(group).with(repo), event).forEach(
([river, action]) => {
if (rivers[river] === undefined) rivers[river] = [];
rivers[river].push({ group, repo, action });
Expand Down Expand Up @@ -326,7 +335,7 @@ function reply(
class Simulator {
private pendingReplies: PendingReplies = {};
private channels: Channels = {};
constructor(private pathToRoot: string) {}
constructor(private pathToRoot: PathToOrganization) {}
start() {
return new Promise<void>((resolve) => {
const app = express();
Expand Down Expand Up @@ -481,7 +490,10 @@ ${NORMAL_COLOR}`);
resp.cookie("sessionId", sessionId);
}
const api_json: ApiJson = JSON.parse(
fs.readFileSync(`${this.pathToRoot}/event-catalogue/api.json`, "utf-8")
fs.readFileSync(
this.pathToRoot.with("event-catalogue").with("api.json").toString(),
"utf-8"
)
);
const conf = api_json[event];
const traceId = generateString(3, all);
Expand Down Expand Up @@ -522,7 +534,7 @@ ${NORMAL_COLOR}`);
}
}

export function do_startSimulator(pathToRoot: string) {
export function do_startSimulator(pathToRoot: PathToOrganization) {
const sim = new Simulator(pathToRoot);
addToExecuteQueue(() => sim.start());
return finish();
Expand Down
1 change: 1 addition & 0 deletions contexts.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export const CONTEXTS = {
join: NOT_ORGANIZATION_CONTEXT,
key: ORGANIZATION_CONTEXT,
org: NOT_ORGANIZATION_CONTEXT,
start: NOT_ORGANIZATION_CONTEXT,
rapids: ORGANIZATION_CONTEXT,
rename: NOT_SERVICE_GROUP_CONTEXT,
repo: SERVICE_GROUP_CONTEXT,
Expand Down
1 change: 1 addition & 0 deletions contexts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ export const CONTEXTS: { [cmd: string]: (cmd: string) => string } = {
join: NOT_ORGANIZATION_CONTEXT,
key: ORGANIZATION_CONTEXT,
org: NOT_ORGANIZATION_CONTEXT,
start: NOT_ORGANIZATION_CONTEXT,
rapids: ORGANIZATION_CONTEXT,
rename: NOT_SERVICE_GROUP_CONTEXT,
repo: SERVICE_GROUP_CONTEXT,
Expand Down
3 changes: 2 additions & 1 deletion mm.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env node
process.env["COMMAND"] = "mm";
import { setCommand } from "./mmCommand.js";
setCommand("mm");
import { YELLOW, NORMAL_COLOR } from "./prompt.js";
process.env["UPDATE_MESSAGE"] = `to update run the command:
${YELLOW}npm install --global @merrymake/cli@latest${NORMAL_COLOR}`;
Expand Down
3 changes: 2 additions & 1 deletion mm.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env node
process.env["COMMAND"] = "mm";
import { setCommand } from "./mmCommand.js";
setCommand("mm");
import { YELLOW, NORMAL_COLOR } from "./prompt.js";
process.env["UPDATE_MESSAGE"] = `to update run the command:
${YELLOW}npm install --global @merrymake/cli@latest${NORMAL_COLOR}`;
Expand Down
7 changes: 7 additions & 0 deletions mmCommand.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
let command = "$ mm";
export function setCommand(mm) {
command = "$ " + mm;
}
export function getCommand() {
return command;
}
7 changes: 7 additions & 0 deletions mmCommand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
let command = "$ mm";
export function setCommand(mm: string) {
command = "$ " + mm;
}
export function getCommand() {
return command;
}
3 changes: 2 additions & 1 deletion mmk.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env winpty node
process.env["COMMAND"] = "mmk";
import { setCommand } from "./mmCommand.js";
setCommand("mmk");
import { YELLOW, NORMAL_COLOR } from "./prompt.js";
process.env["UPDATE_MESSAGE"] = `to update run the command:
${YELLOW}npm install --global @merrymake/cli@latest${NORMAL_COLOR}`;
Expand Down
3 changes: 2 additions & 1 deletion mmk.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env winpty node
process.env["COMMAND"] = "mmk";
import { setCommand } from "./mmCommand.js";
setCommand("mmk");
import { YELLOW, NORMAL_COLOR } from "./prompt.js";
process.env["UPDATE_MESSAGE"] = `to update run the command:
${YELLOW}npm install --global @merrymake/cli@latest${NORMAL_COLOR}`;
Expand Down
7 changes: 4 additions & 3 deletions newCommands/deploy.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { choice, Formatting, shortText } from "../prompt.js";
import { choice, Formatting, output, shortText } from "../prompt.js";
import { addToExecuteQueue, execStreamPromise, finish, outputGit, spawnPromise, } from "../utils.js";
/*
[remove .gitignored files]
Expand Down Expand Up @@ -66,7 +66,7 @@ function redeploy() {
}
async function rebaseOntoMain() {
try {
const output = await executeAndPrint(`git fetch && git rebase origin/main && git push origin HEAD:main 2>&1`);
const output = await executeAndPrint(`git fetch && ({ ! git ls-remote --exit-code origin main; } || git rebase origin/main) && git push origin HEAD:main 2>&1`);
if (output.trimEnd().endsWith("Everything up-to-date"))
return choice("Would you like to redeploy?", [
{
Expand All @@ -83,7 +83,8 @@ async function rebaseOntoMain() {
}
async function getMessage() {
try {
const message = await shortText("Describe your changes: This commit will ", "Write in future tense 'refactor module X'", null, { formatting: Formatting.Minimal });
output("Describe your changes (optional):\n");
const message = await shortText("This commit will ", "Write in future tense 'refactor module X'", null, { formatting: Formatting.Minimal });
const msg = message.length === 0
? "[No message]"
: message[0].toUpperCase() + message.substring(1);
Expand Down
7 changes: 4 additions & 3 deletions newCommands/deploy.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { choice, Formatting, shortText } from "../prompt.js";
import { choice, Formatting, output, shortText } from "../prompt.js";
import { PathToRepository } from "../types.js";
import {
addToExecuteQueue,
Expand Down Expand Up @@ -84,7 +84,7 @@ function redeploy() {
async function rebaseOntoMain() {
try {
const output = await executeAndPrint(
`git fetch && git rebase origin/main && git push origin HEAD:main 2>&1`
`git fetch && ({ ! git ls-remote --exit-code origin main; } || git rebase origin/main) && git push origin HEAD:main 2>&1`
);
if (output.trimEnd().endsWith("Everything up-to-date"))
return choice(
Expand All @@ -106,8 +106,9 @@ async function rebaseOntoMain() {

async function getMessage() {
try {
output("Describe your changes (optional):\n");
const message = await shortText(
"Describe your changes: This commit will ",
"This commit will ",
"Write in future tense 'refactor module X'",
null,
{ formatting: Formatting.Minimal }
Expand Down
16 changes: 11 additions & 5 deletions newCommands/hosting.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export function bitbucketStep(group_service, repo) {
.toString()
.replace(/\\/g, "/")} ${repo}`;
}
export async function do_bitbucket(organization, host, key) {
export async function do_bitbucket(organization, host, key, releaseBranch) {
try {
const structure = await do_fetch(organization);
fs.writeFileSync(organization.pathTo.with(".merrymake").with("deploy.sh").toString(), `set -o errexit
Expand All @@ -47,7 +47,7 @@ case $RES in "Everything up-to-date"*) exit 0 ;; *"Releasing service"*) exit 0 ;
const pipelineFile = [
`pipelines:
branches:
master:
${releaseBranch}:
- parallel:
# SERVICES ARE AUTOMATICALLY ADDED BELOW`,
];
Expand Down Expand Up @@ -97,9 +97,15 @@ case $RES in "Everything up-to-date"*) exit 0 ;; *"Releasing service"*) exit 0 ;
throw e;
}
}
function hosting_bitbucket_key_host(organization, host, key) {
addToExecuteQueue(() => do_bitbucket(organization, host, key));
return finish();
async function hosting_bitbucket_key_host(organization, host, key) {
try {
const branch = await shortText("Release branch", "Pushes or pull requests to this branch will trigger a deploy. Normally: main, master, trunk, or release", `master`).then();
addToExecuteQueue(() => do_bitbucket(organization, host, key, branch));
return finish();
}
catch (e) {
throw e;
}
}
async function hosting_bitbucket_key(organization, file) {
try {
Expand Down
Loading

0 comments on commit ccadac8

Please sign in to comment.