When to add a plan to core plans
Participation in the Habitat community is governed by the code of conduct.
You can browse all available packages that you can leverage and use, including packages built and maintained by community members both inside and outside of this core origin, in Habitat Builder.
Keep in mind that a core plan must by definition be abstracted to serve a wide array of users in service of their applications. If you are building a plan that is tailor made for your own unique application or specific use case, it is better suited to your own origin. Packages can be made public in your own origin too. Community and external project owned origins are an awesome way to make, share, and use functionality that lives outside of and extends core plans.
Requirements to add a plan to core plans
In order for a package to be accepted as a core package, the following requirements must be met:
- Package Metadata
- Package Name Conventions
- Adding an older version of a core package
- Plan syntax
- Linting your plans
- Pre-commit hooks
- Signing your commits
- Separate changes, separate PRs
- Pull request review and merge automation
- Add yourself as a CODEOWNER
- Add yourself to core plans maintainers
Each package plan in this repository must contain a value adhering to the guidelines for each of the following elements:
pkg_license(in SPDX format)
pkg_maintainerin the format of "The Habitat Maintainers firstname.lastname@example.org"
pkg_namesee the section of this document on "Package Name Conventions"
pkg_originmust be set to
pkg_versionmust be the complete version number of the software
Package Name Conventions
Each package is identified by a unique string containing four sub-strings separated
by a forward slash (
/) called a PackageIdent.
version values of this identifier are user defined by
setting their corresponding variable in your
plan.sh file while the value of
release is generated at build-time.
The value of
name should exactly match the name of the project it represents and the
plan.sh file should be located within a directory of the same name in this repository.
Example: The plan for the bison project project contains setting
pkg_name=bisonand resides in
There is one exception to this rule: Additional plans may be defined for projects for their past major versions by appending the major version number to its name. The
plan.sh file for this new package should be located within a directory of the same name.
Example: the bison project maintains the 2.x line along with their current major version (at time of writing: 3.x). A second plan is created as
bison2and placed within a directory of the same name in this repository.
Packages meeting this exception will always have their latest major version found in the package sharing the exact name of their project. A new package will be created for the previous major version following these conventions.
Example: the bison project releases the 4.x line and is continuing to support Bison 3.x. The
bisonpackage is copied to
bisonpackage is updated to build Bison 4.x.
Adding an older version of a core package
Sometimes you may need a version of software that we are packaging which was released before the project's corresponding Habitat core package was created.
Please do not issue a PR containing a new plan for the specific version of software that you need unless the software project it packages meets the exceptional cases outlined in the above section "Package Name Conventions". Instead create an issue containing the name and version of the software that you want published to Habitat Builder. A maintainer will run a one-off build and publish the generated artifact to the public depot and close your issue once the work is completed.
Issues with an associated gist containing a working fork of our current plan which builds the version of the software will be attended to first.
If your package has dependencies, it must only depend on other packages in the core origin.
Pinned versions are not allowed as they prevent package rebuilds and will cause dependencies conflicts.
You can review the entire plan syntax guide here.
Please note that the following conditions must be observed for any plan to be merged into core plans (and are important best practices for any plan):
Plan basic settings
You can read more about basic plan settings here. The minimum requirements for a core plan are:
- pkg_name is set
- pkg_origin is set
- pkg_shasum is set
- pkg_description is set
You can read more about callbacks here. The minimum requirement for a core plan are:
do_prepare()is a good place to set environment variables and set the table to build the software. Think of it as a good place to do patches.
- You should never call
exitwithin a build phase. You should instead return an exit code such as
return 1for failure, and
return 0for success.
- If you clone a repo from git, you must override
- Never use
pkg_sourceunless you are downloading something as a third party.
- You should never shell out to
habfrom within a callback. If you think you want to, you should use a utility function instead.
- You should not call any function or helper that begin with an underscore, for example
_dont_call_this_function(). Those are internal only functions that are not supported for external use and will break your plan if you call them.
- Don't run any code or run anything outside of a build phase or bash function.
The supervisor dynamically invokes hooks at run-time, triggered by an application lifecycle event. You can read more about hooks here.
- You cannot block the thread in a hook unless it is in the
runhook. Never call
sleepin a hook that is not the
- You should never shell out to
habfrom within a hook. If you think you want to, you should use a runtime configuration setting instead. If none of those will solve your problem, open an issue and tell the core team why.
- Run hooks should:
exec 2>&1at the start of the hook)
- Call the command to execute with
exec <command> <options>rather than running the command directly. This ensures the command is executed in the same process and that the service will restart correctly on configuration changes.
- If you are running something with a pipe
- Always assume a minimal BusyBox
shimplementation, never GNU Bash unless
core/bashis an explicit run dependency and the hook's shebang line calls this Bash interpreter directly.
- Attempting to execute commands as a
rootuser or trying to do
sudo hab installare not good practice.
- Don't edit any of the Supervisor rendered templates.
- You can only write to:
/data/directories. You should only access these with your
runtime configuration settingvariable.
- No one should ever edit anything in
- No one should write to anything in
- You can only write to:
Adding a new plan to core-plans requires updating
.bldr.toml with your new package plan. This is so that Builder can map all of the plans to their respective directories.
Check out the core plans README template for a quick start!
All plans should have a README. In core plans, it is a hard requirement. Your README at a bare minimum should include:
- Your name as maintainer and supporter of this plan.
- Absolutely required:
- What habitat topology it uses (and the plan should have the correct topology for the technology).
- Clear, step by step instructions as to how to use the package successfully.
- What is the best update strategy for different deployments?
- What are some configuration updates a user can make, or do they always need to do a full rebuild?
- Strongly recommended:
- Documentation on how to scale the service.
- Instructions on how to monitor the health of the service at the application layer.
- Can a user simply call the package as a dependency of their application?
- How does the package integrate into their developer workflow?
Linting Your Plans
It is good it use a tool to lint your plans to ensure you are not making any easy-to-catch mistakes in your scripting. We recommend running ShellCheck against your plans.
Some default checks of ShellCheck can be turned off, since they aren't necessarily applicable in plans. The following options work well:
shellcheck --shell=bash --exclude=SC1090,SC1091,SC2034,SC2039,SC2148,SC2153,SC2154,SC2140
If ShellCheck is installed, you can run this (and other checks) locally with:
git add <your changes> && pre-commit run
See below for more about the pre-commit hooks.
Install pre-commit to run prior to your commits. This will perform some initial checks against your changes and recommend any fixes before you commit.
Signing Your Commits
This project utilizes a Developer Certificate of Origin (DCO) to ensure that each commit was written by the author or that the author has the appropriate rights necessary to contribute the change. The project utilizes Developer Certificate of Origin, Version 1.1
Developer Certificate of Origin Version 1.1 Copyright (C) 2004, 2006 The Linux Foundation and its contributors. 660 York Street, Suite 102, San Francisco, CA 94110 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Developer's Certificate of Origin 1.1 By making a contribution to this project, I certify that: (a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it. (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved.
Each commit must include a DCO which looks like this
Signed-off-by: Joe Smith <email@example.com>
The project requires that the name used is your real name. Neither anonymous contributors nor those utilizing pseudonyms will be accepted.
Git makes it easy to add this line to your commit messages.
- Make sure the
user.emailare set in your git configs.
--signoffto add the Signed-off-by line to the end of the commit message.
Separate Changes, Separate Pull Requests
Each package being changed should be separated into its own pull request. E.g. If you are making a change to
core/openssl and your change requires another change in
core/curl to be merged, each of these changes should be submitted as two different PRs with a note about the order in which each thing should be submitted.
Each of these change PRs submitted should include a bracketed packagename as the prefix to the change information. For example in the previously defined situation the PR titles above might titled like so:
[curl] Making a change here
[openssl] Also making a change here
If you have opened a single PR that changes multiple plans, it is assumed you are making a substantial change to core plans. Substantial change PRs submitted without an RFC will be closed and you will be directed to open an RFC. If this was not your intention please open separate PRs per package change. RFCs live in their own repository. To open one, write one up according to the template, and open a pull request.
Pull Request Review and Merge Automation
Habitat uses a bot to automate merging of pull requests. Messages to and from the bots are brokered via the account @thesentinels which can process incoming commands from reviewers to approve PRs. These commands are routed to a sentinel bot that will automatically merge a PR when sufficient reviewers have provided a +1 (or @thesentinels
approve in sentinels terminology).
We use GitHub's integrated CODEOWNERS to determine a appropriate reviewer(s). You must receive an approval from at least one CODEOWNER if there is one present for the plan you are modifying.
Add yourself as a CODEOWNER
You may optionally add yourself as a CODEOWNER of a plan. Adding yourself as an owner means you have a vested interest in the software packaged by the plan and you, or another owner of the plan, will be required to review suggested changes. At least one CODEOWNER's approval is always required for a change to be accepted even if the change has been reviewed by a core plans maintainer.
Add yourself to core plans maintainers
You can add yourself to core plans maintainers to take a greater role and responsibility in the care, feeding, and maintenance of all core plans.