Table of Contents
First: if you're unsure or afraid of anything, just ask or submit the issue or pull request anyways. You won't be yelled at for giving your best effort. The worst that can happen is that you'll be politely asked to change something. We appreciate all contributions!
For those folks who want a bit more guidance on the best way to contribute to the project, read on. Addressing the points below lets us merge or address your contributions quickly.
-
Make sure you test against the latest released version. It is possible we already fixed the bug you're experiencing.
-
If you experienced a panic, please create a gist of the entire generated crash log for us to look at. Double check no sensitive items were in the log.
-
Respond as promptly as possible to any questions made by the doctl team to your issue. Stale issues will be closed.
-
The issue is reported.
-
The issue is verified and categorized by a doctl collaborator. Categorization is done via labels. For example, bugs are marked as "bugs".
-
Unless it is critical, the issue is left for a period of time (sometimes many weeks), giving outside contributors a chance to address the issue.
-
The issue is addressed in a pull request. The issue will be referenced in commit message(s) so that the code that fixes it is clearly linked.
-
The issue is closed. Sometimes, valid issues will be closed to keep the issue tracker clean. The issue is still indexed and available for future viewers, or can be re-opened if necessary.
doctl
has make
commands for most tooling in the Makefile
. Run make
or make help
for a list of available commands with descriptions.
The minimal version of Golang for doctl
is 1.11. doctl
uses Go
modules for dependency
management with vendoring.
Please run make vendor
after any dependency modifications.
Be sure to run go fmt
on your code before submitting a pull request.
You can create a local Docker container via make docker_build
.
Run the tests locally via make test
, or on Travis CI by pushing a branch to your fork
on github.
In doctl, we have two kinds of tests: unit tests and integration tests. Both are run with Go's
built-in go test
tool.
Unit tests live in the _test.go
files. The bulk of these tests live in the commands
package,
and exist to ensure that a CLI command produces an expected output. For each unit test, we
typically rely on an accompanying mocked API call. These mocks are generated via gomock
, and
can be set to return different values from the API calls to test how our commands behave when
given different inputs.
Writing a unit test for a new command typically looks like this,
- Write your new command.
- If your new command depends on a mocked
godo
call, generate a mock for it. See the section below about regenerating mocks to learn how to do this. - Use your new mocks to stub out the API call, and write a test case. We use
github.com/stretchr/testify/assert
for our assertions. Test cases typically look like the following:func TestMyNewCommand(t *testing.T) { // Use the `withTestClient` helper to access our tets config, as well as the godo API // mocks. withTestClient(t, func(config *CmdConfig, tm *tcMocks) { // Mock the godo API call. tm.myNewCommandMock.EXPECT().Get("some-value").Return("some-other-value") // Optionally add a CLI argument. config.Args = append(config.Args, "some-value") // Optionally add a CLI flag. config.Doit.Set(config.NS, "--my-flag", "some-value") // Execute your command. err := RunMyNewCommand(config) // Add assertions to check if your test passes. assert.NoError(t, err) }) }
Integration tests live under the top-level integration
directory. These tests exist to ensure
that an invocation of a command though this CLI produces the expected output. These tests use a
mocked HTTP client, but run the actual compiled doctl binary.
Writing an integration test typically looks like this,
- Write your new command.
- Mock the API's JSON response that your command depends on.
- Execute your command using
exec.Command
on the test CLI binary. - Add assertions to check the output from the CLI command.
Rather than providing an example here, please have a look at the integration/account_test.go
file to see what an integration test typically looks like.
When you upgrade godo
you have to re-generate the mocks.
```
make mocks
```
If you modify the build scripts, you can use make shellcheck
to
check your changes. You'll need to install shellcheck
to do so. Travis also runs shellcheck.
doctl
releases are orchestrated by Travis CI,
triggered when a new tag is pushed to master.
-
Run
make changes
to review the changes since the last release. Based on the changes, decide what kind of release you are doing (bugfix, feature or breaking).doctl
follows semantic versioning, ask if you aren't sure. -
Tag the release using
BUMP=(bugfix|feature|breaking) make tag
. (Bugfix, feature and breaking are aliases for semver's patch, minor and major. BUMP will also acceptpatch
,minor
andmajor
, if you prefer). The command assumes you have a remote repository namedorigin
pointing to this repository. If you'd prefer to specify a different remote repository, you can do so by settingORIGIN=(preferred remote name)
.
In case of an issue with the travis deployments:
make release
releases the most recent tag to github releases and
dockerhub images. If make release
fails, you can always fall back to
goreleaser
itself.
- goreleaser
- docker
- a valid
GITHUB_TOKEN
environment variable with access to thedigitalocean/doctl
repo. You can generate a token here, it needs thepublic_repo
access. - a valid Docker Hub login with access to the
digitalocean
account. Post in #it_support to request access.
make snap
builds and pushes a snap for the most recent tag to the
snap store. Specify the release channel using the environment
variable CHANNEL
, which defaults to stable
:
CHANNEL=candidate make _snap
If make snap
fails, you can fall back to building and pushing the
snap manually.
- docker
- a valid ubuntu one login with access to the
digitalocean
snapcraft account. Post in #it_support to request access.
Using the url and sha from the github release, update the
homebrew formula.
You can use brew bump-formula-pr doctl
, or
- fork
homebrew-core
- create a branch named
doctl-<version>
- update the url and the sha256 using the values for the archive in the github release
- commit your changes
- submit a PR to homebrew