Skip to content

A Better README

Magic README

README's are where you start, but they are frozen snapshots of what they could be. Let's use Speedrun to make them interactive.

Speedrun Required

This blog only displays the necessary Speedrun configuration, install Speedrun and open the same markdown on GitHub to interact with the examples.

README's describe your project and tell users how to use it, but they could do more. Speedrun can customize the README experience for each user and actually help them interact with your project. In this blog we'll explore how Speedrun can help build a UI for command lines, pivot between stages, federate into the AWS console and embed content via iframes.

Building command lines

Let's start with one of the most quintessential command line tools, curl. Surprisingly, the curl README doesn't actually have example usage. The simplest curl command fetches the html for a site. We'll use Speedrun to build the command and prompt for a url. The prompt syntax is ~~~Prompt Text~~~.

```
#copy
curl ~~~Url~~~
```

When you click the Copy button, it will prompt you for the Url. Once you're ready, click Ok to copy the command line to your clipboard.

Setting a default value

You can customize the prompt by setting parameters using json5 syntax. This is the same as above, but with a default value.

```
#copy
curl ~~~Url {default:'ifconfig.me'}~~~
```

When you click the Copy button, it will prompt you for the Url. Notice how it pre-fills the value with what you entered last time you set a Url, or the default value if you haven't set a Url before. This is so you always pick up where you left off. Click the button to the right to reset the value to the default.

Again, clicking the Ok button will copy the command line to your clipboard.

Downloading a file

Downloading a file requires you to set both a Url and a filename. Here we'll assign the url to a variable url and try and extract the filename from it using JavaScript with the ${} syntax. If the Url doesn't end with something with a file extension, it will default to output. Notice how even though we define url after attempting to extract the filename it still works. This is because variables are resolved at runtime and order doesn't matter.

```
#copy
curl -o ${/\.\w{1,4}$/.test(url)?url.substring(url.lastIndexOf('/')+1):'output'} ~~~url=URL~~~
```

Advanced example

The tool imaginAIry can be used to generate AI images. If you look at the README you'll find an intense command line to mask part of an image and generate a new image. That command looks like this:

imagine \
    --init-image pearl_earring.jpg \
    --mask-prompt "face AND NOT (bandana OR hair OR blue fabric){*6}" \
    --mask-mode keep \
    --init-image-strength .2 \
    --fix-faces \
    "a modern female president" "a female robot" "a female doctor" "a female firefighter"

Let's wrap it for ease of use and give it default values and a few prompts with dropdowns:

```
#copy
imagine \
    --init-image ~~~Image File {default:'pearl_earring.jpg'}~~~ \
    -r ~~~Number of Images {type:'select', options:['1','5','10']}~~~ \
    --mask-prompt "~~~Mask {default:'face AND NOT (bandana OR hair OR blue fabric){*6}'}~~~" \
    --mask-mode keep \
    --init-image-strength .2 --steps ~~~Steps {type:'select', options:['15','20','30']}~~~ \
    "~~~Customization {default:'a modern female president'}~~~"
```

Setting the stage

Configuration via srConfig

Your project starts small with just you using it. As it grows you'll want to start introducing stages so you aren't testing in production. Speedrun lets you pivot between stages for each page using a toolbar. You do this by embedding #srConfig into a page. This example shows you how you would configure two stages for the Ticket Service both in us-west-2, but with different AWS accounts. The role has been set globally to 'ReadOnly'.

Tip

Use the Debug tab on a block to see what the variables are currently set too.

```
#srConfig
{
  role : "ReadOnly",
  services : {
    TicketService : {
       regions: {
         "us-west-2 - Prod" : {
            "account" : "11111111111"
         },
         "us-west-2 - Beta" : {
            "account" : "22222222222"
         }
       }
     }
  }
}
```

Adding variables and using JavaScript

You can add your own variables to the configuration and use JavaScript to resolve them. Let's add a logGroup variable that is made up of a prefix and the stage. We'll define it at the service level so it's available to all stages.

```
#srConfig
{
  role : "ReadOnly",
  services : {
    TicketService : {
       logGroup : "/aws/lambda/${service.toLowerCase()}-${srRegionName.substring(srRegionName.lastIndexOf('-')+2).toLowerCase()}",
       regions: {
         "us-west-2 - Prod" : {
            "account" : "11111111111"
         },
         "us-west-2 - Beta" : {
            "account" : "22222222222"
         }
       }
     }
  }
}
```

Now when you pick a stage, the logGroup will be set to /aws/lambda/ticketservice-prod or /aws/lambda/ticketservice-beta depending on which stage you pick.

Getting AWS credentials

If you're using AWS, the config above can get you AWS credentials in a role. You can use #copy.withCreds to get command line credentials. Maybe you want to add the commands to deploy your CDK stack. Notice how we override the role for this block to Deployment otherwise it would be set to the page config of ReadOnly.

```
#copy.withCreds {role:'Deployment'}
cdk deploy
```

If you instead want to federate into the AWS console, use the #federate template. The toolbar gives you quick access, but if you want to go to a specific place, using the federate template and provide the console path.

```
#federate
cloudwatch/home?region=${region}#logsV2:log-groups/log-group/${encodeCloudWatchURL(logGroup)}
```

There's already a template to do this, so you can do the same thing with #CloudWatchLogs:

```
#CloudWatchLogs
```

Advanced configuration

You can put your configuration in a central location and transclude it so you don't need to embed it on each page. You can also use composition to overlay multiple configurations allowing you to override variables. Read more here.

Federation links work for authorized users whether they have Speedrun installed or not. They allow you to get credentials in a role and federate to a specific location in the AWS console. This is perfect for sharing links with peers or accessing the AWS console from your mobile device. I use deep links to review my CloudWatch daily analytics dashboard on my phone. To build a federation link, just click the Speedrun icon in the AWS console toolbar.

Toolbar

Magic Copy

Magic copy allows you to copy any inline code block to the clipboard with a click. No highlighting required!

Magic Copy

IFrames

You can embed any web page in a Speedrun page using iFrames. Perhaps you want to add a YouTube video or CloudWatch Dashboard. Use the #iframe template or one of the builtin ones like #!YouTube.

```
#!YouTube
LXboNl2vWH8
```

Conclusion

With Speedrun, you can do a lot more in your GitHub markdown. This blog only scratches the surface. Refer to the documentation and cookbooks for more examples. I'd love to hear your feedback! Join our Discord to get help, get and share tips and see release notes.