Development Guide

Building Kedge

Read about building kedge here.

Workflow

Fork the main repository

  1. Go to https://github.com/kedgeproject/kedge
  2. Click the “Fork” button (at the top right)

Clone your fork

The commands below require that you have $GOPATH. We highly recommended you put Kedge’ code into your $GOPATH.

git clone https://github.com/$YOUR_GITHUB_USERNAME/kedge.git $GOPATH/src/github.com/kedgeproject/kedge
cd $GOPATH/src/github.com/kedgeproject/kedge
git remote add upstream 'https://github.com/kedgeproject/kedge'

Create a branch and make changes

git checkout -b myfeature
# Make your code changes

Keeping your development fork in sync

git fetch upstream
git rebase upstream/master

Note: If you have write access to the main repository at github.com/kedgeproject/kedge, you should modify your git configuration so that you can’t accidentally push to upstream:

git remote set-url --push upstream no_push

Committing changes to your fork

git commit
git push -f origin myfeature

Creating a pull request

  1. Visit https://github.com/$YOUR_GITHUB_USERNAME/kedge.git
  2. Click the “Compare and pull request” button next to your “myfeature” branch.
  3. Check out the pull request process for more details

Dependency management

Kedge uses glide to manage dependencies. If you want to make changes to dependencies please make sure that glide is in your $PATH.

Installing glide

There are many ways to build and host golang binaries. Here is an easy way to get utilities like glide and glide-vc installed:

Ensure that Mercurial and Git are installed on your system. (some of the dependencies use the mercurial source control system). Use apt-get install mercurial git or yum install mercurial git on Linux, or brew.sh on OS X, or download them directly.

go get -u github.com/Masterminds/glide

Check that glide is working.

glide --version

Using glide

Adding new dependency

  1. Update glide.yaml file

Add new packages or subpackages to glide.yaml depending if you added whole new package as dependency or just new subpackage.

Kedge vendors OpenShift and all its dependencies. (see comments in glide.yaml and ./scripts/vendor-openshift.yaml) It is possible that the dependency you want to add is already in OpenShift as a vendored dependency. If that is true, please make sure that you use the same version OpenShift is using.

  1. Get new dependencies
make vendor-update
  1. Commit updated glide files and vendor
git add glide.yaml glide.lock vendor
git commit

Updating dependencies

  1. Set new package version in glide.yaml file.

  2. Clear cache

glide cc

This step is necessary if not done glide will pick up old data from it’s cache.

  1. Get new and updated dependencies
make vendor-update
  1. Commit updated glide files and vendor
git add glide.yaml glide.lock vendor
git commit

Updating OpenShift

  1. Update OPENSHIFT_VERSION within scripts/vendor-openshift.sh

  2. Clear the cache to prevent glide from using previous data

glide cc
  1. Retrieve new and updated dependencies
make vendor-update
  1. Commit updated glide files and vendor
git add glide.yaml glide.lock scripts/vendor-openshift.sh vendor
git commit

PR review guidelines

Note: Above guidelines are not hard rules use those with discretion

Running tests

Run all tests except end-to-end tests

make test

Run end-to-end tests

Before running end to end tests locally make sure minikube is running.

make bin
make test-e2e

Note: When you run end to end tests, those tests are run in parallel. If you are low on resources you can limit number of tests that run in parallel by doing following:

make test-e2e PARALLEL=4

This will run only 4 tests in parallel. By default, it is set to the value of GOMAXPROCS.

You may also add a timeout which will increase the overall timeout period for the tests.

make test-e2e TIMEOUT=15m

types.go conventions

Validation

In order to facilitate consistent error messages, we ask that validation logic adheres to the following guidelines whenever possible (though exceptional cases will exist).

Taken from: github.com/kubernetes/community/contributors/devel/api-conventions.md

Naming conventions

Taken from: github.com/kubernetes/community/contributors/devel/api-conventions.md

Optional vs. Required

Fields must be either optional or required.

Optional fields have the following properties:

In most cases, optional fields should also have the omitempty struct tag (the omitempty option specifies that the field should be omitted from the json encoding if the field has an empty value).

