Usage
Getting started
To get started with Jalapeno, you need to install the CLI tool. You can find the installation instructions here.
Then you can bootstrap a new recipe (aka template) by running:
jalapeno create recipe my-recipe
After this you should have a new folder called my-recipe
with the following structure:
my-recipe
├── recipe.yml
├── templates
│ └── README.md
└── tests
└── defaults
├── test.yml
└── files
└── README.md
The templates
directory contains the templates which will be rendered to the project directory. You can add and edit files there or you can already execute the recipe (render the templates) to your project directory by running:
mkdir my-project && cd my-project
jalapeno execute my-recipe
# OR
mkdir my-project
jalapeno execute my-recipe -d my-project
You can also execute any of the examples from the Jalapeno repository, for example:
git clone git@github.com:futurice/jalapeno.git
jalapeno execute ./jalapeno/examples/variable-types
Or execute them directly from GitHub Container Registry:
jalapeno execute oci://ghcr.io/futurice/jalapeno/examples/variable-types:v0.0.0
You can also set the values with --set
flag or with environment variables when executing the recipe. For example:
jalapeno execute my-recipe --set MY_VAR=foo
# OR
export JALAPENO_VAR_MY_VAR=foo
jalapeno execute my-recipe
After this, the project directory should have the following files:
my-project
├── .jalapeno
│ └── sauces.yml
└── README.md
The .jalapeno
directory contains files which Jalapeno uses internally. For example sauces.yml
is Jalapeno metadata file which contains information about the sauces (aka executed recipes). This file is used to check for updates for the recipes later.
The rest of the files are rendered from the templates. You can edit the templates and execute the recipe again to update the files.
Templating
Templates are done by using Go templates extended with sprig functions. Examples of how to write these templates can be found in this article and in the example recipe.
The following context is available on the templates:
.Recipe
: Metadata object of the recipe.Recipe.APIVersion
: The API version which the recipe file uses.Recipe.Name
: The name of the recipe.Recipe.Version
: The current version of the recipe.Recipe.Source
: URL to source code for this recipe
.ID
: An UUID which is generated after the first execution of the recipe. It can be used to generate unique pseudo-random values which stay the same over the upgrades, for examplemy-resource-{{ sha1sum .ID | trunc 5 }}
.Variables
: Object which contains the values of the variables defined for the recipe. Example:{{ .Variables.FOO }}
You can use templates in the filenames as well. For example, if you want to create a file with a name defined by a variable, you can use {{ .Variables.MY_FILE_NAME }}.md
. See the example recipe. The same context is available for the filenames as for normal templates.
Template files starting with _
are not rendered to the output. This is useful when you have a file which contains helper templates for other files, like _helpers.yml
.
Template only specific type of files
By defining templateExtension
property in the recipe.yml
file, you can define that only the files with the given file extensions should be rendered from the templates
directory. The rest of the files will be copied as is. This is useful when there are files that do not need templating, but you would still need to escape the {{
and }}
characters (for example Taskfiles).
Variables
Recipe variables let you define values which users need to provide to be able to render the templates. Variables are defined in the recipe.yml
file. You can check the schema here.
Variable types
Recipe variables support the following types:
You can see examples of all the possible variables in the example recipe.
If you need to use numbers in the templates, you can use the atoi
function to convert a string variable to an integer: {{ .Variables.FOO | atoi }}
Validation
Variables can be validated by defining validators
property for the variable. Validators support regular expression pattern matching, and table validators also have column value uniqueness validator.
Publishing recipes
Jalapeno supports publishing and storing recipes in OCI-compatible registries. This means that versioned recipes can be pushed and pulled to/from ordinary Container Registries. This is useful when you want to make your recipes available or you want to check for updates for the recipe manually or programmatically from a CI/CD pipeline.
Pushing a recipe to Container registry
You can push a recipe to a Container registry by using the jalapeno push
command. For authentication, you can use docker login
before pushing the recipe or provide credentials directly to the jalapeno push
command by using flags. For example:
jalapeno create recipe my-recipe
# You can find possible authentication methods to Github Container Registry at https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry#authenticating-to-the-container-registry
docker login ghcr.io -u my-user
jalapeno push my-recipe ghcr.io/my-user/my-recipe
After this, you should be able to see the recipe in the Container registry from the UI or by running:
docker inspect ghcr.io/my-user/my-recipe:v0.0.0
The tag of the recipe in Container Registry is automatically determined by the version in the recipe.yml
file. So if you want to push a new version of the recipe, you need to update the version in the recipe.yml
file first. If you want to use the latest
tag, set the --latest
flag when pushing the recipe.
Executing a recipe from Container registry
You can execute a recipe directly from Container registry by using the jalapeno execute
command. For example:
mkdir my-project && cd my-project
jalapeno execute oci://ghcr.io/my-user/my-recipe:v0.0.0
Another way is to pull the recipe first on your local machine and then execute it:
mkdir my-project && cd my-project
jalapeno pull oci://ghcr.io/my-user/my-recipe:v0.0.0
jalapeno execute my-recipe
Executing multiple recipes with a manifest file
You can execute multiple recipes at once by using a manifest file. The manifest file is a YAML file which contains the list of recipes which should be executed. The manifest file should be in the following format:
apiVersion: v1
recipes:
- name: recipe-a
version: v0.0.1
repository: ./path/to/local/recipe-a
- name: recipe-b
version: v0.0.1
repository: oci://url/to/remote/recipe-b
values:
MY_VAR: "Hello World" # Predefined values for the recipe
After you've created the manifest file, you can execute the recipes by running:
jalapeno execute ./path/to/manifest.yml -d my-project
Checking updates for a recipe
After you have executed a recipe, Jalapeno will create a .jalapeno/sauces.yml
file in the project directory. This file contains information about the executed recipes and their versions. If the recipe was executed directly from a Container Registry, the registry URL is also stored in the file for checking for new versions. To check the new versions for the recipes, you can run:
jalapeno check
This will check for updates for all the recipes in the project directory. You can also check for updates for a specific recipe by running:
jalapeno check --recipe my-recipe
If you've executed the recipe from a local directory and the registry URL is still unknown, you can set the registry URL manually by running:
jalapeno check --recipe my-recipe --from oci://ghcr.io/my-user/my-recipe
If you want to run the check in a CI/CD pipeline (like Github Actions), you can check the examples/github-action
recipe on how to do it or you can execute it in your project with jalapeno execute oci://ghcr.io/futurice/jalapeno/examples/github-action:v0.0.0
.
If you want to start upgrading the recipes to the latest version right away, you can run:
jalapeno check --upgrade
Upgrading recipes
You can upgrade a recipe by running:
jalapeno upgrade oci://ghcr.io/my-user/my-recipe:v2.0.0
Note that the new recipe version needs to be the same or newer than the previous version. Doing rollbacks with the upgrade
command is not supported at the moment.
If you've modified the files which were originally generated by the recipe, Jalapeno will notice them while doing the upgrade. It will ask if you want to overwrite the modified files with the newer versions or keep the modified ones.
Updating recipe version and changelog
You can update the recipe version number and write a changelog with
jalapeno bumpver path/to/recipe
This will prompt you for the semver increment (patch/minor/major) of the update and an optional multiline comment for the changelog. Ctrl+S exits the multiline editor and saves your changes.
If a changelog doesn't already exist for a given recipe, bumpver
will initialize it with the current version number and message "Init version"
You can alternatively specify a version number and message directly with
jalapeno bumpver path/to/recipe --version=v0.0.2 --message="Hello world"
Creating tests for a recipe
To bootstrap a test case for a recipe, you can run:
jalapeno create test -d ./my-recipe
After that, the following structure should be created in the recipe directory:
my-recipe
├── ...
└── tests
└── example
├── files/
└── test.yml
The test.yml
file contains the configuration for the test case which will be executed when running the jalapeno test
command. The configuration contains, for example, the values for the template variables which should be used when rendering the recipe. The files
directory contains the expected files which the recipe should generate. You can add more test cases by creating new directories under the tests
directory. In this case, the test case name is example
.
To update the current recipe output as the expected output to all tests, you can run:
jalapeno test ./my-recipe --update-snapshots
After you've created the test cases, you can run the tests by running:
jalapeno test ./my-recipe