Your first hscloud Change

This codelab will teach you how to send your first change to hscloud. We'll be modifying some files in your personal directory, so you won't bother anyone or break anything.

Prerequisites

Required: Checking out hscloud to understand the basics of the hscloud code structure.

Gerrit concepts

We use Gerrit as a code review and code gating platform for hscloud. Every change to hscloud is submitted and reviewed there.

Changes to hscloud in Gerrit are called, well, changes. Every change is a single commit, and every commit correspons to a single change. A change is submitted to the master branch by creating a Change Request (CR) in Gerrit. This CR will then be reviewed by owner(s) of codebase(s) that this CR touches, and then submitted to master. This model is somewhat similar to Pull/Merge Requests on other platforms like GitLab or GitHub, but vastly less complex due to the 1 CR == 1 commit mapping.

hscloud does not use any branches, and instead follows a single, rolling master.

Accessing Gerrit

Gerrit's main interface is available through the web, at https://gerrit.hackerspace.pl/. After signing, click the Gerrit logo to navigate to your dashboard, which should look something like this:

To access Gerrit via Git/SSH, you'll need to upload your SSH key to the Gerrit settings panel.

If you don't have an SSH key yet, generate one with the following command:

$ ssh-keygen -t ed25519     # and press return for every question
$ cat ~/.ssh/id_ed25519.pub # this is your public key

Then, add the key via the Gerrit web interface.

1. Click the gear icon in the top right corner:

2. Click 'SSH keys' in the sidebar:

3. Paste your SSH public key in the textbox and click 'Add new SSH key':

You should now be able to SSH into Gerrit. As Git access is also over SSH, this gives you access to Git as well.

$ ssh q3k@gerrit.hackerspace.pl
  ****    Welcome to Gerrit Code Review    ****

  Hi q3k, you have successfully connected over SSH.

  Unfortunately, interactive shells are disabled.
  To clone a hosted Git repository, use:

  git clone ssh://q3k@gerrit.hackerspace.pl/REPOSITORY_NAME.git
^C
$

Note that you should be using your Warsaw Hackerspace SSO user name. If that's different from your local workstation username, you'll have to specify user@gerrit.hackerspace.pl in all the following commands.

Connecting your hscloud checkout to Gerrit

If you've come here from the Checking out hscloud codelab, you probably already have a read-only hscloud checkout over HTTPS. If so, you will have to switch its remote to access Gerrit through your SSH key:

$ cd hscloud
$ git remote remove origin
$ # If your local username is the same as your SSO username:
$ git remote add origin gerrit.hackerspace.pl:hscloud
$ # Otherwise, you'll have to specify your SSO username explicitly:
$ git remote add origin user@gerrit.hackerspace.pl:hscloud

Or, if you don't have a hscloud checkout on hand, just clone it from scratch using the authenticated Gerrit endpoint:

$ git clone gerrit.hackerspace.pl:hscloud
Cloning into 'hscloud'...
remote: Counting objects: 162, done
remote: Finding sources: 100% (162/162)
remote: Total 5469 (delta 45), reused 5439 (delta 45)
Receiving objects: 100% (5469/5469), 15.25 MiB | 14.08 MiB/s, done.
Resolving deltas: 100% (2686/2686), done.
$ cd hscloud

Configuring git for Gerrit

You now have hscloud cloned from an authenticated Gerrit endpoint. Gerrit knows it's you trying to access (and/or write) code. However, there's just a bit more of one-time setup that you'll need to do in order to send changes to Gerrit:

$ git config user.email 'user@hackerspace.pl' # replace user with your SSO login name
$ curl -Lo .git/hooks/commit-msg https://gerrit.hackerspace.pl/tools/hooks/commit-msg
$ chmod +x .git/hooks/commit-msg

This sets up the email for the repository to correspond to your Hackerspace email address, and sets up the Gerrit Change-Id autogeneration hook (more on that later). You only need to run this once for each hscloud clone.

Changing something

We're ready to go! Every hscloud contributor can edit any file they want in //personal/$user without having to go through code review. Let's create a file there.

$ mkdir -p personal/$USER
$ cd personal/$USER
$ echo '**Hello, world!**' > hello.md

Feel free to be more creative what the contents of this file. But remember - anything you submit to hscloud, or any CR you create, is visible to the entire world!

Then, create a git commit containing your changes:

$ git add hello.md
$ git commit -m "personal: say hello"

This is standard git stuff. However, if you take a closer look at the commit you've just created, you'll see a Change-Id: line has been added:

