doc: add getting-started/your-first-change

Change-Id: Ib3d3805507e2cb5ef0194605f081c74719f3b1a3
diff --git a/README.md b/README.md
index 7d2684d..3f13173 100644
--- a/README.md
+++ b/README.md
@@ -13,31 +13,28 @@
 Getting started
 ---------------
 
-You will need Bash and Bazel (1.2.0+).
-
-First, clone the repository:
-
-    git clone https://gerrit.hackerspace.pl/hscloud
-    cd hscloud
-
-Then, set up everything:
-
-    . ./env.sh       # setup PATH and hscloud_root
-    tools/install.sh # build tools
-
-A bunch of common tools will appearify in your `$PATH`. You should now be ready to follow other documentation.
-
-This does not pollute your system, and you can work on multiple hscloud checkouts independently.
-
-What now?
----------
-
-If you want to use our Kubernetes cluster to run some stuff, see [//cluster/doc/user.md](cluster/doc/user.md).
-
-If you're looking for administrative docs about cluster maintenance, see [//cluster/doc/admin.md](cluster/doc/admin.md).
+See [//doc/codelabs](/doc/codelabs) for tutorials on how to use hscloud.
 
 If you want to browse the source of `hscloud` in a web browser, use [gerrit's gitiles](https://gerrit.hackerspace.pl/plugins/gitiles/hscloud/+/refs/heads/master/).
 
-If you want to learn how to contribute to this repository, see [//doc/codelab/gerrit](doc/codelab/gerrit).
+If you want some other help, talk to q3k, informatic or your therapist.
 
-If you want help, talk to q3k, informatic or your therapist.
+Directory Structure
+-------------------
+
+Directories you should care about:
+
+ - **app**: external services that we host that are somewhat universal: matrix, covid-formity, etc.
+ - **bgpwtf**: code related to our little ISP
+ - **cluster**: code related to our Kubernetes cluster (`k0.hswaw.net`)
+ - **dc**: code related to datacenter automation
+ - **devtools**: code related to developer tooling, like gerrit or hackdoc
+ - **doc**: high-level documentation that doesn't fit anywhere else, ie. codelabs
+ - **hswaw**: Warsaw Hackerspace specific/internal services. The line between this and **app** is unfortunately blurry.
+ - **personal**: user's personal (experimental) directories
+ - **kube**, **go**: code specific to languages but general to the whole of hscloud
+
+Licensing
+---------
+
+Unless noted otherwise, code in hscloud is licensed under the BSD 0-clause license - see [COPYING](/COPYING).
diff --git a/devtools/hackdoc/tpl/default.html b/devtools/hackdoc/tpl/default.html
index 3e3b268..edb4c33 100644
--- a/devtools/hackdoc/tpl/default.html
+++ b/devtools/hackdoc/tpl/default.html
@@ -146,6 +146,10 @@
     color: #555;
 }
 
+.content strong {
+    font-weight: 600;
+}
+
 .content code {
     font-family: Consolas, monospace;
     background-color: #f8f8f8;
@@ -166,6 +170,7 @@
 
 .content ul {
     padding-top: 0.5em;
+    line-height: 1.5em;
 }
 
 .content ul li {
@@ -180,6 +185,12 @@
     margin-left: -1em;
 }
 
+.content img {
+    max-width: 90%;
+    margin: 1em auto 1em auto;
+    display: block;
+}
+
 .toc {
     float: right;
     padding: 1em 1em 1em 1em;
diff --git a/doc/codelabs/getting-started/img/gerrit-change-annotated.png b/doc/codelabs/getting-started/img/gerrit-change-annotated.png
new file mode 100644
index 0000000..8b1b352
--- /dev/null
+++ b/doc/codelabs/getting-started/img/gerrit-change-annotated.png
Binary files differ
diff --git a/doc/codelabs/getting-started/img/gerrit-change.png b/doc/codelabs/getting-started/img/gerrit-change.png
new file mode 100644
index 0000000..2eed80b
--- /dev/null
+++ b/doc/codelabs/getting-started/img/gerrit-change.png
Binary files differ
diff --git a/doc/codelabs/getting-started/img/gerrit-dashboard.png b/doc/codelabs/getting-started/img/gerrit-dashboard.png
new file mode 100644
index 0000000..91b2111
--- /dev/null
+++ b/doc/codelabs/getting-started/img/gerrit-dashboard.png
Binary files differ
diff --git a/doc/codelabs/getting-started/img/gerrit-gear-click.png b/doc/codelabs/getting-started/img/gerrit-gear-click.png
new file mode 100644
index 0000000..821345f
--- /dev/null
+++ b/doc/codelabs/getting-started/img/gerrit-gear-click.png
Binary files differ
diff --git a/doc/codelabs/getting-started/img/gerrit-ssh-key-paste.png b/doc/codelabs/getting-started/img/gerrit-ssh-key-paste.png
new file mode 100644
index 0000000..f51d290
--- /dev/null
+++ b/doc/codelabs/getting-started/img/gerrit-ssh-key-paste.png
Binary files differ
diff --git a/doc/codelabs/getting-started/img/gerrit-ssh-keys-click.png b/doc/codelabs/getting-started/img/gerrit-ssh-keys-click.png
new file mode 100644
index 0000000..47c9a56
--- /dev/null
+++ b/doc/codelabs/getting-started/img/gerrit-ssh-keys-click.png
Binary files differ
diff --git a/doc/codelabs/getting-started/your-first-change.md b/doc/codelabs/getting-started/your-first-change.md
new file mode 100644
index 0000000..ef94ff8
--- /dev/null
+++ b/doc/codelabs/getting-started/your-first-change.md
@@ -0,0 +1,192 @@
+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
+-------------
+
+hscloud is a git repository. If you're new to git, this might be slightly confusing to you, but you should still be able to follow along. In case you need brush up on that, links to relevant resources await you at the bottom of this document.
+
+As for software, you'll need to have git installed on your workstation.
+
+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:
+
+![](img/gerrit-dashboard.png)
+
+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:**
+
+![](img/gerrit-gear-click.png)
+
+**2. Click 'SSH keys' in the sidebar:** 
+
+![](img/gerrit-ssh-keys-click.png)
+
+**3. Paste your SSH public key in the textbox and click 'Add new SSH key':**
+
+![](img/gerrit-ssh-key-paste.png)
+
+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.
+
+Cloning hscloud and looking around
+----------------------------------
+
+Now, clone hscloud and take a look around:
+
+    $ 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
+    $ ls
+    app  bgpwtf  BUILD  bzl  cluster  COPYING  dc  devtools  doc  env.fish  env.sh  gcp  go  hackdoc.toml  hswaw  kube  OWNERS  personal  README.md  third_party  tools  WORKSPACE
+    $
+
+If you've already cloned hscloud before (eg. over https), either clone it again or update your origin to point at `user@gerrit.hackerspace.pl:hscloud`.
+
+You can also use Gitiles (a part of Gerrit) to view hscloud in your web browser: https://gerrit.hackerspace.pl/plugins/gitiles/hscloud/+/refs/heads/master
+
+Any time you see a `//path/written/like/this`, `//` refers to the root of the hscloud checkout. For example, `//devtools/gerrit` contains all code related to our Gerrit instance. If you want to learn more about hscloud's directory structure, start at [//README.md](/README.md).
+
+Configuring git for Gerrit
+--------------------------
+
+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:
+
+![](img/gerrit-change.png)
+
+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.
+
+![](img/gerrit-change-annotated.png)
+
+- **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](https://gerrit.hackerspace.pl/plugins/gitiles/hscloud/+/master).
+
+Further steps
+-------------
+
+ - If you need a **Git refresher** - we highly recommend the [Git Visual Reference](https://marklodato.github.io/visual-git-guide/index-en.html)
+ - While this codelab showed you how to create and submit CRs, you didn't see anything about code review. Watch this space for a codelab about that.
+ - You should now be able to commit and change code. Watch this space for a link to a codelab on using Bazel or writing a simple microservice in Go.
diff --git a/doc/codelabs/index.md b/doc/codelabs/index.md
index 9af259f..790447f 100644
--- a/doc/codelabs/index.md
+++ b/doc/codelabs/index.md
@@ -1,6 +1,11 @@
 Codelabs
 ========
 
-Short and sweet technical tutorials.
+Codelabs are short, sweet and hands-on technical tutorials that teach you concepts related to hscloud and our infrastructure in general.
 
-Coming soon. Continue pinging q3k.
+Yes, there aren't many of these yet. Wanna change that? :)
+
+Getting started
+---------------
+
+- [**Your First Change**](getting-started/your-first-change.md) - how to use Gerrit and git to send your first change to hscloud, and an intro to personal directories. Using Gerrit can be somewhat confusing even (or especially) if you're used to Gitflow or GitHub.