Manual Orb Authoring Process
This guide covers the steps required to create a simple orb, manually, without using the orb development kit. We recommend the orb development kit for most orb projects.
1. Create a namespace
If you have not already done so, claim a namespace for your user/organization using the following command, substituting your namespace choice and GitHub organization name:
circleci namespace create <name> --org-id <your-organization-id>
2. Create your orb
Create your orb inside your namespace. At this stage no orb content is being generated, but the naming is reserved for when the orb is published. To create a public orb:
circleci orb create <my-namespace>/<my-orb-name>
To create a private orb:
circleci orb create <my-namespace>/<my-orb-name> --private
--private
flag is not currently supported on CircleCI server. Orbs created within a server installation will only be visible to authenticated users.Next, create the content of your orb in a YAML file. Here is a simple example to get you started:
version: 2.1
description: A greeting command orb
commands:
greet:
description: Greet someone with a "hello".
parameters:
to:
type: string
default: World
steps:
- run: echo "Hello, << parameters.to >>"
3. Pack a configuration (optional)
The CLI pack command (different than circleci orb pack
) allows you to create a single YAML file from several separate files (based on directory structure and file contents). The pack
command implements FYAML, a scheme for breaking YAML documents across files in a directory tree. This is particularly useful for breaking up source code for large orbs and allows custom organization of your orbs’ YAML configuration.
circleci config pack
How you name and organize your files when using the pack
command will determine the final orb.yml
output. Consider the following folder structure example:
$ tree
.
└── your-orb-source
├── @orb.yml
├── commands
│ └── foo.yml
└── jobs
└── bar.yml
3 directories, 3 files
The unix tree
command is great for printing out folder structures. In the example tree structure above, the pack
command will map the folder names and file names to YAML keys, and map the file contents as the values to those keys.
The following command will pack
up the example folder from above:
$ circleci config pack your-orb-source
And the output will be in your .yml
file:
# Contents of @orb.yml appear here
commands:
foo:
# contents of foo.yml appear here
jobs:
bar:
# contents of bar.yml appear here
Other configuration packing capabilities
A file beginning with @
will have its contents merged into its parent folder level. This can be useful at the top level of an orb, when one might want generic orb.yml
to contain metadata, but not to map into an orb
key-value pair.
Thus:
$ cat foo/bar/@baz.yml
{baz: qux}
Is mapped to:
bar:
baz: qux
4. Validate your orb
Validate your orb code using the CLI:
circleci orb validate /tmp/orb.yml
Processing a configuration (optional)
Running the following command validates your configuration, but will also display expanded source configuration alongside your original configuration (useful if you are using orbs):
circleci config process
Consider the following example configuration that uses the node
orb:
version: 2.1
orbs:
node: circleci/node@4.7.0
workflows:
example-workflow:
jobs:
- node/test
Running the following command will output a YAML file like the example below (which is a mix of the expanded source and the original configuration commented out):
circleci config process .circleci/config.yml
# Orb 'circleci/node@4.7.0' resolved to 'circleci/node@4.7.0'
version: 2
jobs:
node/test:
docker:
- image: cimg/node:13.11.0
steps:
- checkout
- run:
command: |
if [ ! -f "package.json" ]; then
echo
echo "---"
echo "Unable to find your package.json file. Did you forget to set the app-dir parameter?"
echo "---"
echo
echo "Current directory: $(pwd)"
echo
echo
echo "List directory: "
echo
ls
exit 1
fi
name: Checking for package.json
working_directory: ~/project
- run:
command: |
if [ -f "package-lock.json" ]; then
echo "Found package-lock.json file, assuming lockfile"
ln package-lock.json /tmp/node-project-lockfile
elif [ -f "npm-shrinkwrap.json" ]; then
echo "Found npm-shrinkwrap.json file, assuming lockfile"
ln npm-shrinkwrap.json /tmp/node-project-lockfile
elif [ -f "yarn.lock" ]; then
echo "Found yarn.lock file, assuming lockfile"
ln yarn.lock /tmp/node-project-lockfile
fi
ln package.json /tmp/node-project-package.json
name: Determine lockfile
working_directory: ~/project
- restore_cache:
keys:
- node-deps-{{ arch }}-v1-{{ .Branch }}-{{ checksum "/tmp/node-project-package.json" }}-{{ checksum "/tmp/node-project-lockfile" }}
- node-deps-{{ arch }}-v1-{{ .Branch }}-{{ checksum "/tmp/node-project-package.json" }}-
- node-deps-{{ arch }}-v1-{{ .Branch }}-
- run:
command: "if [[ ! -z \"\" ]]; then\n echo \"Running override package installation command:\"\n \nelse\n npm ci\nfi\n"
name: Installing NPM packages
working_directory: ~/project
- save_cache:
key: node-deps-{{ arch }}-v1-{{ .Branch }}-{{ checksum "/tmp/node-project-package.json" }}-{{ checksum "/tmp/node-project-lockfile" }}
paths:
- ~/.npm
- run:
command: npm run test
name: Run NPM Tests
working_directory: ~/project
workflows:
version: 2
example-workflow:
jobs:
- node/test
# Original config.yml file:
# version: 2.1
#
# orbs:
# node: circleci/node@4.7.0
#
# workflows:
# version: 2
# example-workflow:
# jobs:
# - node/test
5. Publish your orb
Publish a dev version of your orb:
circleci orb publish /tmp/orb.yml <my-namespace>/<my-orb-name>@dev:first
Once you are ready to push your orb to production, you can publish it manually using circleci orb publish
or promote it directly from the dev version. Using the following command will increment the dev version to become 0.0.1
:
circleci orb publish promote <my-namespace>/<my-orb-name>@dev:first patch
Your orb is now published, in an immutable form, as a production version and can be used safely in CircleCI projects. You can pull the source of your orb using:
circleci orb source <my-namespace>/<my-orb-name>@0.0.1
List available orbs
List your available orbs using the CLI:
To list public orbs:
circleci orb list <my-namespace>
To list private orbs:
circleci orb list <my-namespace> --private
Next Steps
For more information on how to use the circleci orb
command, see the CLI documentation.