Required fields have the opposite properties, namely:

Using the +optional or the omitempty tag causes OpenAPI documentation to reflect that the field is optional.

Using a pointer allows distinguishing unset from the zero value for that type. There are examples of this in the codebase. However:

Therefore, we ask that pointers always be used with optional fields that do not have a built-in nil value.

Inspired from: github.com/kubernetes/community/contributors/devel/api-conventions.md

General guidelines for developers

golang dependency import conventions

Imports MUST be arranged in three sections, separated by an empty line.

stdlib
kedge
thirdparty

For example:

"fmt"
"io"
"os/exec"

pkgcmd "github.com/kedgeproject/kedge/pkg/cmd"
"github.com/kedgeproject/kedge/pkg/spec"

"github.com/ghodss/yaml"
"github.com/pkg/errors"

Once arranged, let gofmt sort the sequence of imports.

Code instructions

Things to take care of when adding new type:

Issue labeling

Most of the issues should have at least size and priority and kind label.

size/*

size/* labels are for estimating size. It should estimation how complicated it is going to be to solve given problem.

size/S

Simple change, just few lines (no more than 1 day of work).

size/M

Considerable change but fair straightforward problem statement. This is the default size. If you are not sure about the sizes of the task, you can start with marking it as size/M and adjust size later on.

size/L

A bit more complicated to solve, maybe requiring small refactoring of existing code.

size/XL

Complex change, new big feature, requiring big refactoring, perhaps is an epic and should be broken into smaller tasks.

priority/*

priority/low

The lowest priority, the issue is not affecting any functionality or it is nice to have feature.

priority/medium

Medium should be a default priority. If you are not sure about priority of the issue mark it as priority/medium.

priority/high

High priority means that this is important feature that will help someone start using Kedge, or it is a bug that is affecting existing users.

priority/urgent

If issue is marked as urgent it means that it should be solved before everything else (Drop everything and work on this). Bug marked as priority/urget completely breaks important Kedge functionality. Usually it doesn’t make sense to new features as priority/urgent.

kind/*

kind/blocker

This issue is blocking some other issue. There should be a commend that is explaining what issue is blocked and why.

Related labels: status/blocked

kind/bug

This is a bug. Something that should be working is broken.

kind/CI-CD

Issue is touching CI/CD area.

kind/discussion

This issue is discussion. The discussion can be about new features or changes or anything that is related to the project.

Related labels: status/decided, status/undecided

kind/documentation

Issues related to documentation.

kind/enhancement

This issue is improving already existing functionality.

kind/epic

Issues marked as kind/epic are usually description of a larger goal or feature. Before any actual coding work can be started on this it should be broken down to smaller smaller features (kind/feature) or tasks (kind/task)

kind/feature

This is a description or definition of a new feature.

kind/question

Someone is asking a question. Once the question is answered the issue should be closed.

kind/refactor

This is work on definition of some kind of refactoring effort.

kind/task

This is clear definition of a task that can be assigned and work on this can start.

kind/tests

Issue related to test and testing.

kind/user-experience

This issue is touching user experience.

status/*

status/blocked

This issue is blocked by some other issue. There should be a commend explaining why this issue is blocked and what is blocking it. Issue that is blocking it should be marked as kind/blocker.

Related labels: kind/blocker

status/decided

This usually goes together with kind/discussion. Once a discussion ended and decision was made issue should be labeled status/decided.

Related labels: kind/discussion

status/discussion-ongoing

status/do-not-review

Used for PRs. It means that PR is Work In Progress and it will change a lot. Currently it is not worth to do any reviews on it.

status/needs-rebase

Used for PRs. There are conflicts and branch needs rebase and resolving conflicts.

status/needs-review

Used for PRs. All work is done, and PR just need review.

status/undecided

This usually goes together with kind/discussion. This means that conclusion was not yet made.

Related labels: kind/discussion

status/work-in-progress

Used for PRs. It means that PR is Work In Progress. Some preliminary reviews can be done, but it can’t be merged yet, as something is still missing.

other

duplicate

Issue is a duplicate of other already existing issue.

help wanted

invalid

wontfix