$ git log -1
commit 222a00a25adeadbeeff7ec0a409deadc0de49fb4
Author: Sergiusz Bazanski <q3k@hackerspace.pl>
Date:   Sun Apr 12 18:37:21 2020 +0200

    personal: say hello
    
    Change-Id: I161ca0deadcode86c9b1446b141ecf1421372d9c

This Change-Id uniquely identifies Gerrit Changes and CRs. This means that no matter the content of the commit message, or the parent of the commit, Gerrit will be able to map your work to a CR. You'll see more of this in a bit, when we modify our change. But for now, first, let's push it to Gerrit. This step is likely the largest difference between Gerrit and other git-based code revie software:

$ git push origin HEAD:refs/for/master
[...]
remote: Resolving deltas: 100% (2/2)
remote: Processing changes: refs: 1, new: 1, done    
remote: 
remote: SUCCESS
remote: 
remote:   https://gerrit.hackerspace.pl/c/hscloud/+/XXXX personal: say hello [NEW]
remote: 

In case you're confused: what's happening here is that you're pushing whatever you have at the top of your local git history to Gerrit. Gerrit will then look at all commits pushed, and create a new CR for every commit whose Change-Id it cannot match to an existing CR. New CRs will then get assigned a sequential CR number, which will be printed to the command line. You can either copy the full URL, or just the number and go to https://gerrit.hackerspace.pl/1234 (where 1234 is your CR number).

Viewing your CR in Gerrit

This is how your CR should look like in the Gerrit UI:

This might look daunting - but don't panic. The Gerrut UI is very utilitarion, and once you get through it's somewhat-not-flat learning curve you'll be wishing you could use Gerrit everywhere.

To help you understand what's going on, we've divided the view into multiple, labeled sections - and we'll go through them one by one.

  • Commit/Change data - this should look familiar: it's the commit you've submitted. Because of the change/commit mapping, the commit message is also the main message of the CR, and is what your reviewers will see. Also take note of the Reply button - we will not use it today, but it is used to review code and to reply to code comments.
  • Files - this is a collapsed view of all files that are going to be affected by this change. To view individual files, click their file names, or the 'expand all files' button. You can also use keyboard shortcuts to navigate files quickly (press ? on your keyboard to learn more).
  • Metadata - these are fields related to the CR but not strictly to the change itself. This is for instance: the owner/author of the change, the assigned reviewers, the repository/branch names, etc. You will notice the CR in the screenshot has a reviewer attached. Hopefully, yours won't, as personal changes should not trigger review requests. If it does, it means q3k still hasn't fixed this.
  • Labels - labels are a Gerrit construct that represent people's and system's votes to include your change in hscloud. Generally, all labels must have a positive value set in order for a CR to be submittable. As this is a personal directory change, you will automatically get a Personal-Only 'okay' label. Otherwise, you would get a Code-Review 'needed' label, which would have to be fulfilled by a vote before your change could be submitted.
  • Changelog - this is a unified history of this CR. Any metadata update or code review comment will be reflected in a history here. In addition, subsequent versions of your CR will appear here as 'patch sets', numbered from 1 onwards.
  • Actions - these buttons, and the three-dots menu to the right, mostly serve to manage the lifecycle of the CR. You will notice a Submit button here - don't press it yet, though :). Some other buttons will appearify here when you're viewing a change in a different context, for instance a 'Code Review +1' button if you were reviewing the change instead.

Updating your CR

To make this a bit more interesting, let's do one more quick thing before we submit our CR: update it! This will hopefully show you a bit more about how Gerrit maps changes to commits.

$ echo "I am a change." >> hello.md
$ git add hello.md
$ git commit --amend
$ git push origin HEAD:refs/for/master

You should notice that the flow to update a CR is pretty symmetrical to the flow that was used to create it. Instead of adding another commit on top (polluting history), you just amend your existing commit with whatever changes you want. This also means you can use quite powerful git constructs like rebase -i to alter history (for instance, stack one CR on top of another!) and arrange things in a pretty way.

Regardless, the Gerrit CR view should now show a new patch set appear in your change. Feel free to mess around more with this, or just press the Submit button when you're ready :).

Observing your change

You should now be able to pull from Gerrit again and observe that your commit is now on master:

$ git checkout master
$ git fetch origin master
$ git reset --hard origin/master
$ git log

Naturally, your change should also be visible in gitiles.

Further steps

  • If you need a Git refresher - we highly recommend the Git Visual Reference
  • Bazel & Go basics will (TODO) guide you through building some code using Bazel, and then writing a tiny bit of Go code of your own.
  • Prepare environment with nix will guide you through accessing our production Kubernetes cluster and running some code on it.