Publishing modules to the Central Registry

Introduction

In this tutorial you will publish a module to the Central Registry and then create a second module that depends on the first.

Prerequisites

  • A GitHub account – this will let you authenticate to the Central Registry
  • A GitHub repository called frostyconfig – create it under your personal GitHub account (it doesn’t matter if it is public or private)
  • A Central Registry account
  • The cue binary – follow the installation instructions if you don’t already use cue
  • A tool to edit text files – any text editor you have will be fine, such as VSCode, Notepad, or Vim
  • A command terminalcue works on all platforms, so you can use any Linux or macOS terminal, or a Windows terminal such as PowerShell, cmd, or WSL to run commands.

This tutorial is written using the following version of cue:

TERMINAL
$ cue version
cue version v0.14.0
...

Create the module for the schema code

In this tutorial we will focus on an imaginary application called FrostyApp, which consumes its configuration in YAML format. You will define the configuration in CUE and use a CUE schema to validate it. We would like to be able to share the schema between several consumers, so we will publish it to the Central Registry.

:material-chevron-right-circle-outline: Step 1{id=“step-1”}: Create a directory to hold the schema code

TERMINAL
$ mkdir frostyconfig
$ cd frostyconfig

:material-chevron-right-circle-outline: Step 2{id=“step-2”}: Initialize the directory as a git repository and a CUE module

!!! warning “You must adapt the command shown in this step!”

Don't simply paste the command into your terminal and run it.

Before running the command, replace the example username,
`cueckoo`,
with **the lower-cased form of YOUR GitHub username.**
For example:
if your GitHub username is `_TomHanks`
then you would replace `cueckoo` with `_tomhanks`.

**You need to make this replacement *everywhere* you see
the username `cueckoo` in this tutorial.**
TERMINAL
$ git init -q

# Replace "cueckoo" with *your* GitHub username, lower-cased.
$ cue mod init --source=git github.com/cueckoo/frostyconfig@v0

The --source=git flag tells cue to use the same file-inclusion rules as git, when publishing this module.

The GitHub user cueckoo controls all the repositories under github.com/cueckoo/, so they can publish modules to the Central Registry inside that namespace. The same is true for your GitHub username.


:material-chevron-right-circle-outline: Step 3{id=“step-3”}: Create the configuration schema

frostyconfig/config.cue
package frostyconfig

// #Config defines the schema for the FrostyApp configuration.
#Config: {
	// appName defines the name of the application.
	appName!: string
	// port holds the port number the application listens on.
	port!: int
	// debug holds whether to enable debug mode.
	debug?: bool
	// features holds optional feature settings
	features?: {
		// logging enables or disables logging.
		logging?: bool
		// analytics enables or disables analytics.
		analytics?: bool
	}
}

:material-chevron-right-circle-outline: Step 4{id=“step-4”}: Login to the Central Registry

TERMINAL
$ cue login

This is only required once for each computer that accesses the Central Registry.

!!! info “The Central Registry is in beta testing” Please give us your feedback about the service in the #modules channels on Slack and Discord.


:material-chevron-right-circle-outline: Step 5{id=“step-5”}: Ensure the module is tidy

TERMINAL
$ cue mod tidy

:material-chevron-right-circle-outline: Step 6{id=“step-6”}: Create a GitHub repository

If you haven’t already done so, create a repository called frostyconfig under your personal username at GitHub. It doesn’t matter if the repository is public or private.


:material-chevron-right-circle-outline: Step 7{id=“step-7”}: Create a git commit

TERMINAL
$ git add -A
$ git commit -q -m 'Initial commit'

Earlier, you initialized this module with --source=git, which told the cue command that it should publish only those files that git knows about. The git commit you just created leaves the directory in a “clean” state, which is necessary for cue to know exactly which files to include in the published module.


:material-chevron-right-circle-outline: Step 8{id=“step-8”}: Publish the first version of this module

TERMINAL
$ cue mod publish v0.0.1
...

!!! success

The output from this command should mention **your** GitHub username,
and should publish the module successfully.

If the command fails with an error message that mentions *your* GitHub username
then you probably haven't created the `frostyconfig` repository under your GitHub username.
Create it, and try the step again.

If the command fails with an error message that mentions `cueckoo/frostyconfig`
then you probably forgot to adapt the command in step 3, above.
Don't worry - this **isn't** a serious problem!

The easiest way to fix this is to delete your `frostyconfig` directory
and restart the tutorial from step 1.

Create a new frostyapp module that depends on the first module

Define the FrostyApp configuration, constrained by the schema you just published.

:material-chevron-right-circle-outline: Step 9{id=“step-9”}: Create a directory for the frostyapp module

Create a directory for the new module and initalize it, changing cueckoo to your GitHub username, lower-cased:

TERMINAL
$ mkdir ../frostyapp
$ cd ../frostyapp
$ git init -q
$ cue mod init --source=git github.com/cueckoo/frostyapp@v0

:material-chevron-right-circle-outline: Step 10{id=“step-10”}: Create the code for the new module

!!! info “Make sure to change cueckoo to your GitHub username, lower-cased, on the highlighted line.”

frostyapp/config.cue
package frostyapp

// Adapt this line to your GitHub username, lower-cased.
import "github.com/cueckoo/frostyconfig@v0"

config: frostyconfig.#Config & {
	appName: "alpha"
	port:    80
	features: logging: true
}

:material-chevron-right-circle-outline: Step 11{id=“step-11”}: Ensure the module is tidy

Tidy the module and add any missing dependencies:

TERMINAL
$ cue mod tidy

We can see that the dependencies have now been added to the cue.mod/module.cue file:

TERMINAL
$ cat cue.mod/module.cue
module: "github.com/cueckoo/frostyapp@v0"
language: {
	version: "v0.14.0"
}
source: {
	kind: "git"
}
deps: {
	"github.com/cueckoo/frostyconfig@v0": {
		v: "v0.0.1"
	}
}

Evaluate the configuration

:material-chevron-right-circle-outline: Step 12{id=“step-12”}: Export the configuration as YAML

TERMINAL
$ cue export --out yaml
config:
  appName: alpha
  port: 80
  features:
    logging: true

We can use this new module code just like any other CUE code.


Module published successfully!

Well done - you’ve finished! You have just created a module and published it to the Central Registry, and then used the newly published module to check a concrete configuration held in a different module.