Speedrun Merrymake
This guide is intended to get your code running in Merrymake as fast as possible. So let's jump straight into it.
Install the CLI
First we need to install the CommandLine Interface (CLI) with the command:
$ npm install --global @merrymake/cli
Quickstart a project
We can now use the CLI to automatically setup a user account, with a service ready to deploy. We only need to specify which programming language we prefer then watch the magic:
$ mm quickstart
> [p] python
[#] c#
[r] rust
[t] typescript
[¤] javascript
Take note of the key it gives us as it will be important later. Then simply run the command it gives us, to navigate to the new service:
$ cd [org]/services/Merrymake
Deploy the service
We can deploy the service with a Git push or with the command:
$ mm deploy
Trigger the service
In order to trigger a service we need a key, fortunately quickstart
gave us one to use:
$ curl --silent \
--header "Content-Type: text/plain" \
--data "World" \
https://rapids.merrymake.io/[key]/hello
We have now learned how to deploy and execute code with Merrymake. This is sufficient to start playing around. The rest of the tutorial covers advanced topics such as system maintenance, setting up proper security, and integrations.
Get Properly Introduced
While quickstart
is great for playing around, it does not support production level software. To
demonstrate how to work with Merrymake professionally we are going to build an uptime detector. Before we get
started on that we need to master the CLI itself.
Master the CLI
We at Merrymake have spent a lot of effort making the CLI as easy to use as possible, therefore it is different from usual CLI's in a few important areas:
Context sensitivity
The Merrymake-CLI looks at which folder we are in, and presents only options relevant to that context. For example we cannot create an organization inside another organization. If you are missing an option, verify that you are in the correct folder to perform that action.
Preselecting options
Every option in the CLI has a unique word, highlighted with yellow. This name can be used as a commandline
argument to preselect that option skipping the choice. In the example from earlier, mm quickstart
presented a
choice of languages, if we were to call it again we can skip this choice by adding the language as a commandline
argument:
$ mm quickstart typescript
For text prompts we can preselect the default options by using underscore (_
) as the commandline
argument.
Shorthand preselection
Most options in the CLI also have brackets with a character inside it, this character can be used as a shorthand
when preselecting this option, by prefixing it with a dash (-
). Using shorthand looks like this:
$ mm quickstart -t
It is possible to chain shorthands, combining -b -t
into -bt
. Note that not all
options have a shorthand version, such as the command quickstart
itself.
Help for text input
When you are asked to type in text you can press escape to display a help-text. For example when we hit escape while setting up a cron job:
$ mm cron new event event
Cron expression (optional): |
Eg. every 5 minutes is '*/5 * * * *'
Dryrun
The final CLI feature we want to mention is the dryrun
mode. This mode lets us navigate through
the CLI without making changes to our project, which is very helpful when building commands to use as part some
automation, or if we're just curious about what lies behind an option. ;-)
$ mm dryrun org
Register a device
To work with Merrymake we need to register the device and tie it to a user account. The CLI sends all commands
securely via ssh, which is like a fingerprint for your computer. quickstart
automatically set up an
ssh key for you, and configured it for Merrymake, however it did not tie an email to the account.
Accounts with no emails attached get's automatically deleted after a while without notice -- since we have no email to notify. We can prevent this by adding an email to our account, then we'll be notified if our account is in danger of being archived. Adding an email also lets us register multiple ssh keys (ie. multiple devices) to the same account.
$ mm register merrymake
$ eval `ssh-agent`
$ ssh-add [file]
Create an organization
After registering our device, it is time to start building our uptime detector. The first step is to create an organization for it. An organization consists of service groups, loosely corresponding to teams, with repos (aka services) inside them. When we setup a new organization we also have to name the first service group and repo.
$ mm org [name] services alpha basic
Cloning [name]...
Creating service group...
Creating service...
Fetching template...
Use 'cd [name]\\services\\alpha' to go to the new service.
Then use 'mm deploy' to deploy it.
In addition to service groups, each organization also has one central message queue called the rapids and one event-catalogue which we'll cover in depth later.
For now, let's follow the instructions from the CLI and go to the new service:
$ cd [org]/services/alpha
Deploy with Git
In the speedrun, we saw that mm deploy
can deploy a service to the platform. Behind the scene
deployment happens through Git. Thus, we can work with services exclusively through Git if we prefer. Using Git
directly is recommended if multiple developers are collaborating the service, because then we can control the
commit messages. To deploy a service with Git, we simply commit our changes as normal and then push the
main branch. Since we selected a template we are ready to push:
$ git push origin main
[some git stuff]
remote: 88. .88 88
remote: 888. .888 88
remote: 88Y8. .8P88 88
remote: 88 Y8o8P 88 .88. 88.d8 88.d8 Yb dP 8888bd88b .88.8 88 .8P .88.
remote: 88 Y8P 88 d" "b 88" 88" Yb dP 88 '88 '8b d" "8 88 .8P d" "b
remote: 88 " 88 888888 88 88 Yb dP 88 88 88 8 8 88d8P 888888
remote: 88 88 Y. 88 88 Y8P 88 88 88 Y. .8 88" 8b Y.
remote: 88 88 "88P 88 88 dP 88 88 88 "88"8 88 "8b "88P
remote: dP
remote: Cloning repository...
remote: Detecting project type...
remote: Scheduling typescript build...
remote: [Build output]
remote: Build completed...
remote: Registering service...
remote: Deploying service...
remote: Queueing smoke test...
remote: Service 'Merrymake' will be released if/when the smoke test succeeds.
From this output we can see that Merrymake builds, packages, and deploys our service automatically. This is pretty normal for a continuous deployment pipeline. What is unique is the 'smoke test'. In Merrymake, before a service is allowed to handle traffic is started once, to ensure there are no critical errors in the configuration. We'll return to the smoke test later.
We can check if our smoke test went through we can inspect the rapids, this displays all events that have gone through our system:
$ mm queue
Id │ River │ Event │ Status │ Queue time
-------┼--------------┼--------------┼---------┼----------------------
> [_] 192554 │ init │ │ success │ 23/11/2023, 14.44.23
Smoke tests are unique in that they have an empty Event
. As we can see, the smoke test succeeded so
the service is now live. If we want more details about an event, such as its console output we can drill down into
it:
$ mm queue 192554 init
{
messageId: '192554c1-ff81-435a-8bc0-35eb522b26d0',
startedOn: '2023-11-23T13:44:23.577Z',
finishedOn: '2023-11-23T13:44:23.636Z',
result: 'success'
}
Output:
This becomes more useful when our services print something. Let's proceed so we can get to trigger it!
Create an api-key
Services are trigged by events coming indirectly from the rapids. The rapids -- and thus the organization -- is isolated from the outside by a virtual wall. To allow events from the outside we need an api-key or key for short. In Merrymake, all keys are temporary, to prevent old keys accidentally becoming security vulnerabilities. When creating a key we can specify a human readable description, which is highly encouraged, to help distinguish keys from each other. Let's create a new key for admin use lasting 14 days:
$ mm key new admin "14 days"
New keys are created as master keys, therefore like services they can post any event to the rapids. Later we'll look at how to limit this by whitelist events for api-keys.
Trigger a service with code
In the speedrun we triggered the code from curl, but in our uptime detector we would like a little more
convenience. Let's create an admin portal where we can easily send events to our rapids. We create a file on our
desktop called admin.html
, and populate it with:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Admin portal</title>
</head>
<body>
<input type="text" id="event-type" />
<button id="button">Post to Rapids</button>
<pre id="response"></pre>
<script>
let respElem = document.getElementById("response");
let textElem = document.getElementById("event-type");
let button = document.getElementById("button");
function loadDoc(url, method, body, resolve) {
const xhttp = new XMLHttpRequest();
xhttp.onload = function () {
if (this.readyState === 4) {
respElem.innerText = (this.responseText);
}
}
xhttp.open(method, url, true);
respElem.innerText = "Waiting...";
xhttp.send(JSON.stringify(body));
}
button.addEventListener("click", (e) => {
loadDoc(
`https://rapids.merrymake.io/[key]/${textElem.value}`,
"GET",
"",
(resp) => console.log(resp));
});
</script>
</body>
</html>
Remember to replace [key]
with your api-key from the previous section.
Try it out by opening the file in a browser and posting a hello
event. The output should say:
Hello, {}!
It looks a bit odd because the service we deployed expects a payload, which our admin portal currently don't support. The important thing is that we have verified that we can deploy and trigger services, so now it is time to start building the actual uptime detector.
Other interesting bits
Disable an api-key
To disable a key we set its duration to 0 seconds:
$ mm key [key] _ '0s'