From 6def2c7542ec3fd0efd74e057dc13b32b5bd31fd Mon Sep 17 00:00:00 2001 From: Laurence Smith Date: Thu, 14 Jan 2021 19:58:18 +0000 Subject: [PATCH 01/43] Inital www commit --- .gitignore | 14 +++++++++++++ about.html | 34 ++++++++++++++++++++++++++++++++ assets/css/main.css | 15 ++++++++++++++ contact.html | 34 ++++++++++++++++++++++++++++++++ index.html | 39 +++++++++++++++++++++++++++++++++++++ posts/even-newer.html | 39 +++++++++++++++++++++++++++++++++++++ posts/slightly-newer.html | 41 +++++++++++++++++++++++++++++++++++++++ posts/test.html | 39 +++++++++++++++++++++++++++++++++++++ 8 files changed, 255 insertions(+) create mode 100644 .gitignore create mode 100644 about.html create mode 100644 assets/css/main.css create mode 100644 contact.html create mode 100644 index.html create mode 100644 posts/even-newer.html create mode 100644 posts/slightly-newer.html create mode 100644 posts/test.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c407f65 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +/target +/classes +/checkouts +profiles.clj +pom.xml +pom.xml.asc +*.jar +*.class +/.lein-* +/.nrepl-port +/.prepl-port +.hgignore +.hg/ +dist/ \ No newline at end of file diff --git a/about.html b/about.html new file mode 100644 index 0000000..1cf7f21 --- /dev/null +++ b/about.html @@ -0,0 +1,34 @@ + + + + + Sourceless - about + + + + + + + + + + + + +

sourceless

+ + +index + + about + + contact + + +

This is an about page

+ + + +
+ + diff --git a/assets/css/main.css b/assets/css/main.css new file mode 100644 index 0000000..8275287 --- /dev/null +++ b/assets/css/main.css @@ -0,0 +1,15 @@ +body { + height: 100vh; + background: #1F2933; + color: #CBD2D9; +} + +a { + color: #F5F7FA; +} + +code { + display: block; + width: 40em; + margin: 10em auto; +} diff --git a/contact.html b/contact.html new file mode 100644 index 0000000..0dd8f69 --- /dev/null +++ b/contact.html @@ -0,0 +1,34 @@ + + + + + Sourceless - contact + + + + + + + + + + + + +

sourceless

+ + +index + + about + + contact + + +

Here you can contact me

+ + + +
+ + diff --git a/index.html b/index.html new file mode 100644 index 0000000..932126d --- /dev/null +++ b/index.html @@ -0,0 +1,39 @@ + + + + + Sourceless + + + + + + + + + + + + +

sourceless

+ + +index + + about + + contact + + + +
+ + diff --git a/posts/even-newer.html b/posts/even-newer.html new file mode 100644 index 0000000..2e0f545 --- /dev/null +++ b/posts/even-newer.html @@ -0,0 +1,39 @@ + + + + + Sourceless - Test post 3 - the newest one + + + + + + + + + + + + +

sourceless

+ + +index + + about + + contact + + + + posted 2020-01-14 +

This is a test post that should be rendered nicely in markdown.

Actually, this one is first in the index list.

+ + +← Test post 2 - the newer one + + + +
+ + diff --git a/posts/slightly-newer.html b/posts/slightly-newer.html new file mode 100644 index 0000000..e05fa67 --- /dev/null +++ b/posts/slightly-newer.html @@ -0,0 +1,41 @@ + + + + + Sourceless - Test post 2 - the newer one + + + + + + + + + + + + +

sourceless

+ + +index + + about + + contact + + + + posted 2020-01-12 +

This is a test post that should be rendered nicely in markdown.

And it comes first in the index list!

+ + +← Test post + + +Test post 3 - the newest one → + + +
+ + diff --git a/posts/test.html b/posts/test.html new file mode 100644 index 0000000..1537d62 --- /dev/null +++ b/posts/test.html @@ -0,0 +1,39 @@ + + + + + Sourceless - Test post + + + + + + + + + + + + +

sourceless

+ + +index + + about + + contact + + + + posted 2020-01-11 +

This is a test post that should be rendered nicely in markdown.

+ + + +Test post 2 - the newer one → + + +
+ + From 447bcae51cb206498bec36d42815e73b8b43fbda Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Thu, 14 Jan 2021 22:41:54 +0000 Subject: [PATCH 02/43] www-build-5 --- .github/workflows/build.yml | 52 +++++++++++++++++++++++++++++++++++++ CNAME | 1 + about.html | 8 +++--- contact.html | 8 +++--- index.html | 14 +++++----- posts/even-newer.html | 10 +++---- posts/slightly-newer.html | 12 ++++----- posts/test.html | 10 +++---- 8 files changed, 84 insertions(+), 31 deletions(-) create mode 100644 .github/workflows/build.yml create mode 100644 CNAME diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..1c6552d --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,52 @@ +name: build + +on: + push: + branches: [ master ] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + with: + persist-credentials: false + fetch-depth: 0 + - name: git fetch + run: git fetch + - name: checkout www + run: git checkout -t origin/www + - name: ensure pull + run: git pull + - name: return to master + run: git checkout master + - name: Install dependencies + run: lein deps + - name: Build site + run: ./build.sh + - name: git reset www + run: git reset www + - name: delete non-dist folders + run: ls | grep -v dist | xargs rm -r + - name: pull contents out of dist + run: cp -r dist/* . + - name: delete dist folder + run: rm -r dist + - name: git add . + run: git add . + - name: checkout www + run: git checkout www + - name: git status + run: git status + - name: Set git user + run: | + git config --local user.email "bot@sourceless.org" + git config --local user.name "Site Builder Bot" + - name: commit + run: git commit -m "www-build-$GITHUB_RUN_NUMBER" + - name: Push changes + uses: ad-m/github-push-action@master + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + branch: www diff --git a/CNAME b/CNAME new file mode 100644 index 0000000..cb584ed --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +sourceless.org \ No newline at end of file diff --git a/about.html b/about.html index 1cf7f21..029b31d 100644 --- a/about.html +++ b/about.html @@ -10,7 +10,7 @@ - + @@ -18,11 +18,11 @@

sourceless

-index +index - about + about - contact + contact

This is an about page

diff --git a/contact.html b/contact.html index 0dd8f69..7868402 100644 --- a/contact.html +++ b/contact.html @@ -10,7 +10,7 @@ - + @@ -18,11 +18,11 @@

sourceless

-index +index - about + about - contact + contact

Here you can contact me

diff --git a/index.html b/index.html index 932126d..09c8b20 100644 --- a/index.html +++ b/index.html @@ -10,7 +10,7 @@ - + @@ -18,20 +18,20 @@

sourceless

-index +index - about + about - contact + contact diff --git a/posts/even-newer.html b/posts/even-newer.html index 2e0f545..6f5ef4c 100644 --- a/posts/even-newer.html +++ b/posts/even-newer.html @@ -10,7 +10,7 @@ - + @@ -18,11 +18,11 @@

sourceless

-index +index - about + about - contact + contact @@ -30,7 +30,7 @@

sourceless

This is a test post that should be rendered nicely in markdown.

Actually, this one is first in the index list.

-← Test post 2 - the newer one +← Test post 2 - the newer one diff --git a/posts/slightly-newer.html b/posts/slightly-newer.html index e05fa67..70d103a 100644 --- a/posts/slightly-newer.html +++ b/posts/slightly-newer.html @@ -10,7 +10,7 @@ - + @@ -18,11 +18,11 @@

sourceless

-index +index - about + about - contact + contact @@ -30,10 +30,10 @@

sourceless

This is a test post that should be rendered nicely in markdown.

And it comes first in the index list!

-← Test post +← Test post -Test post 3 - the newest one → +Test post 3 - the newest one → diff --git a/posts/test.html b/posts/test.html index 1537d62..ff6eec5 100644 --- a/posts/test.html +++ b/posts/test.html @@ -10,7 +10,7 @@ - + @@ -18,11 +18,11 @@

sourceless

-index +index - about + about - contact + contact @@ -31,7 +31,7 @@

sourceless

-Test post 2 - the newer one → +Test post 2 - the newer one → From f8afce90e7b5dd4a84ce029d9b9717cc99219628 Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Thu, 14 Jan 2021 22:44:27 +0000 Subject: [PATCH 03/43] www-build-6 --- .github/workflows/build.yml | 52 ------------------------------------- about.html | 8 +++--- contact.html | 8 +++--- index.html | 14 +++++----- posts/even-newer.html | 10 +++---- posts/slightly-newer.html | 12 ++++----- posts/test.html | 10 +++---- 7 files changed, 31 insertions(+), 83 deletions(-) delete mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index 1c6552d..0000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,52 +0,0 @@ -name: build - -on: - push: - branches: [ master ] - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - with: - persist-credentials: false - fetch-depth: 0 - - name: git fetch - run: git fetch - - name: checkout www - run: git checkout -t origin/www - - name: ensure pull - run: git pull - - name: return to master - run: git checkout master - - name: Install dependencies - run: lein deps - - name: Build site - run: ./build.sh - - name: git reset www - run: git reset www - - name: delete non-dist folders - run: ls | grep -v dist | xargs rm -r - - name: pull contents out of dist - run: cp -r dist/* . - - name: delete dist folder - run: rm -r dist - - name: git add . - run: git add . - - name: checkout www - run: git checkout www - - name: git status - run: git status - - name: Set git user - run: | - git config --local user.email "bot@sourceless.org" - git config --local user.name "Site Builder Bot" - - name: commit - run: git commit -m "www-build-$GITHUB_RUN_NUMBER" - - name: Push changes - uses: ad-m/github-push-action@master - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - branch: www diff --git a/about.html b/about.html index 029b31d..12fdbc6 100644 --- a/about.html +++ b/about.html @@ -10,7 +10,7 @@ - + @@ -18,11 +18,11 @@

sourceless

-index +index - about + about - contact + contact

This is an about page

diff --git a/contact.html b/contact.html index 7868402..ed791f3 100644 --- a/contact.html +++ b/contact.html @@ -10,7 +10,7 @@ - + @@ -18,11 +18,11 @@

sourceless

-index +index - about + about - contact + contact

Here you can contact me

diff --git a/index.html b/index.html index 09c8b20..39722e2 100644 --- a/index.html +++ b/index.html @@ -10,7 +10,7 @@ - + @@ -18,20 +18,20 @@

sourceless

-index +index - about + about - contact + contact diff --git a/posts/even-newer.html b/posts/even-newer.html index 6f5ef4c..df7db00 100644 --- a/posts/even-newer.html +++ b/posts/even-newer.html @@ -10,7 +10,7 @@ - + @@ -18,11 +18,11 @@

sourceless

-index +index - about + about - contact + contact @@ -30,7 +30,7 @@

sourceless

This is a test post that should be rendered nicely in markdown.

Actually, this one is first in the index list.

-← Test post 2 - the newer one +← Test post 2 - the newer one diff --git a/posts/slightly-newer.html b/posts/slightly-newer.html index 70d103a..6600657 100644 --- a/posts/slightly-newer.html +++ b/posts/slightly-newer.html @@ -10,7 +10,7 @@ - + @@ -18,11 +18,11 @@

sourceless

-index +index - about + about - contact + contact @@ -30,10 +30,10 @@

sourceless

This is a test post that should be rendered nicely in markdown.

And it comes first in the index list!

-← Test post +← Test post -Test post 3 - the newest one → +Test post 3 - the newest one → diff --git a/posts/test.html b/posts/test.html index ff6eec5..17906cf 100644 --- a/posts/test.html +++ b/posts/test.html @@ -10,7 +10,7 @@ - + @@ -18,11 +18,11 @@

sourceless

-index +index - about + about - contact + contact @@ -31,7 +31,7 @@

sourceless

-Test post 2 - the newer one → +Test post 2 - the newer one → From 1121eeea12f5719120fdc870d983e0e2a3ca4895 Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Sun, 17 Jan 2021 18:08:54 +0000 Subject: [PATCH 04/43] www-build-7 --- about.html | 6 ++--- assets/css/main.css | 18 +++++++++++++- contact.html | 6 ++--- index.html | 19 +++++++-------- posts/even-newer.html | 39 ------------------------------ posts/how-i-built-this-site.html | 38 +++++++++++++++++++++++++++++ posts/slightly-newer.html | 41 -------------------------------- posts/test.html | 39 ------------------------------ 8 files changed, 69 insertions(+), 137 deletions(-) delete mode 100644 posts/even-newer.html create mode 100644 posts/how-i-built-this-site.html delete mode 100644 posts/slightly-newer.html delete mode 100644 posts/test.html diff --git a/about.html b/about.html index 12fdbc6..3343014 100644 --- a/about.html +++ b/about.html @@ -14,18 +14,18 @@ - +

sourceless

-index +index about contact -

This is an about page

+

Hi, I'm Laurence Pakenham-Smith.

I'm a software engineer in the Healthcare industry, with experience in the NHS (UK) and the US Health insurance industry.

My topics of particular interest are:

  • Building high performing teams
  • Building software that helps teams perform
  • Making delightful interfaces
  • Provably correct computing

I've dabbled in a lot of things, including:

  • Formal methods
  • Computer graphics

Most of my professional experience is in Python, Ruby, JavaScript, and similar languages, but in my spare time I build things in Clojure and Rust.

diff --git a/assets/css/main.css b/assets/css/main.css index 8275287..e1cda06 100644 --- a/assets/css/main.css +++ b/assets/css/main.css @@ -1,6 +1,6 @@ body { height: 100vh; - background: #1F2933; + background: #323F4B; color: #CBD2D9; } @@ -9,7 +9,23 @@ a { } code { + background: #1F2933; + color: #E4E7DB; +} + +#content { + background: #323F4B; display: block; width: 40em; margin: 10em auto; } + +h2, h3, h4, h5, h6 { + margin-top: 3em; +} + +@media only screen and (max-width: 768px) { + #content { + width: 100%; + } +} diff --git a/contact.html b/contact.html index ed791f3..1d6b9c7 100644 --- a/contact.html +++ b/contact.html @@ -14,18 +14,18 @@ - +

sourceless

-index +index about contact -

Here you can contact me

+

E: laurence@[this website]
T: @sourceless
GH: sourceless
HN: sourceless

diff --git a/index.html b/index.html index 39722e2..3872d2d 100644 --- a/index.html +++ b/index.html @@ -14,26 +14,23 @@ - +

sourceless

-index +index about contact - +
+
+
+ + 2020-01-17 Getting github pages to work with my custom site generator
+
diff --git a/posts/even-newer.html b/posts/even-newer.html deleted file mode 100644 index df7db00..0000000 --- a/posts/even-newer.html +++ /dev/null @@ -1,39 +0,0 @@ - - - - - Sourceless - Test post 3 - the newest one - - - - - - - - - - - - -

sourceless

- - -index - - about - - contact - - - - posted 2020-01-14 -

This is a test post that should be rendered nicely in markdown.

Actually, this one is first in the index list.

- - -← Test post 2 - the newer one - - - -
- - diff --git a/posts/how-i-built-this-site.html b/posts/how-i-built-this-site.html new file mode 100644 index 0000000..a9bbd70 --- /dev/null +++ b/posts/how-i-built-this-site.html @@ -0,0 +1,38 @@ + + + + + Sourceless - Getting github pages to work with my custom site generator + + + + + + + + + + + + +

sourceless

+ + +index + + about + + contact + + +

Getting github pages to work with my custom site generator

So, I built a crappy site generator. It's pretty bad, which is the result of some very targeted design decisions:

  • I didn't want to spend a huge amount of effort building it. This is for fun, not work. You're not going to find any unit tests or any significant refactoring effort.
  • I want to generate a fast site that I can host for free (sans domain costs).
  • I want it to be easy to author new posts in my tool of choice (emacs).
  • Deploying the website should be a git push.

Feel free to look at the code (linked above) if you want, but it's really the least interesting part of this post. At a quick summary, here's what it can do:

  • Fixed index page that lists posts and pages
  • Pages and posts generated from markdown
  • Page/post metadata stored as EDN (Jekyll-style, but EDN isntead of YAML)

Getting Github actions to deploy from my own generator

Github Pages comes with Jekyll site generation built in. This is nice, unless you want to use your own generator.

Now of course, you could generate it locally and push it, but really, where's the fun in that? So, let's get github to do all the work.

For reference, here is the action that builds the site. At a high level, it:

  1. Generates the site from the files in the repo
  2. Resets to the www branch, which contains the built output served by GitHub pages (you can change the branch it watches in settings)
  3. Checks out and adds files
  4. Makes a new commit postfixed by the actions run number
  5. Pushes to the www branch.

(Note to readers: I haven't gone through this with a fine-tooth comb. It's quite possible that the reset is entirely unnecessary.)

The fantastic GitHub Push Action by ad-m was instrumental in getting this to work so easily.

The end result

So what am I left with?

  • A small, lean, html-only site
  • On free hosting
  • Using any site generator I want
  • Pushing a new version to master auto-generates a new site

Seems like it fits the bill! I'm happy with the output, and maybe I will spend some time improving the code to something I would be proud to show to people, but the fact remains: working code that solves the problem is better than neat code that doesn't work yet.

👋

+
+ Posted 2020-01-17 +
+
+ + + +
+ + diff --git a/posts/slightly-newer.html b/posts/slightly-newer.html deleted file mode 100644 index 6600657..0000000 --- a/posts/slightly-newer.html +++ /dev/null @@ -1,41 +0,0 @@ - - - - - Sourceless - Test post 2 - the newer one - - - - - - - - - - - - -

sourceless

- - -index - - about - - contact - - - - posted 2020-01-12 -

This is a test post that should be rendered nicely in markdown.

And it comes first in the index list!

- - -← Test post - - -Test post 3 - the newest one → - - -
- - diff --git a/posts/test.html b/posts/test.html deleted file mode 100644 index 17906cf..0000000 --- a/posts/test.html +++ /dev/null @@ -1,39 +0,0 @@ - - - - - Sourceless - Test post - - - - - - - - - - - - -

sourceless

- - -index - - about - - contact - - - - posted 2020-01-11 -

This is a test post that should be rendered nicely in markdown.

- - - -Test post 2 - the newer one → - - -
- - From 6a8a7d9ecd533df9037efe7b5710e39db4ebb6a2 Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Sun, 17 Jan 2021 18:17:24 +0000 Subject: [PATCH 05/43] www-build-9 --- posts/how-i-built-this-site.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/posts/how-i-built-this-site.html b/posts/how-i-built-this-site.html index a9bbd70..a6bed2e 100644 --- a/posts/how-i-built-this-site.html +++ b/posts/how-i-built-this-site.html @@ -25,7 +25,7 @@

sourceless

contact -

Getting github pages to work with my custom site generator

So, I built a crappy site generator. It's pretty bad, which is the result of some very targeted design decisions:

  • I didn't want to spend a huge amount of effort building it. This is for fun, not work. You're not going to find any unit tests or any significant refactoring effort.
  • I want to generate a fast site that I can host for free (sans domain costs).
  • I want it to be easy to author new posts in my tool of choice (emacs).
  • Deploying the website should be a git push.

Feel free to look at the code (linked above) if you want, but it's really the least interesting part of this post. At a quick summary, here's what it can do:

  • Fixed index page that lists posts and pages
  • Pages and posts generated from markdown
  • Page/post metadata stored as EDN (Jekyll-style, but EDN isntead of YAML)

Getting Github actions to deploy from my own generator

Github Pages comes with Jekyll site generation built in. This is nice, unless you want to use your own generator.

Now of course, you could generate it locally and push it, but really, where's the fun in that? So, let's get github to do all the work.

For reference, here is the action that builds the site. At a high level, it:

  1. Generates the site from the files in the repo
  2. Resets to the www branch, which contains the built output served by GitHub pages (you can change the branch it watches in settings)
  3. Checks out and adds files
  4. Makes a new commit postfixed by the actions run number
  5. Pushes to the www branch.

(Note to readers: I haven't gone through this with a fine-tooth comb. It's quite possible that the reset is entirely unnecessary.)

The fantastic GitHub Push Action by ad-m was instrumental in getting this to work so easily.

The end result

So what am I left with?

  • A small, lean, html-only site
  • On free hosting
  • Using any site generator I want
  • Pushing a new version to master auto-generates a new site

Seems like it fits the bill! I'm happy with the output, and maybe I will spend some time improving the code to something I would be proud to show to people, but the fact remains: working code that solves the problem is better than neat code that doesn't work yet.

👋

+

Getting github pages to work with my custom site generator

So, I built a crappy site generator. It's pretty bad, which is the result of some very targeted design decisions:

  • I didn't want to spend a huge amount of effort building it. This is for fun, not work. You're not going to find any unit tests or any significant refactoring effort.
  • I want to generate a fast site that I can host for free (sans domain costs).
  • I want it to be easy to author new posts in my tool of choice (emacs).
  • Deploying the website should be a git push.

Feel free to look at the code (linked above) if you want, but it's really the least interesting part of this post. At a quick summary, here's what it can do:

  • Fixed index page that lists posts and pages
  • Pages and posts generated from markdown
  • Page/post metadata stored as EDN (Jekyll-style, but EDN isntead of YAML)

Getting Github actions to deploy from my own generator

I hasten to note this is by no means revolutionary or new. But here's how I did it.

Github Pages comes with Jekyll site generation built in. This is nice, unless you want to use your own generator.

Now of course, you could generate it locally and push it, but really, where's the fun in that? So, let's get github to do all the work.

For reference, here is the action that builds the site. At a high level, it:

  1. Generates the site from the files in the repo
  2. Resets to the www branch, which contains the built output served by GitHub pages (you can change the branch it watches in settings)
  3. Checks out and adds files
  4. Makes a new commit postfixed by the actions run number
  5. Pushes to the www branch.

(Note to readers: I haven't gone through this with a fine-tooth comb. It's quite possible that the reset is entirely unnecessary.)

The fantastic GitHub Push Action by ad-m was instrumental in getting this to work so easily.

The end result

So what am I left with?

  • A small, lean, html-only site
  • On free hosting
  • Using any site generator I want
  • Pushing a new version to master auto-generates a new site

Seems like it fits the bill! I'm happy with the output, and maybe I will spend some time improving the code to something I would be proud to show to people, but the fact remains: working code that solves the problem is better than neat code that doesn't work yet.

👋

Follow the discussion on Hacker News


Posted 2020-01-17
From 55ecfc3364dfd00931a38a5eabf290ebab26faf1 Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Fri, 19 Mar 2021 12:24:46 +0000 Subject: [PATCH 06/43] www-build-10 --- index.html | 4 ++- posts/how-i-built-this-site.html | 4 ++- posts/the-documentation-triangle.html | 40 +++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 posts/the-documentation-triangle.html diff --git a/index.html b/index.html index 3872d2d..70f2af8 100644 --- a/index.html +++ b/index.html @@ -29,7 +29,9 @@

sourceless



- 2020-01-17 Getting github pages to work with my custom site generator
+ 2021-03-19 The Documentation Triangle (or, why code isn't self-documenting)
+ + 2021-01-17 Getting github pages to work with my custom site generator
diff --git a/posts/how-i-built-this-site.html b/posts/how-i-built-this-site.html index a6bed2e..d1a739b 100644 --- a/posts/how-i-built-this-site.html +++ b/posts/how-i-built-this-site.html @@ -27,11 +27,13 @@

sourceless

Getting github pages to work with my custom site generator

So, I built a crappy site generator. It's pretty bad, which is the result of some very targeted design decisions:

  • I didn't want to spend a huge amount of effort building it. This is for fun, not work. You're not going to find any unit tests or any significant refactoring effort.
  • I want to generate a fast site that I can host for free (sans domain costs).
  • I want it to be easy to author new posts in my tool of choice (emacs).
  • Deploying the website should be a git push.

Feel free to look at the code (linked above) if you want, but it's really the least interesting part of this post. At a quick summary, here's what it can do:

  • Fixed index page that lists posts and pages
  • Pages and posts generated from markdown
  • Page/post metadata stored as EDN (Jekyll-style, but EDN isntead of YAML)

Getting Github actions to deploy from my own generator

I hasten to note this is by no means revolutionary or new. But here's how I did it.

Github Pages comes with Jekyll site generation built in. This is nice, unless you want to use your own generator.

Now of course, you could generate it locally and push it, but really, where's the fun in that? So, let's get github to do all the work.

For reference, here is the action that builds the site. At a high level, it:

  1. Generates the site from the files in the repo
  2. Resets to the www branch, which contains the built output served by GitHub pages (you can change the branch it watches in settings)
  3. Checks out and adds files
  4. Makes a new commit postfixed by the actions run number
  5. Pushes to the www branch.

(Note to readers: I haven't gone through this with a fine-tooth comb. It's quite possible that the reset is entirely unnecessary.)

The fantastic GitHub Push Action by ad-m was instrumental in getting this to work so easily.

The end result

So what am I left with?

  • A small, lean, html-only site
  • On free hosting
  • Using any site generator I want
  • Pushing a new version to master auto-generates a new site

Seems like it fits the bill! I'm happy with the output, and maybe I will spend some time improving the code to something I would be proud to show to people, but the fact remains: working code that solves the problem is better than neat code that doesn't work yet.

👋

Follow the discussion on Hacker News


- Posted 2020-01-17 + Posted 2021-01-17

+The Documentation Triangle (or, why code isn't self-documenting) → +
diff --git a/posts/the-documentation-triangle.html b/posts/the-documentation-triangle.html new file mode 100644 index 0000000..dcbf123 --- /dev/null +++ b/posts/the-documentation-triangle.html @@ -0,0 +1,40 @@ + + + + + Sourceless - The Documentation Triangle (or, why code isn't self-documenting) + + + + + + + + + + + + +

sourceless

+ + +index + + about + + contact + + +

The Documentation Triangle

At some point in your coding career, you've probably heard something like:

"My code is self documenting"

or

"Code IS documentation"

These statements can be hard to argue against, especially if they come from someone who is more experienced than you. A lot of the trouble is that they are not wrong – well, they're not completely wrong.

The goal of documentation

Why do we document things? If the code was enough, we would never need tutorials, API documentation, or anything of the sort, right? What user need is being fulfilled by having more than just code to communicate what our programs and services do?

It sounds obvious, but documentation exists so that code can be easily used.

This is incredibly easy to forget when the program is all in your head and you have an intuitive understanding – but to fresh eyes, is your code really all that easy to approach?

What, Why, How: The Documentation Triangle

Here's a rule of thumb I've seen repeated in a few places regarding how to ensure that your documentation is up to scratch.

Why a triangle? Well, triangles are a strong shape, and any missing side renders it entirely structurally unsound - just as missing out vital documentation can make your code as good as unusable to others.

What (code)

This is generally what people are going for when they say "my code is self documenting". Clear, concise, and well-written code is a form of documentation in itself.

It is the most honest account of what actually happens when you run the code, what the most important data structures are, and what interfaces you'll be able to interact with. Some languages are better than this for others, and supplementary information such as type signatures can be incredibly helpful in understanding some code that's new to you.

However, there are some things this alone leaves out...

Why (comments)

Every program has a history - whether in the very mundane sense of having a history in version control, or a long and detailed history of changes it has undergone to meet various challenges.

It's this latter case that is the most crucial to note why certain pieces of code exist in their current state.

Comments are most often the vehicle for these sort of margin notes. Noting that this thing was done in this way for optimization reasons, or another thing was a dirty hack leaves signposts for the next maintainer to know what compromises have been made in building this software.

Maintaining (legacy) code without any comments is less like being a mechanic, and much more like being an archaeologist.

How (context)

The last side of the triangle is often the most neglected. It might live in docstrings, or in confluence, be automatically generated, or be in a carefully crafted README, but it's all information on the context in which the code will be executed.

No program exists in a vacuum. There is always some environment, some organisation, some process that it lives in or serves, and taken out of said context, it is entirely useless.

Failing to recognise this is the number one leading cause of new users and junior devs being unable to do 'this simple task' (don't quote me on this, I have no data).

There's a great litmus test for this. Take the new process or pipeline or whatever that you've implemented (be it setting up a repo, running a job, etc.) and find yourself someone that's technically competent but unfamiliar with what you're working on. Plonk them in front of it and shut the fuck up. Watch them struggle through it and only help them if they are genuinely, truly stumped. This will very quickly tell you where you need to spend effort on documentation.

Heck - make it part of your code review.

+
+ Posted 2021-03-19 +
+
+ +← Getting github pages to work with my custom site generator + + + +
+ + From 28ae85bf59be3b5fd06df9462b0c32a05b05c019 Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Fri, 19 Mar 2021 12:29:59 +0000 Subject: [PATCH 07/43] www-build-11 --- index.html | 2 +- posts/how-i-built-this-site.html | 2 +- posts/the-documentation-triangle.html | 12 ++++++++++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/index.html b/index.html index 70f2af8..ceb30e6 100644 --- a/index.html +++ b/index.html @@ -29,7 +29,7 @@

sourceless



- 2021-03-19 The Documentation Triangle (or, why code isn't self-documenting)
+ 2021-03-19 The Documentation Triangle
2021-01-17 Getting github pages to work with my custom site generator
diff --git a/posts/how-i-built-this-site.html b/posts/how-i-built-this-site.html index d1a739b..b6bcb3e 100644 --- a/posts/how-i-built-this-site.html +++ b/posts/how-i-built-this-site.html @@ -32,7 +32,7 @@

Getting github pages to work with my custom site generator

So, I buil
-The Documentation Triangle (or, why code isn't self-documenting) → +The Documentation Triangle →
diff --git a/posts/the-documentation-triangle.html b/posts/the-documentation-triangle.html index dcbf123..9561f54 100644 --- a/posts/the-documentation-triangle.html +++ b/posts/the-documentation-triangle.html @@ -2,7 +2,7 @@ - Sourceless - The Documentation Triangle (or, why code isn't self-documenting) + Sourceless - The Documentation Triangle @@ -25,7 +25,15 @@

sourceless

contact -

The Documentation Triangle

At some point in your coding career, you've probably heard something like:

"My code is self documenting"

or

"Code IS documentation"

These statements can be hard to argue against, especially if they come from someone who is more experienced than you. A lot of the trouble is that they are not wrong – well, they're not completely wrong.

The goal of documentation

Why do we document things? If the code was enough, we would never need tutorials, API documentation, or anything of the sort, right? What user need is being fulfilled by having more than just code to communicate what our programs and services do?

It sounds obvious, but documentation exists so that code can be easily used.

This is incredibly easy to forget when the program is all in your head and you have an intuitive understanding – but to fresh eyes, is your code really all that easy to approach?

What, Why, How: The Documentation Triangle

Here's a rule of thumb I've seen repeated in a few places regarding how to ensure that your documentation is up to scratch.

Why a triangle? Well, triangles are a strong shape, and any missing side renders it entirely structurally unsound - just as missing out vital documentation can make your code as good as unusable to others.

What (code)

This is generally what people are going for when they say "my code is self documenting". Clear, concise, and well-written code is a form of documentation in itself.

It is the most honest account of what actually happens when you run the code, what the most important data structures are, and what interfaces you'll be able to interact with. Some languages are better than this for others, and supplementary information such as type signatures can be incredibly helpful in understanding some code that's new to you.

However, there are some things this alone leaves out...

Why (comments)

Every program has a history - whether in the very mundane sense of having a history in version control, or a long and detailed history of changes it has undergone to meet various challenges.

It's this latter case that is the most crucial to note why certain pieces of code exist in their current state.

Comments are most often the vehicle for these sort of margin notes. Noting that this thing was done in this way for optimization reasons, or another thing was a dirty hack leaves signposts for the next maintainer to know what compromises have been made in building this software.

Maintaining (legacy) code without any comments is less like being a mechanic, and much more like being an archaeologist.

How (context)

The last side of the triangle is often the most neglected. It might live in docstrings, or in confluence, be automatically generated, or be in a carefully crafted README, but it's all information on the context in which the code will be executed.

No program exists in a vacuum. There is always some environment, some organisation, some process that it lives in or serves, and taken out of said context, it is entirely useless.

Failing to recognise this is the number one leading cause of new users and junior devs being unable to do 'this simple task' (don't quote me on this, I have no data).

There's a great litmus test for this. Take the new process or pipeline or whatever that you've implemented (be it setting up a repo, running a job, etc.) and find yourself someone that's technically competent but unfamiliar with what you're working on. Plonk them in front of it and shut the fuck up. Watch them struggle through it and only help them if they are genuinely, truly stumped. This will very quickly tell you where you need to spend effort on documentation.

Heck - make it part of your code review.

+

The Documentation Triangle (or, why code isn't self documenting)

At some point in your coding career, you've probably heard something like:

"My code is self documenting"

or

"Code IS documentation"

These statements can be hard to argue against, especially if they come from someone who is more experienced than you. A lot of the trouble is that they are not wrong – well, they're not completely wrong.

The goal of documentation

Why do we document things? If the code was enough, we would never need tutorials, API documentation, or anything of the sort, right? What user need is being fulfilled by having more than just code to communicate what our programs and services do?

It sounds obvious, but documentation exists so that code can be easily used.

This is incredibly easy to forget when the program is all in your head and you have an intuitive understanding – but to fresh eyes, is your code really all that easy to approach?

What, Why, How: The Documentation Triangle

        What
+         /\
+        /  \
+       /    \
+      /      \
+     /        \
+    /__________\
+ Why            How 
+

Here's a rule of thumb I've seen repeated in a few places regarding how to ensure that your documentation is up to scratch.

Why a triangle? Well, triangles are a strong shape, and any missing side renders it entirely structurally unsound - just as missing out vital documentation can make your code as good as unusable to others.

What (code)

This is generally what people are going for when they say "my code is self documenting". Clear, concise, and well-written code is a form of documentation in itself.

It is the most honest account of what actually happens when you run the code, what the most important data structures are, and what interfaces you'll be able to interact with. Some languages are better than this for others, and supplementary information such as type signatures can be incredibly helpful in understanding some code that's new to you. However, there are some things this alone leaves out...

Why (comments)

Every program has a history - whether in the very mundane sense of having a history in version control, or a long and detailed history of changes it has undergone to meet various challenges.

It's this latter case that is the most crucial to note why certain pieces of code exist in their current state.

Comments are most often the vehicle for these sort of margin notes. Noting that this thing was done in this way for optimization reasons, or another thing was a dirty hack leaves signposts for the next maintainer to know what compromises have been made in building this software.

Maintaining (legacy) code without any comments is less like being a mechanic, and much more like being an archaeologist.

How (context)

The last side of the triangle is often the most neglected. It might live in docstrings, or in confluence, be automatically generated, or be in a carefully crafted README, but it's all information on the context in which the code will be executed.

No program exists in a vacuum. There is always some environment, some organisation, some process that it lives in or serves, and taken out of said context, it is entirely useless.

Failing to recognise this is the number one leading cause of new users and junior devs being unable to do 'this simple task' (don't quote me on this, I have no data).

There's a great litmus test for this. Take the new process or pipeline or whatever that you've implemented (be it setting up a repo, running a job, etc.) and find yourself someone that's technically competent but unfamiliar with what you're working on. Plonk them in front of it and shut the fuck up. Watch them struggle through it and only help them if they are genuinely, truly stumped. This will very quickly tell you where you need to spend effort on documentation.

Heck - make it part of your code review.


Posted 2021-03-19
From 7ffadcc354f2ff3e56388236384243c7a91d6d13 Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Fri, 19 Mar 2021 12:35:56 +0000 Subject: [PATCH 08/43] www-build-12 --- posts/the-documentation-triangle.html | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/posts/the-documentation-triangle.html b/posts/the-documentation-triangle.html index 9561f54..333172c 100644 --- a/posts/the-documentation-triangle.html +++ b/posts/the-documentation-triangle.html @@ -25,13 +25,13 @@

sourceless

contact -

The Documentation Triangle (or, why code isn't self documenting)

At some point in your coding career, you've probably heard something like:

"My code is self documenting"

or

"Code IS documentation"

These statements can be hard to argue against, especially if they come from someone who is more experienced than you. A lot of the trouble is that they are not wrong – well, they're not completely wrong.

The goal of documentation

Why do we document things? If the code was enough, we would never need tutorials, API documentation, or anything of the sort, right? What user need is being fulfilled by having more than just code to communicate what our programs and services do?

It sounds obvious, but documentation exists so that code can be easily used.

This is incredibly easy to forget when the program is all in your head and you have an intuitive understanding – but to fresh eyes, is your code really all that easy to approach?

What, Why, How: The Documentation Triangle

        What
-         /\
-        /  \
-       /    \
-      /      \
-     /        \
-    /__________\
+            

The Documentation Triangle (or, why code isn't self documenting)

At some point in your coding career, you've probably heard something like:

"My code is self documenting"

or

"Code IS documentation"

These statements can be hard to argue against, especially if they come from someone who is more experienced than you. A lot of the trouble is that they are not wrong – well, they're not completely wrong.

The goal of documentation

Why do we document things? If the code was enough, we would never need tutorials, API documentation, or anything of the sort, right? What user need is being fulfilled by having more than just code to communicate what our programs and services do?

It sounds obvious, but documentation exists so that code can be easily used.

This is incredibly easy to forget when the program is all in your head and you have an intuitive understanding – but to fresh eyes, is your code really all that easy to approach?

What, Why, How: The Documentation Triangle

        What        
+         /\         
+        /  \        
+       /    \       
+      /      \      
+     /        \     
+    /__________\    
  Why            How 
 

Here's a rule of thumb I've seen repeated in a few places regarding how to ensure that your documentation is up to scratch.

Why a triangle? Well, triangles are a strong shape, and any missing side renders it entirely structurally unsound - just as missing out vital documentation can make your code as good as unusable to others.

What (code)

This is generally what people are going for when they say "my code is self documenting". Clear, concise, and well-written code is a form of documentation in itself.

It is the most honest account of what actually happens when you run the code, what the most important data structures are, and what interfaces you'll be able to interact with. Some languages are better than this for others, and supplementary information such as type signatures can be incredibly helpful in understanding some code that's new to you. However, there are some things this alone leaves out...

Why (comments)

Every program has a history - whether in the very mundane sense of having a history in version control, or a long and detailed history of changes it has undergone to meet various challenges.

It's this latter case that is the most crucial to note why certain pieces of code exist in their current state.

Comments are most often the vehicle for these sort of margin notes. Noting that this thing was done in this way for optimization reasons, or another thing was a dirty hack leaves signposts for the next maintainer to know what compromises have been made in building this software.

Maintaining (legacy) code without any comments is less like being a mechanic, and much more like being an archaeologist.

How (context)

The last side of the triangle is often the most neglected. It might live in docstrings, or in confluence, be automatically generated, or be in a carefully crafted README, but it's all information on the context in which the code will be executed.

No program exists in a vacuum. There is always some environment, some organisation, some process that it lives in or serves, and taken out of said context, it is entirely useless.

Failing to recognise this is the number one leading cause of new users and junior devs being unable to do 'this simple task' (don't quote me on this, I have no data).

There's a great litmus test for this. Take the new process or pipeline or whatever that you've implemented (be it setting up a repo, running a job, etc.) and find yourself someone that's technically competent but unfamiliar with what you're working on. Plonk them in front of it and shut the fuck up. Watch them struggle through it and only help them if they are genuinely, truly stumped. This will very quickly tell you where you need to spend effort on documentation.

Heck - make it part of your code review.


From c7b1cd539fa93c746fe9bcca2e8e2e76feb4550c Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Sun, 19 Jun 2022 08:28:02 +0000 Subject: [PATCH 09/43] www-build-13 --- about.html | 2 +- contact.html | 2 +- index.html | 4 ++- posts/how-i-built-this-site.html | 2 +- posts/relearning-to-learn.html | 40 +++++++++++++++++++++++++++ posts/the-documentation-triangle.html | 4 ++- 6 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 posts/relearning-to-learn.html diff --git a/about.html b/about.html index 3343014..98f9e78 100644 --- a/about.html +++ b/about.html @@ -7,7 +7,7 @@ - + diff --git a/contact.html b/contact.html index 1d6b9c7..a87ff62 100644 --- a/contact.html +++ b/contact.html @@ -7,7 +7,7 @@ - + diff --git a/index.html b/index.html index ceb30e6..95086c2 100644 --- a/index.html +++ b/index.html @@ -7,7 +7,7 @@ - + @@ -29,6 +29,8 @@

sourceless



+ 2022-06-19 Relearning to Learn
+ 2021-03-19 The Documentation Triangle
2021-01-17 Getting github pages to work with my custom site generator
diff --git a/posts/how-i-built-this-site.html b/posts/how-i-built-this-site.html index b6bcb3e..07083a0 100644 --- a/posts/how-i-built-this-site.html +++ b/posts/how-i-built-this-site.html @@ -7,7 +7,7 @@ - + diff --git a/posts/relearning-to-learn.html b/posts/relearning-to-learn.html new file mode 100644 index 0000000..23c3b8c --- /dev/null +++ b/posts/relearning-to-learn.html @@ -0,0 +1,40 @@ + + + + + Sourceless - Relearning to Learn + + + + + + + + + + + + +

sourceless

+ + +index + + about + + contact + + +

Relearning to Learn

Many years ago, I took a test. It was the first step of our "Learning to Learn" class. After answering a series of multiple choice question, the form issued forth a proclomation:

YOU ARE A VISUAL LEARNER.

Over the course of my years at school I would learn this piece of information to be on the whole useless and entirely innefectual.

To cut a long story short, school and university didn't go particularly well for me.

Learning by accident

It's somewhat embarassing to admit, but I don't think I really learned how to teach myself things effectively until at least the age of 26.

When I look back, I realise much of my learning was a result of accidental chance; for example, I learned to program mostly by virtue of complete immersion and stumbling upon 'the right things'. I just followed my nose (and to be fair it worked out).

But now I'm an adult with a job and a family, and my time is far more precious. If I want to learn something new, I can't count on stumbling on the right approach anymore. Simply creating the conditions in which learning is possible is not sufficient, since I lack the time that approach requires.

Enter Mentor

How I learned to learn is, surprisingly, not at all related to my area of study or profession (software), but a hobby.

I met my whistle teacher Becky in 2020 on a video call. It was near the start of the pandemic, and I had some extra time on my hands. Becky is somewhat unlike other teachers I've had, it that she could mechanically break down and explain music to me in a way that allowed me not just to play it, but understand what I was playing.

The whistle is a small, cheap, end-blown flute – somewhat like a budget recorder. It has six tone holes that you cover with three fingers of either hand, and a mouthpiece that you blow in to. Out of this deceptively simple instrument, you can get two full octaves of range in two major keys and all the keys that come along with that. That is to say, it's small, but surprisingly versatile.

Irish traditional music, along with other traditional music of the British isles, is generally learned and played by ear, though sheet music is available. What sets this folk music apart from most classical and contemporary music is that the sheet music is essentially a suggestion. Using your skill, wits, and guile, you have to take a couple of parts of a repetitive tune and make it interesting.

This is where Becky comes in, with two really solid pieces of advice: one about how to practice, and one about how to learn.

Mindful Practice

The first of the things Becky taught me was how to practice; how to gain the mechanical skill required to execute what I knew, and to transform my knowledge into understanding.

"Know what you're going to practice before you pick up the whistle"

In retrospect, startlingly obvious. Noodling around randomly does very little but ingrain what you've already learned; **if you want to learn something new then you have to have a goal**. But, as with many things in life, having a plan (even if you have no idea what you're getting in to) is half the battle.

"Five minutes every day is better than an hour once per week"

This subtly implies something else; you should make your practice not just habit and routine, but low-friction and easy to access. You will do much better chipping away at small, easy problems, than trying to tackle a hard problem you are not ready for (and all hard problems are just n easy problems in a trenchcoat anyway).

"Do it slow until you can do it right"

This one has a very "slow is smooth, smooth is fast" kind of vibe, and it's right. Doing something slowly and accurately is hard. In a programming context, it's very easy to whack together some code that delivers a feature, but the end result is of limited use if it's buggy, doesn't actually deliver the desired feature, or is riddled with security or structural issues.

Learning to Learn

The second thing Becky taught me was how to learn. Specifically, how to learn an instrument, or a tune – the approach is broadly the same.

It's a model, and as my colleague Craig likes to say; all models are wrong, but some are useful. Hopefully this is one of the latter.

"First, learn the notes"

You have to be able to play a tune through in its entirety. Obvious, right? But there's a lot here – some tunes are difficult. Some tunes don't have a written form, and you'll have to learn them by ear. Worse, some tunes have very poorly transcribed sheet music that will lead you astray! Not all learning material is created equal.

Beyond that, you will also have to contend with your own (lack of) mechanical skill. You will likely get stumped by a strange combination of notes. Perhaps you're not accustomed to switching octaves so quickly, or you accidentally bang out the wrong note because of some pattern you've learned in a previous tune.

"Second, make it more interesting"

Boy, isn't that 'interesting' a really load-bearing word? In this context, it means adding ornamentation, variation, dynamics, and a plethora of other tools in the folk musician's toolbox.

Making the piece flow better - the folk musician's version of 'clean code' - is key to turning a roughly shaped tune into refined birdsong.

"Third, play the tune"

Taking all you have learned, play the tune. Not the notes. Not the parts. The whole thing. Feel the rhythm, lean in to the swing, and add to it with your performance.

This is not just the culmination of learning how to play the tune - it's the start of learning the meta-skill of picking up and playing the tunes you come across.

In code terms; release it. You must make mistakes to improve, and **more often than not you will be startled how others see something that is so mundane to you as so magical**.

Some observations

This is not a new topic, or a new field. People much smarter and more experienced than me have studied this for a long time, but I share it in hopes that for someone out there, the same realisations I had will click.

If you want to read more on this topic, take a look at:

And if I've somehow convinced you to listen to whistle music:

Thanks readers, and thanks Becky!

+
+ Posted 2022-06-19 +
+
+ +← The Documentation Triangle + + + +
+ + diff --git a/posts/the-documentation-triangle.html b/posts/the-documentation-triangle.html index 333172c..941a2f3 100644 --- a/posts/the-documentation-triangle.html +++ b/posts/the-documentation-triangle.html @@ -7,7 +7,7 @@ - + @@ -42,6 +42,8 @@

The Documentation Triangle (or, why code isn't self documenting)

At s ← Getting github pages to work with my custom site generator +Relearning to Learn → + From d98ee9562a0262e334c5cd3786f8a82f927cc839 Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Sun, 19 Jun 2022 08:32:18 +0000 Subject: [PATCH 10/43] www-build-14 --- posts/relearning-to-learn.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/posts/relearning-to-learn.html b/posts/relearning-to-learn.html index 23c3b8c..b4b8a47 100644 --- a/posts/relearning-to-learn.html +++ b/posts/relearning-to-learn.html @@ -25,7 +25,7 @@

sourceless

contact -

Relearning to Learn

Many years ago, I took a test. It was the first step of our "Learning to Learn" class. After answering a series of multiple choice question, the form issued forth a proclomation:

YOU ARE A VISUAL LEARNER.

Over the course of my years at school I would learn this piece of information to be on the whole useless and entirely innefectual.

To cut a long story short, school and university didn't go particularly well for me.

Learning by accident

It's somewhat embarassing to admit, but I don't think I really learned how to teach myself things effectively until at least the age of 26.

When I look back, I realise much of my learning was a result of accidental chance; for example, I learned to program mostly by virtue of complete immersion and stumbling upon 'the right things'. I just followed my nose (and to be fair it worked out).

But now I'm an adult with a job and a family, and my time is far more precious. If I want to learn something new, I can't count on stumbling on the right approach anymore. Simply creating the conditions in which learning is possible is not sufficient, since I lack the time that approach requires.

Enter Mentor

How I learned to learn is, surprisingly, not at all related to my area of study or profession (software), but a hobby.

I met my whistle teacher Becky in 2020 on a video call. It was near the start of the pandemic, and I had some extra time on my hands. Becky is somewhat unlike other teachers I've had, it that she could mechanically break down and explain music to me in a way that allowed me not just to play it, but understand what I was playing.

The whistle is a small, cheap, end-blown flute – somewhat like a budget recorder. It has six tone holes that you cover with three fingers of either hand, and a mouthpiece that you blow in to. Out of this deceptively simple instrument, you can get two full octaves of range in two major keys and all the keys that come along with that. That is to say, it's small, but surprisingly versatile.

Irish traditional music, along with other traditional music of the British isles, is generally learned and played by ear, though sheet music is available. What sets this folk music apart from most classical and contemporary music is that the sheet music is essentially a suggestion. Using your skill, wits, and guile, you have to take a couple of parts of a repetitive tune and make it interesting.

This is where Becky comes in, with two really solid pieces of advice: one about how to practice, and one about how to learn.

Mindful Practice

The first of the things Becky taught me was how to practice; how to gain the mechanical skill required to execute what I knew, and to transform my knowledge into understanding.

"Know what you're going to practice before you pick up the whistle"

In retrospect, startlingly obvious. Noodling around randomly does very little but ingrain what you've already learned; **if you want to learn something new then you have to have a goal**. But, as with many things in life, having a plan (even if you have no idea what you're getting in to) is half the battle.

"Five minutes every day is better than an hour once per week"

This subtly implies something else; you should make your practice not just habit and routine, but low-friction and easy to access. You will do much better chipping away at small, easy problems, than trying to tackle a hard problem you are not ready for (and all hard problems are just n easy problems in a trenchcoat anyway).

"Do it slow until you can do it right"

This one has a very "slow is smooth, smooth is fast" kind of vibe, and it's right. Doing something slowly and accurately is hard. In a programming context, it's very easy to whack together some code that delivers a feature, but the end result is of limited use if it's buggy, doesn't actually deliver the desired feature, or is riddled with security or structural issues.

Learning to Learn

The second thing Becky taught me was how to learn. Specifically, how to learn an instrument, or a tune – the approach is broadly the same.

It's a model, and as my colleague Craig likes to say; all models are wrong, but some are useful. Hopefully this is one of the latter.

"First, learn the notes"

You have to be able to play a tune through in its entirety. Obvious, right? But there's a lot here – some tunes are difficult. Some tunes don't have a written form, and you'll have to learn them by ear. Worse, some tunes have very poorly transcribed sheet music that will lead you astray! Not all learning material is created equal.

Beyond that, you will also have to contend with your own (lack of) mechanical skill. You will likely get stumped by a strange combination of notes. Perhaps you're not accustomed to switching octaves so quickly, or you accidentally bang out the wrong note because of some pattern you've learned in a previous tune.

"Second, make it more interesting"

Boy, isn't that 'interesting' a really load-bearing word? In this context, it means adding ornamentation, variation, dynamics, and a plethora of other tools in the folk musician's toolbox.

Making the piece flow better - the folk musician's version of 'clean code' - is key to turning a roughly shaped tune into refined birdsong.

"Third, play the tune"

Taking all you have learned, play the tune. Not the notes. Not the parts. The whole thing. Feel the rhythm, lean in to the swing, and add to it with your performance.

This is not just the culmination of learning how to play the tune - it's the start of learning the meta-skill of picking up and playing the tunes you come across.

In code terms; release it. You must make mistakes to improve, and **more often than not you will be startled how others see something that is so mundane to you as so magical**.

Some observations

This is not a new topic, or a new field. People much smarter and more experienced than me have studied this for a long time, but I share it in hopes that for someone out there, the same realisations I had will click.

If you want to read more on this topic, take a look at:

And if I've somehow convinced you to listen to whistle music:

Thanks readers, and thanks Becky!

+

Relearning to Learn

Many years ago, I took a test. It was the first step of our "Learning to Learn" class. After answering a series of multiple choice question, the form issued forth a proclomation:

YOU ARE A VISUAL LEARNER.

Over the course of my years at school I would learn this piece of information to be on the whole useless and entirely innefectual.

To cut a long story short, school and university didn't go particularly well for me.

Learning by accident

It's somewhat embarassing to admit, but I don't think I really learned how to teach myself things effectively until at least the age of 26.

When I look back, I realise much of my learning was a result of accidental chance; for example, I learned to program mostly by virtue of complete immersion and stumbling upon 'the right things'. I just followed my nose (and to be fair it worked out).

But now I'm an adult with a job and a family, and my time is far more precious. If I want to learn something new, I can't count on stumbling on the right approach anymore. Simply creating the conditions in which learning is possible is not sufficient, since I lack the time that approach requires.

Enter Mentor

How I learned to learn is, surprisingly, not at all related to my area of study or profession (software), but a hobby.

I met my whistle teacher Becky in 2020 on a video call. It was near the start of the pandemic, and I had some extra time on my hands. Becky is somewhat unlike other teachers I've had, it that she could mechanically break down and explain music to me in a way that allowed me not just to play it, but understand what I was playing.

The whistle is a small, cheap, end-blown flute – somewhat like a budget recorder. It has six tone holes that you cover with three fingers of either hand, and a mouthpiece that you blow in to. Out of this deceptively simple instrument, you can get two full octaves of range in two major keys and all the keys that come along with that. That is to say, it's small, but surprisingly versatile.

Irish traditional music, along with other traditional music of the British isles, is generally learned and played by ear, though sheet music is available. What sets this folk music apart from most classical and contemporary music is that the sheet music is essentially a suggestion. Using your skill, wits, and guile, you have to take a couple of parts of a repetitive tune and make it interesting.

This is where Becky comes in, with two really solid pieces of advice: one about how to practice, and one about how to learn.

Mindful Practice

The first of the things Becky taught me was how to practice; how to gain the mechanical skill required to execute what I knew, and to transform my knowledge into understanding.

"Know what you're going to practice before you pick up the whistle"

In retrospect, startlingly obvious. Noodling around randomly does very little but ingrain what you've already learned; if you want to learn something new then you have to have a goal. But, as with many things in life, having a plan (even if you have no idea what you're getting in to) is half the battle.

"Five minutes every day is better than an hour once per week"

This subtly implies something else; you should make your practice not just habit and routine, but low-friction and easy to access. You will do much better chipping away at small, easy problems, than trying to tackle a hard problem you are not ready for (and all hard problems are just n easy problems in a trenchcoat anyway).

"Do it slow until you can do it right"

This one has a very "slow is smooth, smooth is fast" kind of vibe, and it's right. Doing something slowly and accurately is hard. In a programming context, it's very easy to whack together some code that delivers a feature, but the end result is of limited use if it's buggy, doesn't actually deliver the desired feature, or is riddled with security or structural issues.

Learning to Learn

The second thing Becky taught me was how to learn. Specifically, how to learn an instrument, or a tune – the approach is broadly the same.

It's a model, and as my colleague Craig likes to say; all models are wrong, but some are useful. Hopefully this is one of the latter.

"First, learn the notes"

You have to be able to play a tune through in its entirety. Obvious, right? But there's a lot here – some tunes are difficult. Some tunes don't have a written form, and you'll have to learn them by ear. Worse, some tunes have very poorly transcribed sheet music that will lead you astray! Not all learning material is created equal.

Beyond that, you will also have to contend with your own (lack of) mechanical skill. You will likely get stumped by a strange combination of notes. Perhaps you're not accustomed to switching octaves so quickly, or you accidentally bang out the wrong note because of some pattern you've learned in a previous tune.

"Second, make it more interesting"

Boy, isn't that 'interesting' a really load-bearing word? In this context, it means adding ornamentation, variation, dynamics, and a plethora of other tools in the folk musician's toolbox.

Making the piece flow better - the folk musician's version of 'clean code' - is key to turning a roughly shaped tune into refined birdsong.

"Third, play the tune"

Taking all you have learned, play the tune. Not the notes. Not the parts. The whole thing. Feel the rhythm, lean in to the swing, and add to it with your performance.

This is not just the culmination of learning how to play the tune - it's the start of learning the meta-skill of picking up and playing the tunes you come across.

In code terms; release it. You must make mistakes to improve, and more often than not you will be startled how others see something that is so mundane to you as so magical.

Some observations

This is not a new topic, or a new field. People much smarter and more experienced than me have studied this for a long time, but I share it in hopes that for someone out there, the same realisations I had will click.

If you want to read more on this topic, take a look at:

And if I've somehow convinced you to listen to whistle music:

Thanks readers, and thanks Becky!


Posted 2022-06-19
From ec731aa85b3007793d7802a36cc31957291bcecc Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Sun, 19 Jun 2022 15:27:21 +0000 Subject: [PATCH 11/43] www-build-15 --- posts/relearning-to-learn.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/posts/relearning-to-learn.html b/posts/relearning-to-learn.html index b4b8a47..211213a 100644 --- a/posts/relearning-to-learn.html +++ b/posts/relearning-to-learn.html @@ -25,7 +25,7 @@

sourceless

contact -

Relearning to Learn

Many years ago, I took a test. It was the first step of our "Learning to Learn" class. After answering a series of multiple choice question, the form issued forth a proclomation:

YOU ARE A VISUAL LEARNER.

Over the course of my years at school I would learn this piece of information to be on the whole useless and entirely innefectual.

To cut a long story short, school and university didn't go particularly well for me.

Learning by accident

It's somewhat embarassing to admit, but I don't think I really learned how to teach myself things effectively until at least the age of 26.

When I look back, I realise much of my learning was a result of accidental chance; for example, I learned to program mostly by virtue of complete immersion and stumbling upon 'the right things'. I just followed my nose (and to be fair it worked out).

But now I'm an adult with a job and a family, and my time is far more precious. If I want to learn something new, I can't count on stumbling on the right approach anymore. Simply creating the conditions in which learning is possible is not sufficient, since I lack the time that approach requires.

Enter Mentor

How I learned to learn is, surprisingly, not at all related to my area of study or profession (software), but a hobby.

I met my whistle teacher Becky in 2020 on a video call. It was near the start of the pandemic, and I had some extra time on my hands. Becky is somewhat unlike other teachers I've had, it that she could mechanically break down and explain music to me in a way that allowed me not just to play it, but understand what I was playing.

The whistle is a small, cheap, end-blown flute – somewhat like a budget recorder. It has six tone holes that you cover with three fingers of either hand, and a mouthpiece that you blow in to. Out of this deceptively simple instrument, you can get two full octaves of range in two major keys and all the keys that come along with that. That is to say, it's small, but surprisingly versatile.

Irish traditional music, along with other traditional music of the British isles, is generally learned and played by ear, though sheet music is available. What sets this folk music apart from most classical and contemporary music is that the sheet music is essentially a suggestion. Using your skill, wits, and guile, you have to take a couple of parts of a repetitive tune and make it interesting.

This is where Becky comes in, with two really solid pieces of advice: one about how to practice, and one about how to learn.

Mindful Practice

The first of the things Becky taught me was how to practice; how to gain the mechanical skill required to execute what I knew, and to transform my knowledge into understanding.

"Know what you're going to practice before you pick up the whistle"

In retrospect, startlingly obvious. Noodling around randomly does very little but ingrain what you've already learned; if you want to learn something new then you have to have a goal. But, as with many things in life, having a plan (even if you have no idea what you're getting in to) is half the battle.

"Five minutes every day is better than an hour once per week"

This subtly implies something else; you should make your practice not just habit and routine, but low-friction and easy to access. You will do much better chipping away at small, easy problems, than trying to tackle a hard problem you are not ready for (and all hard problems are just n easy problems in a trenchcoat anyway).

"Do it slow until you can do it right"

This one has a very "slow is smooth, smooth is fast" kind of vibe, and it's right. Doing something slowly and accurately is hard. In a programming context, it's very easy to whack together some code that delivers a feature, but the end result is of limited use if it's buggy, doesn't actually deliver the desired feature, or is riddled with security or structural issues.

Learning to Learn

The second thing Becky taught me was how to learn. Specifically, how to learn an instrument, or a tune – the approach is broadly the same.

It's a model, and as my colleague Craig likes to say; all models are wrong, but some are useful. Hopefully this is one of the latter.

"First, learn the notes"

You have to be able to play a tune through in its entirety. Obvious, right? But there's a lot here – some tunes are difficult. Some tunes don't have a written form, and you'll have to learn them by ear. Worse, some tunes have very poorly transcribed sheet music that will lead you astray! Not all learning material is created equal.

Beyond that, you will also have to contend with your own (lack of) mechanical skill. You will likely get stumped by a strange combination of notes. Perhaps you're not accustomed to switching octaves so quickly, or you accidentally bang out the wrong note because of some pattern you've learned in a previous tune.

"Second, make it more interesting"

Boy, isn't that 'interesting' a really load-bearing word? In this context, it means adding ornamentation, variation, dynamics, and a plethora of other tools in the folk musician's toolbox.

Making the piece flow better - the folk musician's version of 'clean code' - is key to turning a roughly shaped tune into refined birdsong.

"Third, play the tune"

Taking all you have learned, play the tune. Not the notes. Not the parts. The whole thing. Feel the rhythm, lean in to the swing, and add to it with your performance.

This is not just the culmination of learning how to play the tune - it's the start of learning the meta-skill of picking up and playing the tunes you come across.

In code terms; release it. You must make mistakes to improve, and more often than not you will be startled how others see something that is so mundane to you as so magical.

Some observations

This is not a new topic, or a new field. People much smarter and more experienced than me have studied this for a long time, but I share it in hopes that for someone out there, the same realisations I had will click.

If you want to read more on this topic, take a look at:

And if I've somehow convinced you to listen to whistle music:

Thanks readers, and thanks Becky!

+

Relearning to Learn

Many years ago, I took a test. It was the first step of our "Learning to Learn" class. After answering a series of multiple choice question, the form issued forth a proclomation:

YOU ARE A VISUAL LEARNER.

Over the course of my years at school I would learn this piece of information to be on the whole useless and entirely innefectual.

To cut a long story short, school and university didn't go particularly well for me.

Learning by accident

It's somewhat embarassing to admit, but I don't think I really learned how to teach myself things effectively until at least the age of 26.

When I look back, I realise much of my learning was a result of accidental chance; for example, I learned to program mostly by virtue of complete immersion and stumbling upon 'the right things'. I just followed my nose (and to be fair it worked out).

But now I'm an adult with a job and a family, and my time is far more precious. If I want to learn something new, I can't count on stumbling on the right approach anymore. Simply creating the conditions in which learning is possible is not sufficient, since I lack the time that approach requires.

Enter Mentor

How I learned to learn is, surprisingly, not at all related to my area of study or profession (software), but a hobby.

I met my whistle teacher Becky in 2020 on a video call. It was near the start of the pandemic, and I had some extra time on my hands. Becky is somewhat unlike other teachers I've had, in that she could mechanically break down and explain music to me in a way that allowed me not just to play it, but understand what I was playing.

The whistle is a small, cheap, end-blown flute – somewhat like a budget recorder. It has six tone holes that you cover with three fingers of either hand, and a mouthpiece that you blow in to. Out of this deceptively simple instrument, you can get two full octaves of range in two major keys and all the keys that come along with that. That is to say, it's small, but surprisingly versatile.

Irish traditional music, along with other traditional music of the British isles, is generally learned and played by ear, though sheet music is available. What sets this folk music apart from most classical and contemporary music is that the sheet music is essentially a suggestion. Using your skill, wits, and guile, you have to take a couple of parts of a repetitive tune and make it interesting.

This is where Becky comes in, with two really solid pieces of advice: one about how to practice, and one about how to learn.

Mindful Practice

The first of the things Becky taught me was how to practice; how to gain the mechanical skill required to execute what I knew, and to transform my knowledge into understanding.

"Know what you're going to practice before you pick up the whistle"

In retrospect, startlingly obvious. Noodling around randomly does very little but ingrain what you've already learned; if you want to learn something new then you have to have a goal. But, as with many things in life, having a plan (even if you have no idea what you're getting in to) is half the battle.

"Five minutes every day is better than an hour once per week"

This subtly implies something else; you should make your practice not just habit and routine, but low-friction and easy to access. You will do much better chipping away at small, easy problems, than trying to tackle a hard problem you are not ready for (and all hard problems are just n easy problems in a trenchcoat anyway).

"Do it slow until you can do it right"

This one has a very "slow is smooth, smooth is fast" kind of vibe, and it's right. Doing something slowly and accurately is hard. In a programming context, it's very easy to whack together some code that delivers a feature, but the end result is of limited use if it's buggy, doesn't actually deliver the desired feature, or is riddled with security or structural issues.

Learning to Learn

The second thing Becky taught me was how to learn. Specifically, how to learn an instrument, or a tune – the approach is broadly the same.

It's a model, and as my colleague Craig likes to say; all models are wrong, but some are useful. Hopefully this is one of the latter.

"First, learn the notes"

You have to be able to play a tune through in its entirety. Obvious, right? But there's a lot here – some tunes are difficult. Some tunes don't have a written form, and you'll have to learn them by ear. Worse, some tunes have very poorly transcribed sheet music that will lead you astray! Not all learning material is created equal.

Beyond that, you will also have to contend with your own (lack of) mechanical skill. You will likely get stumped by a strange combination of notes. Perhaps you're not accustomed to switching octaves so quickly, or you accidentally bang out the wrong note because of some pattern you've learned in a previous tune.

"Second, make it more interesting"

Boy, isn't that 'interesting' a really load-bearing word? In this context, it means adding ornamentation, variation, dynamics, and a plethora of other tools in the folk musician's toolbox.

Making the piece flow better - the folk musician's version of 'clean code' - is key to turning a roughly shaped tune into refined birdsong.

"Third, play the tune"

Taking all you have learned, play the tune. Not the notes. Not the parts. The whole thing. Feel the rhythm, lean in to the swing, and add to it with your performance.

This is not just the culmination of learning how to play the tune - it's the start of learning the meta-skill of picking up and playing the tunes you come across.

In code terms; release it. You must make mistakes to improve, and more often than not you will be startled how others see something that is so mundane to you as so magical.

Some observations

This is not a new topic, or a new field. People much smarter and more experienced than me have studied this for a long time, but I share it in hopes that for someone out there, the same realisations I had will click.

If you want to read more on this topic, take a look at:

And if I've somehow convinced you to listen to whistle music:

Thanks readers, and thanks Becky!


Posted 2022-06-19
From 8674fa99ecb8794b8c05d0bcd8ac4ee65d9d2572 Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Sun, 19 Jun 2022 15:33:55 +0000 Subject: [PATCH 12/43] www-build-16 --- about.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/about.html b/about.html index 98f9e78..6d52877 100644 --- a/about.html +++ b/about.html @@ -25,7 +25,7 @@

sourceless

contact -

Hi, I'm Laurence Pakenham-Smith.

I'm a software engineer in the Healthcare industry, with experience in the NHS (UK) and the US Health insurance industry.

My topics of particular interest are:

  • Building high performing teams
  • Building software that helps teams perform
  • Making delightful interfaces
  • Provably correct computing

I've dabbled in a lot of things, including:

  • Formal methods
  • Computer graphics

Most of my professional experience is in Python, Ruby, JavaScript, and similar languages, but in my spare time I build things in Clojure and Rust.

+

Hi, I'm Laurence Pakenham-Smith.

I'm an SRE Manager in the AdTech industry. In previous lives I've done SRE, security, and software in Healthcare and Government.

Notable past projects include:

My topics of particular interest are:

  • Building and running high performing teams
  • User-first security, compliance, and governance
  • Logic programming
  • Type systems

I've worked on a lot of projects in a lot of languages and frameworks; the best of those were backed by great teams that knew their tools inside out.

From 00dd45cbbf3cddf12731e434ce7b914bfa4e5f8d Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Sun, 19 Jun 2022 15:34:38 +0000 Subject: [PATCH 13/43] www-build-17 --- about.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/about.html b/about.html index 6d52877..f9ed73a 100644 --- a/about.html +++ b/about.html @@ -25,7 +25,7 @@

sourceless

contact -

Hi, I'm Laurence Pakenham-Smith.

I'm an SRE Manager in the AdTech industry. In previous lives I've done SRE, security, and software in Healthcare and Government.

Notable past projects include:

My topics of particular interest are:

  • Building and running high performing teams
  • User-first security, compliance, and governance
  • Logic programming
  • Type systems

I've worked on a lot of projects in a lot of languages and frameworks; the best of those were backed by great teams that knew their tools inside out.

+

Hi, I'm Laurence Pakenham-Smith.

I'm an SRE Manager in the AdTech industry. In previous lives I've done SRE, security, and software in Healthcare and Government.

Notable past projects include:

My topics of particular interest are:

  • Building and running high performing teams
  • User-first security, compliance, and governance
  • Logic programming
  • Type systems

I've worked on a lot of projects in a lot of languages and frameworks; the best of those were backed by great teams that knew their tools inside out.

If you want to talk, or just want to see a CV, check out my linkedin.

From 153752b1faf9d6d75cc6e65d91f108cb2dfd22ee Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Sun, 19 Jun 2022 15:35:31 +0000 Subject: [PATCH 14/43] www-build-18 --- contact.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contact.html b/contact.html index a87ff62..289bc86 100644 --- a/contact.html +++ b/contact.html @@ -25,7 +25,7 @@

sourceless

contact -

E: laurence@[this website]
T: @sourceless
GH: sourceless
HN: sourceless

+

E: laurence@[this website]
T: @sourceless
GH: sourceless
HN: sourceless L: laurencejosephsmith

From ffeb00447d5d01fa945ed741a8e799b48f219a59 Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Sun, 19 Jun 2022 15:41:06 +0000 Subject: [PATCH 15/43] www-build-20 --- about.html | 2 +- contact.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/about.html b/about.html index f9ed73a..76f09a3 100644 --- a/about.html +++ b/about.html @@ -25,7 +25,7 @@

sourceless

contact -

Hi, I'm Laurence Pakenham-Smith.

I'm an SRE Manager in the AdTech industry. In previous lives I've done SRE, security, and software in Healthcare and Government.

Notable past projects include:

My topics of particular interest are:

  • Building and running high performing teams
  • User-first security, compliance, and governance
  • Logic programming
  • Type systems

I've worked on a lot of projects in a lot of languages and frameworks; the best of those were backed by great teams that knew their tools inside out.

If you want to talk, or just want to see a CV, check out my linkedin.

+

Hi, I'm Laurence Pakenham-Smith.

I'm an SRE Manager in the AdTech industry. In previous lives I've done SRE, security, and software in Healthcare and Government.

Notable past projects include:

My topics of particular interest are:

  • Building and running high performing teams
  • User-first security, compliance, and governance
  • Logic programming
  • Type systems

I've worked on a lot of projects in a lot of languages and frameworks; the best of those were backed by great teams that knew their tools inside out.

If you want to talk, or just want to see a CV, check out my linkedin.

diff --git a/contact.html b/contact.html index 289bc86..f82ef5e 100644 --- a/contact.html +++ b/contact.html @@ -25,7 +25,7 @@

sourceless

contact -

E: laurence@[this website]
T: @sourceless
GH: sourceless
HN: sourceless L: laurencejosephsmith

+

E: laurence@[this website]
T: @sourceless
GH: sourceless
HN: sourceless

L: laurencejosephsmith

From 27fc9921bd6400c07b53b1a28e21bc39c94885d7 Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Sun, 19 Jun 2022 15:43:15 +0000 Subject: [PATCH 16/43] www-build-21 --- contact.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contact.html b/contact.html index f82ef5e..289bc86 100644 --- a/contact.html +++ b/contact.html @@ -25,7 +25,7 @@

sourceless

contact -

E: laurence@[this website]
T: @sourceless
GH: sourceless
HN: sourceless

L: laurencejosephsmith

+

E: laurence@[this website]
T: @sourceless
GH: sourceless
HN: sourceless L: laurencejosephsmith

From 270130fe82790dc41285145e0ba0b8a790420baa Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Wed, 22 Jun 2022 10:00:11 +0000 Subject: [PATCH 17/43] www-build-22 --- index.html | 2 ++ posts/perfect-isnt-good-enough.html | 40 +++++++++++++++++++++++++++++ posts/relearning-to-learn.html | 2 ++ 3 files changed, 44 insertions(+) create mode 100644 posts/perfect-isnt-good-enough.html diff --git a/index.html b/index.html index 95086c2..50fb600 100644 --- a/index.html +++ b/index.html @@ -29,6 +29,8 @@

sourceless



+ 2022-06-22 Perfect isn't Good Enough
+ 2022-06-19 Relearning to Learn
2021-03-19 The Documentation Triangle
diff --git a/posts/perfect-isnt-good-enough.html b/posts/perfect-isnt-good-enough.html new file mode 100644 index 0000000..45cb5bc --- /dev/null +++ b/posts/perfect-isnt-good-enough.html @@ -0,0 +1,40 @@ + + + + + Sourceless - Perfect isn't Good Enough + + + + + + + + + + + + +

sourceless

+ + +index + + about + + contact + + +

Perfect isn't Good Enough

Perfect is the enemy of the good

Or so goes the old adage. For developers, perfection is a mightier enemy than users, project managers, and even one's own lack of skill.

In pursuit of greatness

Many junior (and senior!) engineers strive to write the best code. Clean code. Well-tested. Fully covered. Abstractions on abstractions making beautiful, elegant interfaces.

Beautiful, elegant, fragile interfaces, which shatter upon exposure to the expectations of an ever-changing world.

No (useful) system exists in a vacuum. Users' needs change over time, as does the substrate on which software relies. Nothing is permanent.

The worst thing I've ever built

Very early in my career, I built a system to click through HTML forms, submit some information and return some information. There weren't APIs for this kind of thing, so traversing through legacy websites was the only way.

Even with that short description, you've probably already thought how you would do it; and most of you probably have a better plan than I, a junior developer at the time, did.

So I birthed a new language in to the world. A powerful tool to be sure. By issuing a list of simple commands, a headless browser would go off and perform the commands, fill the forms, and return the information we needed.

Great! Right?

But then there were different forms that were differently bad. Commands had to change and gain options. Commands were constantly bug-fixed. The code that ran was stored in a SQL database, so changing anything required a full run of the system and debugging was waiting for logs to populate. Every new integration made the system heavier and bigger and buggier.

If you're cringing – that's correct. If you're not – come back in a couple years (after you finish reading this).

The making of burdens

Why was that system so bad? What was it that I did that made it so inextensible and brittle?

The first reason is greed. I wanted to make something cool. I sought a challenge where non existed! The problem I was seeking to solve was primarily my own creation.

The second reason is ignorance. I naively believed that the original purpose of the system is all it would ever do.

The third, and perhaps worst reason, is hubris. Perfection for my own selfish reasons – not for the user, but the maker.

I didn't learn how to control each of these right away, and still combat each of these in my working and hobby lives. In moderation, these things are a positive force for learning, but when they take over – beware.

A successful mistake

My most recent relapse was creating an internal tool for a team to register public keys into a repository. By most measures I did an extremely good job of it – it was reliable, did only what it needed to, and was easy for me to extend.

'easy for me to extend'

Ah. Now there was the problem. This tool I created became a victim of its own success and, due to other commitments, changes needed to be made by other members of my team.

Which, for a little web frontend, would have been fine. Had I been on a team used to writing purely functional code, and had I not written it in Elm (no shade to Elm, it's a fantastic language, but it was the wrong choice in this context).

I had failed to keep in mind the future life of this thing I had created.

Code, much like art, ceases to belong to its author once it is released in to the world.

Valueless perfection and glorious mediocrity

Each of these issues of greed, ignorance, and hubris can be avoided through a judicious application of mediocrity.

The key to this is recognising that the time you spend trying to create something perfect is not only extremely expensive (you could release something much earlier), but also holds little value. A program is worthless until it is used, and will not grow in value if you make it too hard to change.

This doesn't mean you shouldn't experiment and sharpen your skills - just make sure you are aiming at a target, and not your own or someone else's foot.

Doing the dumbest possible thing

It's here, then, that I urge you to do the dumbest possible thing.

That may be somewhat hyperbolic, but here's what I mean by it:

  • Your code probably isn't written to serve you, so before anything else make sure it serves the user's needs. You have plenty of time to play on your own time.
  • Don't write more than you need to. Doing anything more than is sufficient is a waste of time. One-off script? Don't write tests for it. Wrote the same thing twice? Great, leave it. You don't know if every use case is going to look like that (aka Avoid Hasty Abstractions).
  • Get it out the door. The code you write has no value until it is used. Your assumptions can only be validated if you have something to test against! This doesn't mean you should ship completely broken stuff - what it does mean, however, is that you need a full solution to the problem, even if it's a crappy solution, so that you can make sure you're building the right thing.
  • Optimise nothing. You don't know what's going to be the slowest part yet, so don't waste effort solving a problem you don't have.

In other words; make it Just Good Enough to do what you need.

+
+ Posted 2022-06-22 +
+
+ +← Relearning to Learn + + + +
+ + diff --git a/posts/relearning-to-learn.html b/posts/relearning-to-learn.html index 211213a..143d74c 100644 --- a/posts/relearning-to-learn.html +++ b/posts/relearning-to-learn.html @@ -34,6 +34,8 @@

Relearning to Learn

Many years ago, I took a test. It was the first s ← The Documentation Triangle +Perfect isn't Good Enough → + From b9c88c4eba294a2e1991c961ffe67cb6b9aee44d Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Wed, 22 Jun 2022 10:06:31 +0000 Subject: [PATCH 18/43] www-build-23 --- posts/relearning-to-learn.html | 2 +- posts/the-documentation-triangle.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/posts/relearning-to-learn.html b/posts/relearning-to-learn.html index 143d74c..c789043 100644 --- a/posts/relearning-to-learn.html +++ b/posts/relearning-to-learn.html @@ -25,7 +25,7 @@

sourceless

contact -

Relearning to Learn

Many years ago, I took a test. It was the first step of our "Learning to Learn" class. After answering a series of multiple choice question, the form issued forth a proclomation:

YOU ARE A VISUAL LEARNER.

Over the course of my years at school I would learn this piece of information to be on the whole useless and entirely innefectual.

To cut a long story short, school and university didn't go particularly well for me.

Learning by accident

It's somewhat embarassing to admit, but I don't think I really learned how to teach myself things effectively until at least the age of 26.

When I look back, I realise much of my learning was a result of accidental chance; for example, I learned to program mostly by virtue of complete immersion and stumbling upon 'the right things'. I just followed my nose (and to be fair it worked out).

But now I'm an adult with a job and a family, and my time is far more precious. If I want to learn something new, I can't count on stumbling on the right approach anymore. Simply creating the conditions in which learning is possible is not sufficient, since I lack the time that approach requires.

Enter Mentor

How I learned to learn is, surprisingly, not at all related to my area of study or profession (software), but a hobby.

I met my whistle teacher Becky in 2020 on a video call. It was near the start of the pandemic, and I had some extra time on my hands. Becky is somewhat unlike other teachers I've had, in that she could mechanically break down and explain music to me in a way that allowed me not just to play it, but understand what I was playing.

The whistle is a small, cheap, end-blown flute – somewhat like a budget recorder. It has six tone holes that you cover with three fingers of either hand, and a mouthpiece that you blow in to. Out of this deceptively simple instrument, you can get two full octaves of range in two major keys and all the keys that come along with that. That is to say, it's small, but surprisingly versatile.

Irish traditional music, along with other traditional music of the British isles, is generally learned and played by ear, though sheet music is available. What sets this folk music apart from most classical and contemporary music is that the sheet music is essentially a suggestion. Using your skill, wits, and guile, you have to take a couple of parts of a repetitive tune and make it interesting.

This is where Becky comes in, with two really solid pieces of advice: one about how to practice, and one about how to learn.

Mindful Practice

The first of the things Becky taught me was how to practice; how to gain the mechanical skill required to execute what I knew, and to transform my knowledge into understanding.

"Know what you're going to practice before you pick up the whistle"

In retrospect, startlingly obvious. Noodling around randomly does very little but ingrain what you've already learned; if you want to learn something new then you have to have a goal. But, as with many things in life, having a plan (even if you have no idea what you're getting in to) is half the battle.

"Five minutes every day is better than an hour once per week"

This subtly implies something else; you should make your practice not just habit and routine, but low-friction and easy to access. You will do much better chipping away at small, easy problems, than trying to tackle a hard problem you are not ready for (and all hard problems are just n easy problems in a trenchcoat anyway).

"Do it slow until you can do it right"

This one has a very "slow is smooth, smooth is fast" kind of vibe, and it's right. Doing something slowly and accurately is hard. In a programming context, it's very easy to whack together some code that delivers a feature, but the end result is of limited use if it's buggy, doesn't actually deliver the desired feature, or is riddled with security or structural issues.

Learning to Learn

The second thing Becky taught me was how to learn. Specifically, how to learn an instrument, or a tune – the approach is broadly the same.

It's a model, and as my colleague Craig likes to say; all models are wrong, but some are useful. Hopefully this is one of the latter.

"First, learn the notes"

You have to be able to play a tune through in its entirety. Obvious, right? But there's a lot here – some tunes are difficult. Some tunes don't have a written form, and you'll have to learn them by ear. Worse, some tunes have very poorly transcribed sheet music that will lead you astray! Not all learning material is created equal.

Beyond that, you will also have to contend with your own (lack of) mechanical skill. You will likely get stumped by a strange combination of notes. Perhaps you're not accustomed to switching octaves so quickly, or you accidentally bang out the wrong note because of some pattern you've learned in a previous tune.

"Second, make it more interesting"

Boy, isn't that 'interesting' a really load-bearing word? In this context, it means adding ornamentation, variation, dynamics, and a plethora of other tools in the folk musician's toolbox.

Making the piece flow better - the folk musician's version of 'clean code' - is key to turning a roughly shaped tune into refined birdsong.

"Third, play the tune"

Taking all you have learned, play the tune. Not the notes. Not the parts. The whole thing. Feel the rhythm, lean in to the swing, and add to it with your performance.

This is not just the culmination of learning how to play the tune - it's the start of learning the meta-skill of picking up and playing the tunes you come across.

In code terms; release it. You must make mistakes to improve, and more often than not you will be startled how others see something that is so mundane to you as so magical.

Some observations

This is not a new topic, or a new field. People much smarter and more experienced than me have studied this for a long time, but I share it in hopes that for someone out there, the same realisations I had will click.

If you want to read more on this topic, take a look at:

And if I've somehow convinced you to listen to whistle music:

Thanks readers, and thanks Becky!

+

Relearning to Learn

Many years ago, I took a test. It was the first step of our "Learning to Learn" class. After answering a series of multiple choice question, the form issued forth a proclomation:

YOU ARE A VISUAL LEARNER.

Over the course of my years at school I would learn this piece of information to be on the whole useless and entirely innefectual.

To cut a long story short, school and university didn't go particularly well for me.

Learning by accident

It's somewhat embarassing to admit, but I don't think I really learned how to teach myself things effectively until at least the age of 26.

When I look back, I realise much of my learning was a result of accidental chance; for example, I learned to program mostly by virtue of complete immersion and stumbling upon 'the right things'. I just followed my nose (and to be fair it worked out).

But now I'm an adult with a job and a family, and my time is far more precious. If I want to learn something new, I can't count on stumbling on the right approach anymore. Simply creating the conditions in which learning is possible is not sufficient, since I lack the time that approach requires.

Enter Mentor

How I learned to learn is, surprisingly, not at all related to my area of study or profession (software), but a hobby.

I met my whistle teacher Becky in 2020 on a video call. It was near the start of the pandemic, and I had some extra time on my hands. Becky is somewhat unlike other teachers I've had, in that she could mechanically break down and explain music to me in a way that allowed me not just to play it, but understand what I was playing.

The whistle is a small, cheap, end-blown flute – somewhat like a budget recorder. It has six tone holes that you cover with three fingers of either hand, and a mouthpiece that you blow in to. Out of this deceptively simple instrument, you can get two full octaves of range in two major keys and all the keys that come along with that. That is to say, it's small, but surprisingly versatile.

Irish traditional music, along with other traditional music of the British isles, is generally learned and played by ear, though sheet music is available. What sets this folk music apart from most classical and contemporary music is that the sheet music is essentially a suggestion. Using your skill, wits, and guile, you have to take a couple of parts of a repetitive tune and make it interesting.

This is where Becky comes in, with two really solid pieces of advice: one about how to practice, and one about how to learn.

Mindful Practice

The first of the things Becky taught me was how to practice; how to gain the mechanical skill required to execute what I knew, and to transform my knowledge into understanding.

"Know what you're going to practice before you pick up the whistle"

In retrospect, startlingly obvious. Noodling around randomly does very little but ingrain what you've already learned; if you want to learn something new then you have to have a goal. But, as with many things in life, having a plan (even if you have no idea what you're getting in to) is half the battle.

"Five minutes every day is better than an hour once per week"

This subtly implies something else; you should make your practice not just habit and routine, but low-friction and easy to access. You will do much better chipping away at small, easy problems, than trying to tackle a hard problem you are not ready for (and all hard problems are just n easy problems in a trenchcoat anyway).

"Do it slow until you can do it right"

This one has a very "slow is smooth, smooth is fast" kind of vibe, and it's right. Doing something slowly and accurately is hard. In a programming context, it's very easy to whack together some code that delivers a feature, but the end result is of limited use if it's buggy, doesn't actually deliver the desired feature, or is riddled with security or structural issues.

Learning to Learn

The second thing Becky taught me was how to learn. Specifically, how to learn an instrument, or a tune – the approach is broadly the same.

It's a model, and as my colleague Craig likes to say; all models are wrong, but some are useful. Hopefully this is one of the latter.

"First, learn the notes"

You have to be able to play a tune through in its entirety. Obvious, right? But there's a lot here – some tunes are difficult. Some tunes don't have a written form, and you'll have to learn them by ear. Worse, some tunes have very poorly transcribed sheet music that will lead you astray! Not all learning material is created equal.

Beyond that, you will also have to contend with your own (lack of) mechanical skill. You will likely get stumped by a strange combination of notes. Perhaps you're not accustomed to switching octaves so quickly, or you accidentally bang out the wrong note because of some pattern you've learned in a previous tune.

"Second, make it more interesting"

Boy, isn't that 'interesting' a really load-bearing word? In this context, it means adding ornamentation, variation, dynamics, and a plethora of other tools in the folk musician's toolbox.

Making the piece flow better - the folk musician's version of 'clean code' - is key to turning a roughly shaped tune into refined birdsong.

"Third, play the tune"

Taking all you have learned, play the tune. Not the notes. Not the parts. The whole thing. Feel the rhythm, lean in to the swing, and add to it with your performance.

This is not just the culmination of learning how to play the tune - it's the start of learning the meta-skill of picking up and playing the tunes you come across.

In code terms; release it. You must make mistakes to improve, and more often than not you will be startled how others see something that is so mundane to you as so magical.

Some observations

This is not a new topic, or a new field. People much smarter and more experienced than me have studied this for a long time, but I share it in hopes that for someone out there, the same realisations I had will click.

If you want to read more on this topic, take a look at:

And if I've somehow convinced you to listen to whistle music:

Thanks readers, and thanks Becky!

Discussion of this article on Hacker News


Posted 2022-06-19
diff --git a/posts/the-documentation-triangle.html b/posts/the-documentation-triangle.html index 941a2f3..da8f7aa 100644 --- a/posts/the-documentation-triangle.html +++ b/posts/the-documentation-triangle.html @@ -33,7 +33,7 @@

The Documentation Triangle (or, why code isn't self documenting)

At s / \ /__________\ Why How -

Here's a rule of thumb I've seen repeated in a few places regarding how to ensure that your documentation is up to scratch.

Why a triangle? Well, triangles are a strong shape, and any missing side renders it entirely structurally unsound - just as missing out vital documentation can make your code as good as unusable to others.

What (code)

This is generally what people are going for when they say "my code is self documenting". Clear, concise, and well-written code is a form of documentation in itself.

It is the most honest account of what actually happens when you run the code, what the most important data structures are, and what interfaces you'll be able to interact with. Some languages are better than this for others, and supplementary information such as type signatures can be incredibly helpful in understanding some code that's new to you. However, there are some things this alone leaves out...

Why (comments)

Every program has a history - whether in the very mundane sense of having a history in version control, or a long and detailed history of changes it has undergone to meet various challenges.

It's this latter case that is the most crucial to note why certain pieces of code exist in their current state.

Comments are most often the vehicle for these sort of margin notes. Noting that this thing was done in this way for optimization reasons, or another thing was a dirty hack leaves signposts for the next maintainer to know what compromises have been made in building this software.

Maintaining (legacy) code without any comments is less like being a mechanic, and much more like being an archaeologist.

How (context)

The last side of the triangle is often the most neglected. It might live in docstrings, or in confluence, be automatically generated, or be in a carefully crafted README, but it's all information on the context in which the code will be executed.

No program exists in a vacuum. There is always some environment, some organisation, some process that it lives in or serves, and taken out of said context, it is entirely useless.

Failing to recognise this is the number one leading cause of new users and junior devs being unable to do 'this simple task' (don't quote me on this, I have no data).

There's a great litmus test for this. Take the new process or pipeline or whatever that you've implemented (be it setting up a repo, running a job, etc.) and find yourself someone that's technically competent but unfamiliar with what you're working on. Plonk them in front of it and shut the fuck up. Watch them struggle through it and only help them if they are genuinely, truly stumped. This will very quickly tell you where you need to spend effort on documentation.

Heck - make it part of your code review.

+

Here's a rule of thumb I've seen repeated in a few places regarding how to ensure that your documentation is up to scratch.

Why a triangle? Well, triangles are a strong shape, and any missing side renders it entirely structurally unsound - just as missing out vital documentation can make your code as good as unusable to others.

What (code)

This is generally what people are going for when they say "my code is self documenting". Clear, concise, and well-written code is a form of documentation in itself.

It is the most honest account of what actually happens when you run the code, what the most important data structures are, and what interfaces you'll be able to interact with. Some languages are better than this for others, and supplementary information such as type signatures can be incredibly helpful in understanding some code that's new to you. However, there are some things this alone leaves out...

Why (comments)

Every program has a history - whether in the very mundane sense of having a history in version control, or a long and detailed history of changes it has undergone to meet various challenges.

It's this latter case that is the most crucial to note why certain pieces of code exist in their current state.

Comments are most often the vehicle for these sort of margin notes. Noting that this thing was done in this way for optimization reasons, or another thing was a dirty hack leaves signposts for the next maintainer to know what compromises have been made in building this software.

Maintaining (legacy) code without any comments is less like being a mechanic, and much more like being an archaeologist.

How (context)

The last side of the triangle is often the most neglected. It might live in docstrings, or in confluence, be automatically generated, or be in a carefully crafted README, but it's all information on the context in which the code will be executed.

No program exists in a vacuum. There is always some environment, some organisation, some process that it lives in or serves, and taken out of said context, it is entirely useless.

Failing to recognise this is the number one leading cause of new users and junior devs being unable to do 'this simple task' (don't quote me on this, I have no data).

There's a great litmus test for this. Take the new process or pipeline or whatever that you've implemented (be it setting up a repo, running a job, etc.) and find yourself someone that's technically competent but unfamiliar with what you're working on. Plonk them in front of it and shut the fuck up. Watch them struggle through it and only help them if they are genuinely, truly stumped. This will very quickly tell you where you need to spend effort on documentation.

Heck - make it part of your code review.

Discussion of this article on Hacker News


Posted 2021-03-19
From 95223e555e0619e1ff64f438d55fea6393086da6 Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Wed, 22 Jun 2022 10:21:14 +0000 Subject: [PATCH 19/43] www-build-24 --- contact.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contact.html b/contact.html index 289bc86..223456e 100644 --- a/contact.html +++ b/contact.html @@ -25,7 +25,7 @@

sourceless

contact -

E: laurence@[this website]
T: @sourceless
GH: sourceless
HN: sourceless L: laurencejosephsmith

+

E: laurence@[this website]\ T: @sourceless\ GH: sourceless\ HN: sourceless\ L: laurencejosephsmith

From 9be3381c013467828fc8361a4e78f677196fd8d0 Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Thu, 7 Jul 2022 08:58:07 +0000 Subject: [PATCH 20/43] www-build-25 --- index.html | 2 ++ posts/perfect-isnt-good-enough.html | 2 ++ posts/the-continuous-delivery-test.html | 40 +++++++++++++++++++++++++ 3 files changed, 44 insertions(+) create mode 100644 posts/the-continuous-delivery-test.html diff --git a/index.html b/index.html index 50fb600..1e8b419 100644 --- a/index.html +++ b/index.html @@ -29,6 +29,8 @@

sourceless



+ 2022-07-07 The Continuous Delivery Test
+ 2022-06-22 Perfect isn't Good Enough
2022-06-19 Relearning to Learn
diff --git a/posts/perfect-isnt-good-enough.html b/posts/perfect-isnt-good-enough.html index 45cb5bc..9c7362d 100644 --- a/posts/perfect-isnt-good-enough.html +++ b/posts/perfect-isnt-good-enough.html @@ -34,6 +34,8 @@

Perfect isn't Good Enough

Perfect is the enemy of the go ← Relearning to Learn +The Continuous Delivery Test → + diff --git a/posts/the-continuous-delivery-test.html b/posts/the-continuous-delivery-test.html new file mode 100644 index 0000000..0dab47c --- /dev/null +++ b/posts/the-continuous-delivery-test.html @@ -0,0 +1,40 @@ + + + + + Sourceless - The Continuous Delivery Test + + + + + + + + + + + + +

sourceless

+ + +index + + about + + contact + + +

The Continuous Delivery Test

In 2000, Joel Spolsky published an piece on what he believed were the key factors that separated high-performing teams from the rest, in a post titled The Joel Test: 12 Steps to Better Code. It contains many insights that are still useful to this day; however, the world, software, and the teams that make it have moved on in the nearly 22 years since that post.

In 2015, John Kodumal of LaunchDarkly published an updated Joel Test for Continuous Delivery. While being far more up-to-date, it's still slipped a little in relevance.

If this post were to have an alternate title, it'd be 'Front-load Your Risks'. All of the advices below seeks to move risks away from the act of deployment and move them to earlier steps of the development process.

So, here's my best shot at a CI/CD Joel Test for the 2020s.

1. Do you use a distributed version control system?

Git, GitHub, and the ecosystems around them have eaten the software world, and for good reason. Beyond the usual advantages - branching, merging, and easy rollbacks, many of these hosted git servers now come with a whole slew of other productivity tooling.

Especially notable are those that move your CI closer to your source code, such as GitHub Actions, and GitLab CI/CD.

2. Do you practice trunk-based development?

Trunk-based development rolls up a bunch of good practices under one system.

It forces you to have one good main branch that is always deployable (and by implication, always able to roll back), and encourages merging small features in one at a time.

3. Do you merge little and often?

It's been known for some time now that large pull requests tend to get cursory reviews at best. On top of this, squirreling away to work on a single feature for a long time means you are not spending adequate time making sure that you are building the right thing!

This also means using small, ticket-scoped feature branches, where the changes have a very tight scope.

4. Do two people read code before it is merged?

You'll notice I was very careful to avoid mentioning how this should take place. For some, pull requests are the right tool, but pairing and mob programming are also sufficient.

Nobody should be solely responsible for any code.

5. Do you require changes to pass checks before they can be merged?

One of the leading causes of outages is deployments. You should do your best to make sure that broken code never gets deployed in the first place.

6. Can you test your changes in a production-like environment before you deploy it?

There are many ways to go about this. You could spin up a small clone of your production env, run the tests, and then kill it, or where this is not possible, you can run tests against mirrored traffic, or even run a canary.

7. Do you have a main branch that is always deployable?

This is possibly the most important takeaway (and it's present in the 2015 circleci post referenced above!). Having an always-deployable main will make deploys boring.

In a good way.

8. Do you deploy to production as soon as main is updated?

Your deploy should be automated and happen right upon merge. This removes a burden from the team delivering a product and allows them to focus on features and reliability rather than long-winded release ceremonies.

9. Does your deploy process self-heal?

When a deployment fails, can you roll back automatically? In addition to this, you should be able to roll back manually where necessary (though it's generally best to fail forwards!)

This also necessitates the use of blue-green deploys, canarying, healthchecks, and myriad other strategies to mitigate outage risk. It's very powerful to be able to turn a possible outage into a mere degredation.

10. Does your Infrastructure as Code live alongside the service it hosts?

It's a good idea to colocate any IaC with the software it's running rather than keeping the two in separate repositories. This dodges any dependency management between the two, and in many cases will save you a pipeline or two.

It's an antipattern (in the author's opinion) to have all infrastructure code completely separate from

11. Do you use feature flags?

Releases are a terrible mechanism for launching new features. You want to be able to run that shiny new feature in production as soon as possible, and you can't do that if you conflate a feature's launch with its release. This also means that you can preview and refine changes with flagship customers before rolling them out more widely.

12. Do you include ticket ids in your commits or branches?

You need to be able to tie every commit back to the ticket that spawned it. It might not be you debugging a change that you merged, so it needs to be really easy to go back and find out why something was changed in order to make the right decision to fix it.

13. Can you still deploy from your own machine?

A key factor in developing software and infrastructure quickly is tight feedback loops. While it's probably not a great idea to be deploying directly to production from your own machine, having the ability to might be useful in a pinch, too.

You should be able to deploy to a dev environment (shared or ephemeral) so that you can easily validate your work in situ.

14. Do you have at least one path to live environment?

Posts before this one have asked if you've had a staging environment – and at the very least you should have one prod-like pre-prod environment to validate changes in.

+
+ Posted 2022-07-07 +
+
+ +← Perfect isn't Good Enough + + + +
+ + From 574b35072f3aafaaf950b50b221bd83e143c59ac Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Thu, 7 Jul 2022 09:02:57 +0000 Subject: [PATCH 21/43] www-build-26 --- posts/the-continuous-delivery-test.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/posts/the-continuous-delivery-test.html b/posts/the-continuous-delivery-test.html index 0dab47c..c45b0e6 100644 --- a/posts/the-continuous-delivery-test.html +++ b/posts/the-continuous-delivery-test.html @@ -25,7 +25,7 @@

sourceless

contact -

The Continuous Delivery Test

In 2000, Joel Spolsky published an piece on what he believed were the key factors that separated high-performing teams from the rest, in a post titled The Joel Test: 12 Steps to Better Code. It contains many insights that are still useful to this day; however, the world, software, and the teams that make it have moved on in the nearly 22 years since that post.

In 2015, John Kodumal of LaunchDarkly published an updated Joel Test for Continuous Delivery. While being far more up-to-date, it's still slipped a little in relevance.

If this post were to have an alternate title, it'd be 'Front-load Your Risks'. All of the advices below seeks to move risks away from the act of deployment and move them to earlier steps of the development process.

So, here's my best shot at a CI/CD Joel Test for the 2020s.

1. Do you use a distributed version control system?

Git, GitHub, and the ecosystems around them have eaten the software world, and for good reason. Beyond the usual advantages - branching, merging, and easy rollbacks, many of these hosted git servers now come with a whole slew of other productivity tooling.

Especially notable are those that move your CI closer to your source code, such as GitHub Actions, and GitLab CI/CD.

2. Do you practice trunk-based development?

Trunk-based development rolls up a bunch of good practices under one system.

It forces you to have one good main branch that is always deployable (and by implication, always able to roll back), and encourages merging small features in one at a time.

3. Do you merge little and often?

It's been known for some time now that large pull requests tend to get cursory reviews at best. On top of this, squirreling away to work on a single feature for a long time means you are not spending adequate time making sure that you are building the right thing!

This also means using small, ticket-scoped feature branches, where the changes have a very tight scope.

4. Do two people read code before it is merged?

You'll notice I was very careful to avoid mentioning how this should take place. For some, pull requests are the right tool, but pairing and mob programming are also sufficient.

Nobody should be solely responsible for any code.

5. Do you require changes to pass checks before they can be merged?

One of the leading causes of outages is deployments. You should do your best to make sure that broken code never gets deployed in the first place.

6. Can you test your changes in a production-like environment before you deploy it?

There are many ways to go about this. You could spin up a small clone of your production env, run the tests, and then kill it, or where this is not possible, you can run tests against mirrored traffic, or even run a canary.

7. Do you have a main branch that is always deployable?

This is possibly the most important takeaway (and it's present in the 2015 circleci post referenced above!). Having an always-deployable main will make deploys boring.

In a good way.

8. Do you deploy to production as soon as main is updated?

Your deploy should be automated and happen right upon merge. This removes a burden from the team delivering a product and allows them to focus on features and reliability rather than long-winded release ceremonies.

9. Does your deploy process self-heal?

When a deployment fails, can you roll back automatically? In addition to this, you should be able to roll back manually where necessary (though it's generally best to fail forwards!)

This also necessitates the use of blue-green deploys, canarying, healthchecks, and myriad other strategies to mitigate outage risk. It's very powerful to be able to turn a possible outage into a mere degredation.

10. Does your Infrastructure as Code live alongside the service it hosts?

It's a good idea to colocate any IaC with the software it's running rather than keeping the two in separate repositories. This dodges any dependency management between the two, and in many cases will save you a pipeline or two.

It's an antipattern (in the author's opinion) to have all infrastructure code completely separate from

11. Do you use feature flags?

Releases are a terrible mechanism for launching new features. You want to be able to run that shiny new feature in production as soon as possible, and you can't do that if you conflate a feature's launch with its release. This also means that you can preview and refine changes with flagship customers before rolling them out more widely.

12. Do you include ticket ids in your commits or branches?

You need to be able to tie every commit back to the ticket that spawned it. It might not be you debugging a change that you merged, so it needs to be really easy to go back and find out why something was changed in order to make the right decision to fix it.

13. Can you still deploy from your own machine?

A key factor in developing software and infrastructure quickly is tight feedback loops. While it's probably not a great idea to be deploying directly to production from your own machine, having the ability to might be useful in a pinch, too.

You should be able to deploy to a dev environment (shared or ephemeral) so that you can easily validate your work in situ.

14. Do you have at least one path to live environment?

Posts before this one have asked if you've had a staging environment – and at the very least you should have one prod-like pre-prod environment to validate changes in.

+

The Continuous Delivery Test

In 2000, Joel Spolsky published an piece on what he believed were the key factors that separated high-performing teams from the rest, in a post titled The Joel Test: 12 Steps to Better Code. It contains many insights that are still useful to this day; however, the world, software, and the teams that make it have moved on in the nearly 22 years since that post.

In 2015, John Kodumal of LaunchDarkly published an updated Joel Test for Continuous Delivery. While being far more up-to-date, it's still slipped a little in relevance.

If this post were to have an alternate title, it'd be 'Front-load Your Risks'. All of the advices below seeks to move risks away from the act of deployment and move them to earlier steps of the development process.

So, here's my best shot at a CI/CD Joel Test for the 2020s.

1. Do you use a distributed version control system?

Git, GitHub, and the ecosystems around them have eaten the software world, and for good reason. Beyond the usual advantages - branching, merging, and easy rollbacks, many of these hosted git servers now come with a whole slew of other productivity tooling.

Especially notable are those that move your CI closer to your source code, such as GitHub Actions, and GitLab CI/CD.

2. Do you practice trunk-based development?

Trunk-based development rolls up a bunch of good practices under one system.

It forces you to have one good main branch that is always deployable (and by implication, always able to roll back), and encourages merging small features in one at a time.

3. Do you merge little and often?

It's been known for some time now that large pull requests tend to get cursory reviews at best. On top of this, squirreling away to work on a single feature for a long time means you are not spending adequate time making sure that you are building the right thing!

This also means using small, ticket-scoped feature branches, where the changes have a very tight scope.

4. Do two people read code before it is merged?

You'll notice I was very careful to avoid mentioning how this should take place. For some, pull requests are the right tool, but pairing and mob programming are also sufficient.

Nobody should be solely responsible for any code.

5. Do you require changes to pass checks before they can be merged?

One of the leading causes of outages is deployments. You should do your best to make sure that broken code never gets deployed in the first place.

6. Can you test your changes in a production-like environment before you deploy it?

There are many ways to go about this. You could spin up a small clone of your production env, run the tests, and then kill it, or where this is not possible, you can run tests against mirrored traffic, or even run a canary.

7. Do you have a main branch that is always deployable?

This is possibly the most important takeaway (and it's present in the 2015 circleci post referenced above!). Having an always-deployable main will make deploys boring.

In a good way.

8. Do you deploy to production as soon as main is updated?

Your deploy should be automated and happen right upon merge. This removes a burden from the team delivering a product and allows them to focus on features and reliability rather than long-winded release ceremonies.

9. Does your deploy process self-heal?

When a deployment fails, can you roll back automatically? In addition to this, you should be able to roll back manually where necessary (though it's generally best to fail forwards!)

This also necessitates the use of blue-green deploys, canarying, healthchecks, and myriad other strategies to mitigate outage risk. It's very powerful to be able to turn a possible outage into a mere degredation.

10. Does your Infrastructure as Code live alongside the service it hosts?

It's a good idea to colocate any IaC with the software it's running rather than keeping the two in separate repositories. This dodges any dependency management between the two, and in many cases will save you a pipeline or two.

It's an antipattern (in the author's opinion) to have all infrastructure code completely separate from

11. Do you use feature flags?

Releases are a terrible mechanism for launching new features. You want to be able to run that shiny new feature in production as soon as possible, and you can't do that if you conflate a feature's launch with its release. This also means that you can preview and refine changes with flagship customers before rolling them out more widely.

12. Do you include ticket ids in your commits or branches?

You need to be able to tie every commit back to the ticket that spawned it. It might not be you debugging a change that you merged, so it needs to be really easy to go back and find out why something was changed in order to make the right decision to fix it.

13. Can you still deploy from your own machine?

A key factor in developing software and infrastructure quickly is tight feedback loops. While it's probably not a great idea to be deploying directly to production from your own machine, having the ability to might be useful in a pinch, too.

You should be able to deploy to a dev environment (shared or ephemeral) so that you can easily validate your work in situ.


Posted 2022-07-07
From 51e6230e18710d82b104343590ff83e33fbc7d6d Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Thu, 7 Jul 2022 09:06:46 +0000 Subject: [PATCH 22/43] www-build-27 --- posts/the-continuous-delivery-test.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/posts/the-continuous-delivery-test.html b/posts/the-continuous-delivery-test.html index c45b0e6..159481d 100644 --- a/posts/the-continuous-delivery-test.html +++ b/posts/the-continuous-delivery-test.html @@ -25,7 +25,7 @@

sourceless

contact -

The Continuous Delivery Test

In 2000, Joel Spolsky published an piece on what he believed were the key factors that separated high-performing teams from the rest, in a post titled The Joel Test: 12 Steps to Better Code. It contains many insights that are still useful to this day; however, the world, software, and the teams that make it have moved on in the nearly 22 years since that post.

In 2015, John Kodumal of LaunchDarkly published an updated Joel Test for Continuous Delivery. While being far more up-to-date, it's still slipped a little in relevance.

If this post were to have an alternate title, it'd be 'Front-load Your Risks'. All of the advices below seeks to move risks away from the act of deployment and move them to earlier steps of the development process.

So, here's my best shot at a CI/CD Joel Test for the 2020s.

1. Do you use a distributed version control system?

Git, GitHub, and the ecosystems around them have eaten the software world, and for good reason. Beyond the usual advantages - branching, merging, and easy rollbacks, many of these hosted git servers now come with a whole slew of other productivity tooling.

Especially notable are those that move your CI closer to your source code, such as GitHub Actions, and GitLab CI/CD.

2. Do you practice trunk-based development?

Trunk-based development rolls up a bunch of good practices under one system.

It forces you to have one good main branch that is always deployable (and by implication, always able to roll back), and encourages merging small features in one at a time.

3. Do you merge little and often?

It's been known for some time now that large pull requests tend to get cursory reviews at best. On top of this, squirreling away to work on a single feature for a long time means you are not spending adequate time making sure that you are building the right thing!

This also means using small, ticket-scoped feature branches, where the changes have a very tight scope.

4. Do two people read code before it is merged?

You'll notice I was very careful to avoid mentioning how this should take place. For some, pull requests are the right tool, but pairing and mob programming are also sufficient.

Nobody should be solely responsible for any code.

5. Do you require changes to pass checks before they can be merged?

One of the leading causes of outages is deployments. You should do your best to make sure that broken code never gets deployed in the first place.

6. Can you test your changes in a production-like environment before you deploy it?

There are many ways to go about this. You could spin up a small clone of your production env, run the tests, and then kill it, or where this is not possible, you can run tests against mirrored traffic, or even run a canary.

7. Do you have a main branch that is always deployable?

This is possibly the most important takeaway (and it's present in the 2015 circleci post referenced above!). Having an always-deployable main will make deploys boring.

In a good way.

8. Do you deploy to production as soon as main is updated?

Your deploy should be automated and happen right upon merge. This removes a burden from the team delivering a product and allows them to focus on features and reliability rather than long-winded release ceremonies.

9. Does your deploy process self-heal?

When a deployment fails, can you roll back automatically? In addition to this, you should be able to roll back manually where necessary (though it's generally best to fail forwards!)

This also necessitates the use of blue-green deploys, canarying, healthchecks, and myriad other strategies to mitigate outage risk. It's very powerful to be able to turn a possible outage into a mere degredation.

10. Does your Infrastructure as Code live alongside the service it hosts?

It's a good idea to colocate any IaC with the software it's running rather than keeping the two in separate repositories. This dodges any dependency management between the two, and in many cases will save you a pipeline or two.

It's an antipattern (in the author's opinion) to have all infrastructure code completely separate from

11. Do you use feature flags?

Releases are a terrible mechanism for launching new features. You want to be able to run that shiny new feature in production as soon as possible, and you can't do that if you conflate a feature's launch with its release. This also means that you can preview and refine changes with flagship customers before rolling them out more widely.

12. Do you include ticket ids in your commits or branches?

You need to be able to tie every commit back to the ticket that spawned it. It might not be you debugging a change that you merged, so it needs to be really easy to go back and find out why something was changed in order to make the right decision to fix it.

13. Can you still deploy from your own machine?

A key factor in developing software and infrastructure quickly is tight feedback loops. While it's probably not a great idea to be deploying directly to production from your own machine, having the ability to might be useful in a pinch, too.

You should be able to deploy to a dev environment (shared or ephemeral) so that you can easily validate your work in situ.

+

The Continuous Delivery Test

In 2000, Joel Spolsky published an piece on what he believed were the key factors that separated high-performing teams from the rest, in a post titled The Joel Test: 12 Steps to Better Code. It contains many insights that are still useful to this day; however, the world, software, and the teams that make it have moved on in the nearly 22 years since that post.

In 2015, John Kodumal of LaunchDarkly published an updated Joel Test for Continuous Delivery. While being far more up-to-date, it's still slipped a little in relevance.

If this post were to have an alternate title, it'd be 'Front-load Your Risks'. All of the advice below seeks to move risks away from the act of deployment and move them to earlier steps of the development process.

So, here's my best shot at a CI/CD Joel Test for the 2020s.

1. Do you use a distributed version control system?

Git, GitHub, and the ecosystems around them have eaten the software world, and for good reason. Beyond the usual advantages - branching, merging, and easy rollbacks, many of these hosted git servers now come with a whole slew of other productivity tooling.

Especially notable are those that move your CI closer to your source code, such as GitHub Actions, and GitLab CI/CD.

2. Do you practice trunk-based development?

Trunk-based development rolls up a bunch of good practices under one system.

It forces you to have one good main branch that is always deployable (and by implication, always able to roll back), and encourages merging small features in one at a time.

3. Do you merge little and often?

It's been known for some time now that large pull requests tend to get cursory reviews at best. On top of this, squirreling away to work on a single feature for a long time means you are not spending adequate time making sure that you are building the right thing!

This also means using small, ticket-scoped feature branches, where the changes have a very tight scope.

4. Do two people read code before it is merged?

You'll notice I was very careful to avoid mentioning how this should take place. For some, pull requests are the right tool, but pairing and mob programming are also sufficient.

Nobody should be solely responsible for any code.

5. Do you require changes to pass checks before they can be merged?

One of the leading causes of outages is deployments. You should do your best to make sure that broken code never gets deployed in the first place.

6. Can you test your changes in a production-like environment before you deploy it?

There are many ways to go about this. You could spin up a small clone of your production env, run the tests, and then kill it, or where this is not possible, you can run tests against mirrored traffic, or even run a canary.

7. Do you have a main branch that is always deployable?

This is possibly the most important takeaway (and it's present in the 2015 circleci post referenced above!). Having an always-deployable main will make deploys boring.

In a good way.

8. Do you deploy to production as soon as main is updated?

Your deploy should be automated and happen right upon merge. This removes a burden from the team delivering a product and allows them to focus on features and reliability rather than long-winded release ceremonies.

9. Does your deploy process self-heal?

When a deployment fails, can you roll back automatically? In addition to this, you should be able to roll back manually where necessary (though it's generally best to fail forwards!)

This also necessitates the use of blue-green deploys, canarying, healthchecks, and myriad other strategies to mitigate outage risk. It's very powerful to be able to turn a possible outage into a mere degradation.

10. Does your Infrastructure as Code live alongside the service it hosts?

It's a good idea to colocate any IaC with the software it's running rather than keeping the two in separate repositories. This dodges any dependency management between the two, and in many cases will save you a pipeline or two.

It's an antipattern (in the author's opinion) to have all infrastructure code completely separate from

11. Do you use feature flags?

Releases are a terrible mechanism for launching new features. You want to be able to run that shiny new feature in production as soon as possible, and you can't do that if you conflate a feature's launch with its release. This also means that you can preview and refine changes with flagship customers before rolling them out more widely.

12. Do you include ticket IDs in your commits or branches?

You need to be able to tie every commit back to the ticket that spawned it. It might not be you debugging a change that you merged, so it needs to be really easy to go back and find out why something was changed in order to make the right decision to fix it.

13. Can you still deploy from your own machine?

A key factor in developing software and infrastructure quickly is tight feedback loops. While it's probably not a great idea to be deploying directly to production from your own machine, having the ability to might be useful in a pinch, too.

You should be able to deploy to a dev environment (shared or ephemeral) so that you can easily validate your work in situ.


Posted 2022-07-07
From bfd27c9fd8f395db9dd33abb80f4933b3c2ede0d Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Thu, 7 Jul 2022 11:53:49 +0000 Subject: [PATCH 23/43] www-build-28 --- posts/the-continuous-delivery-test.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/posts/the-continuous-delivery-test.html b/posts/the-continuous-delivery-test.html index 159481d..ccbe1f1 100644 --- a/posts/the-continuous-delivery-test.html +++ b/posts/the-continuous-delivery-test.html @@ -25,7 +25,7 @@

sourceless

contact -

The Continuous Delivery Test

In 2000, Joel Spolsky published an piece on what he believed were the key factors that separated high-performing teams from the rest, in a post titled The Joel Test: 12 Steps to Better Code. It contains many insights that are still useful to this day; however, the world, software, and the teams that make it have moved on in the nearly 22 years since that post.

In 2015, John Kodumal of LaunchDarkly published an updated Joel Test for Continuous Delivery. While being far more up-to-date, it's still slipped a little in relevance.

If this post were to have an alternate title, it'd be 'Front-load Your Risks'. All of the advice below seeks to move risks away from the act of deployment and move them to earlier steps of the development process.

So, here's my best shot at a CI/CD Joel Test for the 2020s.

1. Do you use a distributed version control system?

Git, GitHub, and the ecosystems around them have eaten the software world, and for good reason. Beyond the usual advantages - branching, merging, and easy rollbacks, many of these hosted git servers now come with a whole slew of other productivity tooling.

Especially notable are those that move your CI closer to your source code, such as GitHub Actions, and GitLab CI/CD.

2. Do you practice trunk-based development?

Trunk-based development rolls up a bunch of good practices under one system.

It forces you to have one good main branch that is always deployable (and by implication, always able to roll back), and encourages merging small features in one at a time.

3. Do you merge little and often?

It's been known for some time now that large pull requests tend to get cursory reviews at best. On top of this, squirreling away to work on a single feature for a long time means you are not spending adequate time making sure that you are building the right thing!

This also means using small, ticket-scoped feature branches, where the changes have a very tight scope.

4. Do two people read code before it is merged?

You'll notice I was very careful to avoid mentioning how this should take place. For some, pull requests are the right tool, but pairing and mob programming are also sufficient.

Nobody should be solely responsible for any code.

5. Do you require changes to pass checks before they can be merged?

One of the leading causes of outages is deployments. You should do your best to make sure that broken code never gets deployed in the first place.

6. Can you test your changes in a production-like environment before you deploy it?

There are many ways to go about this. You could spin up a small clone of your production env, run the tests, and then kill it, or where this is not possible, you can run tests against mirrored traffic, or even run a canary.

7. Do you have a main branch that is always deployable?

This is possibly the most important takeaway (and it's present in the 2015 circleci post referenced above!). Having an always-deployable main will make deploys boring.

In a good way.

8. Do you deploy to production as soon as main is updated?

Your deploy should be automated and happen right upon merge. This removes a burden from the team delivering a product and allows them to focus on features and reliability rather than long-winded release ceremonies.

9. Does your deploy process self-heal?

When a deployment fails, can you roll back automatically? In addition to this, you should be able to roll back manually where necessary (though it's generally best to fail forwards!)

This also necessitates the use of blue-green deploys, canarying, healthchecks, and myriad other strategies to mitigate outage risk. It's very powerful to be able to turn a possible outage into a mere degradation.

10. Does your Infrastructure as Code live alongside the service it hosts?

It's a good idea to colocate any IaC with the software it's running rather than keeping the two in separate repositories. This dodges any dependency management between the two, and in many cases will save you a pipeline or two.

It's an antipattern (in the author's opinion) to have all infrastructure code completely separate from

11. Do you use feature flags?

Releases are a terrible mechanism for launching new features. You want to be able to run that shiny new feature in production as soon as possible, and you can't do that if you conflate a feature's launch with its release. This also means that you can preview and refine changes with flagship customers before rolling them out more widely.

12. Do you include ticket IDs in your commits or branches?

You need to be able to tie every commit back to the ticket that spawned it. It might not be you debugging a change that you merged, so it needs to be really easy to go back and find out why something was changed in order to make the right decision to fix it.

13. Can you still deploy from your own machine?

A key factor in developing software and infrastructure quickly is tight feedback loops. While it's probably not a great idea to be deploying directly to production from your own machine, having the ability to might be useful in a pinch, too.

You should be able to deploy to a dev environment (shared or ephemeral) so that you can easily validate your work in situ.

+

The Continuous Delivery Test

In 2000, Joel Spolsky published an piece on what he believed were the key factors that separated high-performing teams from the rest, in a post titled The Joel Test: 12 Steps to Better Code. It contains many insights that are still useful to this day; however, the world, software, and the teams that make it have moved on in the nearly 22 years since that post.

In 2015, John Kodumal of LaunchDarkly published an updated Joel Test for Continuous Delivery. While being far more up-to-date, it's still slipped a little in relevance.

If this post were to have an alternate title, it'd be 'Front-load Your Risks'. All of the advice below seeks to move risks away from the act of deployment and move them to earlier steps of the development process.

So, here's my best shot at a CI/CD Joel Test for the 2020s.

1. Do you use a distributed version control system?

Git, GitHub, and the ecosystems around them have eaten the software world, and for good reason. Beyond the usual advantages - branching, merging, and easy rollbacks, many of these hosted git servers now come with a whole slew of other productivity tooling.

Especially notable are those that move your CI closer to your source code, such as GitHub Actions, and GitLab CI/CD.

2. Do you practice trunk-based development?

Trunk-based development rolls up a bunch of good practices under one system.

It forces you to have one good main branch that is always deployable (and by implication, always able to roll back), and encourages merging small features in one at a time.

Having an always-deployable main means that your deploy process becomes a lot more boring (which is great!), and is often indicative of a process that supports developers, rather than requiring long hours spent resolving merge conflicts and preparing release notes.

3. Do you merge little and often?

It's been known for some time now that large pull requests tend to get cursory reviews at best. On top of this, squirreling away to work on a single feature for a long time means you are not spending adequate time making sure that you are building the right thing!

This also means using small, ticket-scoped feature branches, where the changes have a very tight scope.

4. Do two people read code before it is merged?

You'll notice I was very careful to avoid mentioning how this should take place. For some, pull requests are the right tool, but pairing and mob programming are also sufficient.

Nobody should be solely responsible for any code.

5. Do you require changes to pass checks before they can be merged?

One of the leading causes of outages is deployments. You should do your best to make sure that broken code never gets deployed in the first place.

6. Can you test your changes in a production-like environment before you deploy it?

There are many ways to go about this. You could spin up a small clone of your production env, run the tests, and then kill it, or where this is not possible, you can run tests against mirrored traffic, or even run a canary.

7. Do you deploy to production as soon as main is updated?

Your deploy should be automated and happen right upon merge. This removes a burden from the team delivering a product and allows them to focus on features and reliability rather than long-winded release ceremonies. It can be hard to get here from releasing once a day, week, etc. – a mature approach to managing the risks of deployment is required, as well as battle-tested deploy processes and tools.

The earlier you start doing this, the easier it will be.

8. Does your deploy process self-heal?

When a deployment fails, can you roll back automatically? In addition to this, you should be able to roll back manually where necessary (though it's generally best to fail forwards!)

This also necessitates the use of blue-green deploys, canarying, healthchecks, and myriad other strategies to mitigate outage risk. It's very powerful to be able to turn a possible outage into a mere degradation.

9. Does your Infrastructure as Code live alongside the service it hosts?

It's a good idea to colocate any IaC with the software it's running rather than keeping the two in separate repositories. This dodges any dependency management between the two, and in many cases will save you a pipeline or two.

It's an antipattern (in the author's opinion) to have all infrastructure code completely separate from the application it supports. Common or shared infrastructure could be argued to have its own place, but a product should have all its pieces as close together as possible.

Monorepos are an extreme example of this philosophy.

10. Do you use feature flags?

Releases are a terrible mechanism for launching new features. You want to be able to run that shiny new feature in production as soon as possible, and you can't do that if you conflate a feature's launch with its release. This also means that you can preview and refine changes with flagship customers before rolling them out more widely.

11. Do you include ticket IDs in your commits or branches?

You need to be able to tie every commit back to the ticket that spawned it. It might not be you debugging a change that you merged, so it needs to be really easy to go back and find out why something was changed in order to make the right decision to fix it.

13. Can you still deploy from your own machine?

A key factor in developing software and infrastructure quickly is tight feedback loops. While it's probably not a great idea to be deploying directly to production from your own machine, having the ability to might be useful in a pinch, too.

You should be able to deploy to a dev environment (shared or ephemeral) so that you can easily validate your work in situ.


Posted 2022-07-07
From f859c12558ffe6a6f2fa416aaa6a2704b5e86d1f Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Thu, 7 Jul 2022 11:57:55 +0000 Subject: [PATCH 24/43] www-build-29 --- posts/the-continuous-delivery-test.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/posts/the-continuous-delivery-test.html b/posts/the-continuous-delivery-test.html index ccbe1f1..ebc250f 100644 --- a/posts/the-continuous-delivery-test.html +++ b/posts/the-continuous-delivery-test.html @@ -25,7 +25,7 @@

sourceless

contact -

The Continuous Delivery Test

In 2000, Joel Spolsky published an piece on what he believed were the key factors that separated high-performing teams from the rest, in a post titled The Joel Test: 12 Steps to Better Code. It contains many insights that are still useful to this day; however, the world, software, and the teams that make it have moved on in the nearly 22 years since that post.

In 2015, John Kodumal of LaunchDarkly published an updated Joel Test for Continuous Delivery. While being far more up-to-date, it's still slipped a little in relevance.

If this post were to have an alternate title, it'd be 'Front-load Your Risks'. All of the advice below seeks to move risks away from the act of deployment and move them to earlier steps of the development process.

So, here's my best shot at a CI/CD Joel Test for the 2020s.

1. Do you use a distributed version control system?

Git, GitHub, and the ecosystems around them have eaten the software world, and for good reason. Beyond the usual advantages - branching, merging, and easy rollbacks, many of these hosted git servers now come with a whole slew of other productivity tooling.

Especially notable are those that move your CI closer to your source code, such as GitHub Actions, and GitLab CI/CD.

2. Do you practice trunk-based development?

Trunk-based development rolls up a bunch of good practices under one system.

It forces you to have one good main branch that is always deployable (and by implication, always able to roll back), and encourages merging small features in one at a time.

Having an always-deployable main means that your deploy process becomes a lot more boring (which is great!), and is often indicative of a process that supports developers, rather than requiring long hours spent resolving merge conflicts and preparing release notes.

3. Do you merge little and often?

It's been known for some time now that large pull requests tend to get cursory reviews at best. On top of this, squirreling away to work on a single feature for a long time means you are not spending adequate time making sure that you are building the right thing!

This also means using small, ticket-scoped feature branches, where the changes have a very tight scope.

4. Do two people read code before it is merged?

You'll notice I was very careful to avoid mentioning how this should take place. For some, pull requests are the right tool, but pairing and mob programming are also sufficient.

Nobody should be solely responsible for any code.

5. Do you require changes to pass checks before they can be merged?

One of the leading causes of outages is deployments. You should do your best to make sure that broken code never gets deployed in the first place.

6. Can you test your changes in a production-like environment before you deploy it?

There are many ways to go about this. You could spin up a small clone of your production env, run the tests, and then kill it, or where this is not possible, you can run tests against mirrored traffic, or even run a canary.

7. Do you deploy to production as soon as main is updated?

Your deploy should be automated and happen right upon merge. This removes a burden from the team delivering a product and allows them to focus on features and reliability rather than long-winded release ceremonies. It can be hard to get here from releasing once a day, week, etc. – a mature approach to managing the risks of deployment is required, as well as battle-tested deploy processes and tools.

The earlier you start doing this, the easier it will be.

8. Does your deploy process self-heal?

When a deployment fails, can you roll back automatically? In addition to this, you should be able to roll back manually where necessary (though it's generally best to fail forwards!)

This also necessitates the use of blue-green deploys, canarying, healthchecks, and myriad other strategies to mitigate outage risk. It's very powerful to be able to turn a possible outage into a mere degradation.

9. Does your Infrastructure as Code live alongside the service it hosts?

It's a good idea to colocate any IaC with the software it's running rather than keeping the two in separate repositories. This dodges any dependency management between the two, and in many cases will save you a pipeline or two.

It's an antipattern (in the author's opinion) to have all infrastructure code completely separate from the application it supports. Common or shared infrastructure could be argued to have its own place, but a product should have all its pieces as close together as possible.

Monorepos are an extreme example of this philosophy.

10. Do you use feature flags?

Releases are a terrible mechanism for launching new features. You want to be able to run that shiny new feature in production as soon as possible, and you can't do that if you conflate a feature's launch with its release. This also means that you can preview and refine changes with flagship customers before rolling them out more widely.

11. Do you include ticket IDs in your commits or branches?

You need to be able to tie every commit back to the ticket that spawned it. It might not be you debugging a change that you merged, so it needs to be really easy to go back and find out why something was changed in order to make the right decision to fix it.

13. Can you still deploy from your own machine?

A key factor in developing software and infrastructure quickly is tight feedback loops. While it's probably not a great idea to be deploying directly to production from your own machine, having the ability to might be useful in a pinch, too.

You should be able to deploy to a dev environment (shared or ephemeral) so that you can easily validate your work in situ.

+

The Continuous Delivery Test

In 2000, Joel Spolsky published an piece on what he believed were the key factors that separated high-performing teams from the rest, in a post titled The Joel Test: 12 Steps to Better Code. It contains many insights that are still useful to this day; however, the world, software, and the teams that make it have moved on in the nearly 22 years since that post.

In 2015, John Kodumal of LaunchDarkly published an updated Joel Test for Continuous Delivery. While being far more up-to-date, it's still slipped a little in relevance.

If this post were to have an alternate title, it'd be 'Front-load Your Risks'. All of the advice below seeks to move risks away from the act of deployment and move them to earlier steps of the development process.

So, here's my best shot at a CI/CD Joel Test for the 2020s.

1. Do you use a distributed version control system?

Git, GitHub, and the ecosystems around them have eaten the software world, and for good reason. Beyond the usual advantages - branching, merging, and easy rollbacks, many of these hosted git servers now come with a whole slew of other productivity tooling.

Especially notable are those that move your CI closer to your source code, such as GitHub Actions, and GitLab CI/CD.

2. Do you practice trunk-based development?

Trunk-based development rolls up a bunch of good practices under one system.

It forces you to have one good main branch that is always deployable (and by implication, always able to roll back), and encourages merging small features in one at a time.

Having an always-deployable main means that your deploy process becomes a lot more boring (which is great!), and is often indicative of a process that supports developers, rather than requiring long hours spent resolving merge conflicts and preparing release notes.

3. Do you merge little and often?

It's been known for some time now that large pull requests tend to get cursory reviews at best. On top of this, squirreling away to work on a single feature for a long time means you are not spending adequate time making sure that you are building the right thing!

This also means using small, ticket-scoped feature branches, where the changes have a very tight scope.

4. Do two people read code before it is merged?

You'll notice I was very careful to avoid mentioning how this should take place. For some, pull requests are the right tool, but pairing and mob programming are also sufficient.

Nobody should be solely responsible for any code.

5. Do you require changes to pass checks before they can be merged?

One of the leading causes of outages is deployments. You should do your best to make sure that broken code never gets deployed in the first place.

6. Can you test your changes in a production-like environment before you deploy it?

There are many ways to go about this. You could spin up a small clone of your production env, run the tests, and then kill it, or where this is not possible, you can run tests against mirrored traffic, or even run a canary.

7. Do you deploy to production as soon as main is updated?

Your deploy should be automated and happen right upon merge. This removes a burden from the team delivering a product and allows them to focus on features and reliability rather than long-winded release ceremonies. It can be hard to get here from releasing once a day, week, etc. – a mature approach to managing the risks of deployment is required, as well as battle-tested deploy processes and tools.

The earlier you start doing this, the easier it will be.

8. Does your deploy process self-heal?

When a deployment fails, can you roll back automatically? In addition to this, you should be able to roll back manually where necessary (though it's generally best to fail forwards!)

This also necessitates the use of blue-green deploys, canarying, healthchecks, and myriad other strategies to mitigate outage risk. It's very powerful to be able to turn a possible outage into a mere degradation.

9. Does your Infrastructure as Code live alongside the service it hosts?

It's a good idea to colocate any IaC with the software it's running rather than keeping the two in separate repositories. This dodges any dependency management between the two, and in many cases will save you a pipeline or two.

It's an antipattern (in the author's opinion) to have all infrastructure code completely separate from the application it supports. Common or shared infrastructure could be argued to have its own place, but a product should have all its pieces as close together as possible.

Monorepos are an extreme example of this philosophy.

10. Do you use feature flags?

Releases are a terrible mechanism for launching new features. You want to be able to run that shiny new feature in production as soon as possible, and you can't do that if you conflate a feature's launch with its release. This also means that you can preview and refine changes with flagship customers before rolling them out more widely.

11. Do you include ticket IDs in your commits or branches?

You need to be able to tie every commit back to the ticket that spawned it. It might not be you debugging a change that you merged, so it needs to be really easy to go back and find out why something was changed in order to make the right decision to fix it.

12. Can you still deploy from your own machine?

A key factor in developing software and infrastructure quickly is tight feedback loops. While it's probably not a great idea to be deploying directly to production from your own machine, having the ability to might be useful in a pinch, too.

You should be able to deploy to a dev environment (shared or ephemeral) so that you can easily validate your work in situ.

13. Can you show what will happen when a branch is merged?

Most IaC tools offer the ability to diff the changes they want to make. It's vitally important that when you go to merge some changes in, you know what the changes are, why you're making them (see point 11), and the effect the changes will have on the product or system.

This could be a cdk diff, or a visual diff if you're making a change to a frontend. Seldom is the code itself the interesting an crucial part of why you're making a change, and the effect of your changeset should be evident not only to reviewers, but to bleary-eyed SREs at 4am.


Posted 2022-07-07
From 9d783a1e0910638e760bd5dbadd7bd48f7165861 Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Thu, 7 Jul 2022 12:00:46 +0000 Subject: [PATCH 25/43] www-build-30 --- posts/the-continuous-delivery-test.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/posts/the-continuous-delivery-test.html b/posts/the-continuous-delivery-test.html index ebc250f..9b8b1f9 100644 --- a/posts/the-continuous-delivery-test.html +++ b/posts/the-continuous-delivery-test.html @@ -25,7 +25,7 @@

sourceless

contact -

The Continuous Delivery Test

In 2000, Joel Spolsky published an piece on what he believed were the key factors that separated high-performing teams from the rest, in a post titled The Joel Test: 12 Steps to Better Code. It contains many insights that are still useful to this day; however, the world, software, and the teams that make it have moved on in the nearly 22 years since that post.

In 2015, John Kodumal of LaunchDarkly published an updated Joel Test for Continuous Delivery. While being far more up-to-date, it's still slipped a little in relevance.

If this post were to have an alternate title, it'd be 'Front-load Your Risks'. All of the advice below seeks to move risks away from the act of deployment and move them to earlier steps of the development process.

So, here's my best shot at a CI/CD Joel Test for the 2020s.

1. Do you use a distributed version control system?

Git, GitHub, and the ecosystems around them have eaten the software world, and for good reason. Beyond the usual advantages - branching, merging, and easy rollbacks, many of these hosted git servers now come with a whole slew of other productivity tooling.

Especially notable are those that move your CI closer to your source code, such as GitHub Actions, and GitLab CI/CD.

2. Do you practice trunk-based development?

Trunk-based development rolls up a bunch of good practices under one system.

It forces you to have one good main branch that is always deployable (and by implication, always able to roll back), and encourages merging small features in one at a time.

Having an always-deployable main means that your deploy process becomes a lot more boring (which is great!), and is often indicative of a process that supports developers, rather than requiring long hours spent resolving merge conflicts and preparing release notes.

3. Do you merge little and often?

It's been known for some time now that large pull requests tend to get cursory reviews at best. On top of this, squirreling away to work on a single feature for a long time means you are not spending adequate time making sure that you are building the right thing!

This also means using small, ticket-scoped feature branches, where the changes have a very tight scope.

4. Do two people read code before it is merged?

You'll notice I was very careful to avoid mentioning how this should take place. For some, pull requests are the right tool, but pairing and mob programming are also sufficient.

Nobody should be solely responsible for any code.

5. Do you require changes to pass checks before they can be merged?

One of the leading causes of outages is deployments. You should do your best to make sure that broken code never gets deployed in the first place.

6. Can you test your changes in a production-like environment before you deploy it?

There are many ways to go about this. You could spin up a small clone of your production env, run the tests, and then kill it, or where this is not possible, you can run tests against mirrored traffic, or even run a canary.

7. Do you deploy to production as soon as main is updated?

Your deploy should be automated and happen right upon merge. This removes a burden from the team delivering a product and allows them to focus on features and reliability rather than long-winded release ceremonies. It can be hard to get here from releasing once a day, week, etc. – a mature approach to managing the risks of deployment is required, as well as battle-tested deploy processes and tools.

The earlier you start doing this, the easier it will be.

8. Does your deploy process self-heal?

When a deployment fails, can you roll back automatically? In addition to this, you should be able to roll back manually where necessary (though it's generally best to fail forwards!)

This also necessitates the use of blue-green deploys, canarying, healthchecks, and myriad other strategies to mitigate outage risk. It's very powerful to be able to turn a possible outage into a mere degradation.

9. Does your Infrastructure as Code live alongside the service it hosts?

It's a good idea to colocate any IaC with the software it's running rather than keeping the two in separate repositories. This dodges any dependency management between the two, and in many cases will save you a pipeline or two.

It's an antipattern (in the author's opinion) to have all infrastructure code completely separate from the application it supports. Common or shared infrastructure could be argued to have its own place, but a product should have all its pieces as close together as possible.

Monorepos are an extreme example of this philosophy.

10. Do you use feature flags?

Releases are a terrible mechanism for launching new features. You want to be able to run that shiny new feature in production as soon as possible, and you can't do that if you conflate a feature's launch with its release. This also means that you can preview and refine changes with flagship customers before rolling them out more widely.

11. Do you include ticket IDs in your commits or branches?

You need to be able to tie every commit back to the ticket that spawned it. It might not be you debugging a change that you merged, so it needs to be really easy to go back and find out why something was changed in order to make the right decision to fix it.

12. Can you still deploy from your own machine?

A key factor in developing software and infrastructure quickly is tight feedback loops. While it's probably not a great idea to be deploying directly to production from your own machine, having the ability to might be useful in a pinch, too.

You should be able to deploy to a dev environment (shared or ephemeral) so that you can easily validate your work in situ.

13. Can you show what will happen when a branch is merged?

Most IaC tools offer the ability to diff the changes they want to make. It's vitally important that when you go to merge some changes in, you know what the changes are, why you're making them (see point 11), and the effect the changes will have on the product or system.

This could be a cdk diff, or a visual diff if you're making a change to a frontend. Seldom is the code itself the interesting an crucial part of why you're making a change, and the effect of your changeset should be evident not only to reviewers, but to bleary-eyed SREs at 4am.

+

Thanks to Josh Finch for his valuable feedback on this post.


Posted 2022-07-07
From f4a937c2cc9f4225814d83ae046704aadb4db5bf Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Thu, 7 Jul 2022 12:31:53 +0000 Subject: [PATCH 26/43] www-build-31 --- posts/the-continuous-delivery-test.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/posts/the-continuous-delivery-test.html b/posts/the-continuous-delivery-test.html index 9b8b1f9..6ec9e00 100644 --- a/posts/the-continuous-delivery-test.html +++ b/posts/the-continuous-delivery-test.html @@ -25,7 +25,7 @@

sourceless

contact -

Thanks to Josh Finch for his valuable feedback on this post.

+

The Continuous Delivery Test

In 2000, Joel Spolsky published an piece on what he believed were the key factors that separated high-performing teams from the rest, in a post titled The Joel Test: 12 Steps to Better Code. It contains many insights that are still useful to this day; however, the world, software, and the teams that make it have moved on in the nearly 22 years since that post.

In 2015, John Kodumal of LaunchDarkly published an updated Joel Test for Continuous Delivery. While being far more up-to-date, it's still slipped a little in relevance.

If this post were to have an alternate title, it'd be 'Front-load Your Risks'. All of the advice below seeks to move risks away from the act of deployment and move them to earlier steps of the development process.

So, here's my best shot at a CI/CD Joel Test for the 2020s.

1. Do you use a distributed version control system?

Git, GitHub, and the ecosystems around them have eaten the software world, and for good reason. Beyond the usual advantages - branching, merging, and easy rollbacks, many of these hosted git servers now come with a whole slew of other productivity tooling.

Especially notable are those that move your CI closer to your source code, such as GitHub Actions, and GitLab CI/CD.

2. Do you practice trunk-based development?

Trunk-based development rolls up a bunch of good practices under one system.

It forces you to have one good main branch that is always deployable (and by implication, always able to roll back), and encourages merging small features in one at a time.

Having an always-deployable main means that your deploy process becomes a lot more boring (which is great!), and is often indicative of a process that supports developers, rather than requiring long hours spent resolving merge conflicts and preparing release notes.

3. Do you merge little and often?

It's been known for some time now that large pull requests tend to get cursory reviews at best. On top of this, squirreling away to work on a single feature for a long time means you are not spending adequate time making sure that you are building the right thing!

This also means using small, ticket-scoped feature branches, where the changes have a very tight scope.

4. Do two people read code before it is merged?

You'll notice I was very careful to avoid mentioning how this should take place. For some, pull requests are the right tool, but pairing and mob programming are also sufficient.

Nobody should be solely responsible for any code.

5. Do you require changes to pass checks before they can be merged?

One of the leading causes of outages is deployments. You should do your best to make sure that broken code never gets deployed in the first place.

6. Can you test your changes in a production-like environment before you deploy it?

There are many ways to go about this. You could spin up a small clone of your production env, run the tests, and then kill it, or where this is not possible, you can run tests against mirrored traffic, or even run a canary.

7. Do you deploy to production as soon as main is updated?

Your deploy should be automated and happen right upon merge. This removes a burden from the team delivering a product and allows them to focus on features and reliability rather than long-winded release ceremonies. It can be hard to get here from releasing once a day, week, etc. – a mature approach to managing the risks of deployment is required, as well as battle-tested deploy processes and tools.

The earlier you start doing this, the easier it will be.

8. Does your deploy process self-heal?

When a deployment fails, can you roll back automatically? In addition to this, you should be able to roll back manually where necessary (though it's generally best to fail forwards!)

This also necessitates the use of blue-green deploys, canarying, healthchecks, and myriad other strategies to mitigate outage risk. It's very powerful to be able to turn a possible outage into a mere degradation.

9. Does your Infrastructure as Code live alongside the service it hosts?

It's a good idea to colocate any IaC with the software it's running rather than keeping the two in separate repositories. This dodges any dependency management between the two, and in many cases will save you a pipeline or two.

It's an antipattern (in the author's opinion) to have all infrastructure code completely separate from the application it supports. Common or shared infrastructure could be argued to have its own place, but a product should have all its pieces as close together as possible.

Monorepos are an extreme example of this philosophy.

10. Do you use feature flags?

Releases are a terrible mechanism for launching new features. You want to be able to run that shiny new feature in production as soon as possible, and you can't do that if you conflate a feature's launch with its release. This also means that you can preview and refine changes with flagship customers before rolling them out more widely.

11. Do you include ticket IDs in your commits or branches?

You need to be able to tie every commit back to the ticket that spawned it. It might not be you debugging a change that you merged, so it needs to be really easy to go back and find out why something was changed in order to make the right decision to fix it.

12. Can you still deploy from your own machine?

A key factor in developing software and infrastructure quickly is tight feedback loops. While it's probably not a great idea to be deploying directly to production from your own machine, having the ability to might be useful in a pinch, too.

You should be able to deploy to a dev environment (shared or ephemeral) so that you can easily validate your work in situ.

13. Can you show what will happen when a branch is merged?

Most IaC tools offer the ability to diff the changes they want to make. It's vitally important that when you go to merge some changes in, you know what the changes are, why you're making them (see point 11), and the effect the changes will have on the product or system.

This could be a cdk diff, or a visual diff if you're making a change to a frontend. Seldom is the code itself the interesting an crucial part of why you're making a change, and the effect of your changeset should be evident not only to reviewers, but to bleary-eyed SREs at 4am.

Thanks to Josh Finch for his valuable feedback on this post.


Posted 2022-07-07
From 9132e27e8c7312170eae5f2c67596af593def7f7 Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Thu, 7 Jul 2022 12:35:21 +0000 Subject: [PATCH 27/43] www-build-33 --- posts/the-continuous-delivery-test.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/posts/the-continuous-delivery-test.html b/posts/the-continuous-delivery-test.html index 6ec9e00..0149ab8 100644 --- a/posts/the-continuous-delivery-test.html +++ b/posts/the-continuous-delivery-test.html @@ -25,7 +25,7 @@

sourceless

contact -

The Continuous Delivery Test

In 2000, Joel Spolsky published an piece on what he believed were the key factors that separated high-performing teams from the rest, in a post titled The Joel Test: 12 Steps to Better Code. It contains many insights that are still useful to this day; however, the world, software, and the teams that make it have moved on in the nearly 22 years since that post.

In 2015, John Kodumal of LaunchDarkly published an updated Joel Test for Continuous Delivery. While being far more up-to-date, it's still slipped a little in relevance.

If this post were to have an alternate title, it'd be 'Front-load Your Risks'. All of the advice below seeks to move risks away from the act of deployment and move them to earlier steps of the development process.

So, here's my best shot at a CI/CD Joel Test for the 2020s.

1. Do you use a distributed version control system?

Git, GitHub, and the ecosystems around them have eaten the software world, and for good reason. Beyond the usual advantages - branching, merging, and easy rollbacks, many of these hosted git servers now come with a whole slew of other productivity tooling.

Especially notable are those that move your CI closer to your source code, such as GitHub Actions, and GitLab CI/CD.

2. Do you practice trunk-based development?

Trunk-based development rolls up a bunch of good practices under one system.

It forces you to have one good main branch that is always deployable (and by implication, always able to roll back), and encourages merging small features in one at a time.

Having an always-deployable main means that your deploy process becomes a lot more boring (which is great!), and is often indicative of a process that supports developers, rather than requiring long hours spent resolving merge conflicts and preparing release notes.

3. Do you merge little and often?

It's been known for some time now that large pull requests tend to get cursory reviews at best. On top of this, squirreling away to work on a single feature for a long time means you are not spending adequate time making sure that you are building the right thing!

This also means using small, ticket-scoped feature branches, where the changes have a very tight scope.

4. Do two people read code before it is merged?

You'll notice I was very careful to avoid mentioning how this should take place. For some, pull requests are the right tool, but pairing and mob programming are also sufficient.

Nobody should be solely responsible for any code.

5. Do you require changes to pass checks before they can be merged?

One of the leading causes of outages is deployments. You should do your best to make sure that broken code never gets deployed in the first place.

6. Can you test your changes in a production-like environment before you deploy it?

There are many ways to go about this. You could spin up a small clone of your production env, run the tests, and then kill it, or where this is not possible, you can run tests against mirrored traffic, or even run a canary.

7. Do you deploy to production as soon as main is updated?

Your deploy should be automated and happen right upon merge. This removes a burden from the team delivering a product and allows them to focus on features and reliability rather than long-winded release ceremonies. It can be hard to get here from releasing once a day, week, etc. – a mature approach to managing the risks of deployment is required, as well as battle-tested deploy processes and tools.

The earlier you start doing this, the easier it will be.

8. Does your deploy process self-heal?

When a deployment fails, can you roll back automatically? In addition to this, you should be able to roll back manually where necessary (though it's generally best to fail forwards!)

This also necessitates the use of blue-green deploys, canarying, healthchecks, and myriad other strategies to mitigate outage risk. It's very powerful to be able to turn a possible outage into a mere degradation.

9. Does your Infrastructure as Code live alongside the service it hosts?

It's a good idea to colocate any IaC with the software it's running rather than keeping the two in separate repositories. This dodges any dependency management between the two, and in many cases will save you a pipeline or two.

It's an antipattern (in the author's opinion) to have all infrastructure code completely separate from the application it supports. Common or shared infrastructure could be argued to have its own place, but a product should have all its pieces as close together as possible.

Monorepos are an extreme example of this philosophy.

10. Do you use feature flags?

Releases are a terrible mechanism for launching new features. You want to be able to run that shiny new feature in production as soon as possible, and you can't do that if you conflate a feature's launch with its release. This also means that you can preview and refine changes with flagship customers before rolling them out more widely.

11. Do you include ticket IDs in your commits or branches?

You need to be able to tie every commit back to the ticket that spawned it. It might not be you debugging a change that you merged, so it needs to be really easy to go back and find out why something was changed in order to make the right decision to fix it.

12. Can you still deploy from your own machine?

A key factor in developing software and infrastructure quickly is tight feedback loops. While it's probably not a great idea to be deploying directly to production from your own machine, having the ability to might be useful in a pinch, too.

You should be able to deploy to a dev environment (shared or ephemeral) so that you can easily validate your work in situ.

13. Can you show what will happen when a branch is merged?

Most IaC tools offer the ability to diff the changes they want to make. It's vitally important that when you go to merge some changes in, you know what the changes are, why you're making them (see point 11), and the effect the changes will have on the product or system.

This could be a cdk diff, or a visual diff if you're making a change to a frontend. Seldom is the code itself the interesting an crucial part of why you're making a change, and the effect of your changeset should be evident not only to reviewers, but to bleary-eyed SREs at 4am.

Thanks to Josh Finch for his valuable feedback on this post.

+

The Continuous Delivery Test

In 2000, Joel Spolsky published an piece on what he believed were the key factors that separated high-performing teams from the rest, in a post titled The Joel Test: 12 Steps to Better Code. It contains many insights that are still useful to this day; however, the world, software, and the teams that make it have moved on in the nearly 22 years since that post.

In 2015, John Kodumal of LaunchDarkly published an updated Joel Test for Continuous Delivery. While being far more up-to-date, it's still slipped a little in relevance.

If this post were to have an alternate title, it'd be 'Front-load Your Risks'. All of the advice below seeks to move risks away from the act of deployment and move them to earlier steps of the development process.

So, here's my best shot at a CI/CD Joel Test for the 2020s.

1. Do you use a distributed version control system?

Git, GitHub, and the ecosystems around them have eaten the software world, and for good reason. Beyond the usual advantages - branching, merging, and easy rollbacks, many of these hosted git servers now come with a whole slew of other productivity tooling.

Especially notable are those that move your CI closer to your source code, such as GitHub Actions, and GitLab CI/CD.

2. Do you practice trunk-based development?

Trunk-based development rolls up a bunch of good practices under one system.

It forces you to have one good main branch that is always deployable (and by implication, always able to roll back), and encourages merging small features in one at a time.

Having an always-deployable main means that your deploy process becomes a lot more boring (which is great!), and is often indicative of a process that supports developers, rather than requiring long hours spent resolving merge conflicts and preparing release notes.

3. Do you merge little and often?

It's been known for some time now that large pull requests tend to get cursory reviews at best. On top of this, squirreling away to work on a single feature for a long time means you are not spending adequate time making sure that you are building the right thing!

This also means using small, ticket-scoped feature branches, where the changes have a very tight scope.

4. Do two people read code before it is merged?

You'll notice I was very careful to avoid mentioning how this should take place. For some, pull requests are the right tool, but pairing and mob programming are also sufficient.

Nobody should be solely responsible for any code.

5. Do you require changes to pass checks before they can be merged?

One of the leading causes of outages is deployments. You should do your best to make sure that broken code never gets deployed in the first place.

6. Can you test your changes in a production-like environment before you deploy it?

There are many ways to go about this. You could spin up a small clone of your production env, run the tests, and then kill it, or where this is not possible, you can run tests against mirrored traffic, or even run a canary.

7. Do you deploy to production as soon as main is updated?

Your deploy should be automated and happen right upon merge. This removes a burden from the team delivering a product and allows them to focus on features and reliability rather than long-winded release ceremonies. It can be hard to get here from releasing once a day, week, etc. – a mature approach to managing the risks of deployment is required, as well as battle-tested deploy processes and tools.

The earlier you start doing this, the easier it will be.

8. Does your deploy process self-heal?

When a deployment fails, can you roll back automatically? In addition to this, you should be able to roll back manually where necessary (though it's generally best to fail forwards!)

This also necessitates the use of blue-green deploys, canarying, healthchecks, and myriad other strategies to mitigate outage risk. It's very powerful to be able to turn a possible outage into a mere degradation.

9. Does your Infrastructure as Code live alongside the service it hosts?

It's a good idea to colocate any IaC with the software it's running rather than keeping the two in separate repositories. This dodges any dependency management between the two, and in many cases will save you a pipeline or two.

It's an antipattern (in the author's opinion) to have all infrastructure code completely separate from the application it supports. Common or shared infrastructure could be argued to have its own place, but a product should have all its pieces as close together as possible.

Monorepos are an extreme example of this philosophy.

10. Do you use feature flags?

Releases are a terrible mechanism for launching new features. You want to be able to run that shiny new feature in production as soon as possible, and you can't do that if you conflate a feature's launch with its release. This also means that you can preview and refine changes with flagship customers before rolling them out more widely.

11. Do you include ticket IDs in your commits or branches?

You need to be able to tie every commit back to the ticket that spawned it. It might not be you debugging a change that you merged, so it needs to be really easy to go back and find out why something was changed in order to make the right decision to fix it.

12. Can you still deploy from your own machine?

A key factor in developing software and infrastructure quickly is tight feedback loops. While it's probably not a great idea to be deploying directly to production from your own machine, having the ability to might be useful in a pinch, too.

You should be able to deploy to a dev environment (shared or ephemeral) so that you can easily validate your work in situ.

13. Can you show what will happen when a branch is merged?

Most IaC tools offer the ability to diff the changes they want to make. It's vitally important that when you go to merge some changes in, you know what the changes are, why you're making them (see point 11), and the effect the changes will have on the product or system.

This could be a cdk diff, or a visual diff if you're making a change to a frontend. Seldom is the code itself the interesting an crucial part of why you're making a change, and the effect of your changeset should be evident not only to reviewers, but to bleary-eyed SREs at 4am.

Thanks to Josh Finch for his valuable feedback on this post.


Posted 2022-07-07
From 9f3192b9f5381efead32b1dd3dee94131d86afde Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Thu, 7 Jul 2022 12:47:50 +0000 Subject: [PATCH 28/43] www-build-34 --- posts/the-continuous-delivery-test.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/posts/the-continuous-delivery-test.html b/posts/the-continuous-delivery-test.html index 0149ab8..16fbdc4 100644 --- a/posts/the-continuous-delivery-test.html +++ b/posts/the-continuous-delivery-test.html @@ -25,7 +25,7 @@

sourceless

contact -

The Continuous Delivery Test

In 2000, Joel Spolsky published an piece on what he believed were the key factors that separated high-performing teams from the rest, in a post titled The Joel Test: 12 Steps to Better Code. It contains many insights that are still useful to this day; however, the world, software, and the teams that make it have moved on in the nearly 22 years since that post.

In 2015, John Kodumal of LaunchDarkly published an updated Joel Test for Continuous Delivery. While being far more up-to-date, it's still slipped a little in relevance.

If this post were to have an alternate title, it'd be 'Front-load Your Risks'. All of the advice below seeks to move risks away from the act of deployment and move them to earlier steps of the development process.

So, here's my best shot at a CI/CD Joel Test for the 2020s.

1. Do you use a distributed version control system?

Git, GitHub, and the ecosystems around them have eaten the software world, and for good reason. Beyond the usual advantages - branching, merging, and easy rollbacks, many of these hosted git servers now come with a whole slew of other productivity tooling.

Especially notable are those that move your CI closer to your source code, such as GitHub Actions, and GitLab CI/CD.

2. Do you practice trunk-based development?

Trunk-based development rolls up a bunch of good practices under one system.

It forces you to have one good main branch that is always deployable (and by implication, always able to roll back), and encourages merging small features in one at a time.

Having an always-deployable main means that your deploy process becomes a lot more boring (which is great!), and is often indicative of a process that supports developers, rather than requiring long hours spent resolving merge conflicts and preparing release notes.

3. Do you merge little and often?

It's been known for some time now that large pull requests tend to get cursory reviews at best. On top of this, squirreling away to work on a single feature for a long time means you are not spending adequate time making sure that you are building the right thing!

This also means using small, ticket-scoped feature branches, where the changes have a very tight scope.

4. Do two people read code before it is merged?

You'll notice I was very careful to avoid mentioning how this should take place. For some, pull requests are the right tool, but pairing and mob programming are also sufficient.

Nobody should be solely responsible for any code.

5. Do you require changes to pass checks before they can be merged?

One of the leading causes of outages is deployments. You should do your best to make sure that broken code never gets deployed in the first place.

6. Can you test your changes in a production-like environment before you deploy it?

There are many ways to go about this. You could spin up a small clone of your production env, run the tests, and then kill it, or where this is not possible, you can run tests against mirrored traffic, or even run a canary.

7. Do you deploy to production as soon as main is updated?

Your deploy should be automated and happen right upon merge. This removes a burden from the team delivering a product and allows them to focus on features and reliability rather than long-winded release ceremonies. It can be hard to get here from releasing once a day, week, etc. – a mature approach to managing the risks of deployment is required, as well as battle-tested deploy processes and tools.

The earlier you start doing this, the easier it will be.

8. Does your deploy process self-heal?

When a deployment fails, can you roll back automatically? In addition to this, you should be able to roll back manually where necessary (though it's generally best to fail forwards!)

This also necessitates the use of blue-green deploys, canarying, healthchecks, and myriad other strategies to mitigate outage risk. It's very powerful to be able to turn a possible outage into a mere degradation.

9. Does your Infrastructure as Code live alongside the service it hosts?

It's a good idea to colocate any IaC with the software it's running rather than keeping the two in separate repositories. This dodges any dependency management between the two, and in many cases will save you a pipeline or two.

It's an antipattern (in the author's opinion) to have all infrastructure code completely separate from the application it supports. Common or shared infrastructure could be argued to have its own place, but a product should have all its pieces as close together as possible.

Monorepos are an extreme example of this philosophy.

10. Do you use feature flags?

Releases are a terrible mechanism for launching new features. You want to be able to run that shiny new feature in production as soon as possible, and you can't do that if you conflate a feature's launch with its release. This also means that you can preview and refine changes with flagship customers before rolling them out more widely.

11. Do you include ticket IDs in your commits or branches?

You need to be able to tie every commit back to the ticket that spawned it. It might not be you debugging a change that you merged, so it needs to be really easy to go back and find out why something was changed in order to make the right decision to fix it.

12. Can you still deploy from your own machine?

A key factor in developing software and infrastructure quickly is tight feedback loops. While it's probably not a great idea to be deploying directly to production from your own machine, having the ability to might be useful in a pinch, too.

You should be able to deploy to a dev environment (shared or ephemeral) so that you can easily validate your work in situ.

13. Can you show what will happen when a branch is merged?

Most IaC tools offer the ability to diff the changes they want to make. It's vitally important that when you go to merge some changes in, you know what the changes are, why you're making them (see point 11), and the effect the changes will have on the product or system.

This could be a cdk diff, or a visual diff if you're making a change to a frontend. Seldom is the code itself the interesting an crucial part of why you're making a change, and the effect of your changeset should be evident not only to reviewers, but to bleary-eyed SREs at 4am.

Thanks to Josh Finch for his valuable feedback on this post.

+

The Continuous Delivery Test

In 2000, Joel Spolsky published a piece on what he believed were the key factors that separated high-performing teams from the rest, in a post titled The Joel Test: 12 Steps to Better Code. It contains many insights that are still useful to this day; however, the world, software, and the teams that make it have moved on in the nearly 22 years since that post.

In 2015, John Kodumal of LaunchDarkly published an updated Joel Test for Continuous Delivery. While being far more up-to-date, it's still slipped a little in relevance.

If this post were to have an alternate title, it'd be 'Front-load Your Risks'. All of the advice below seeks to move risks away from the act of deployment and move them to earlier steps of the development process.

So, here's my best shot at a CI/CD Joel Test for the 2020s.

1. Do you use a distributed version control system?

Git, GitHub, and the ecosystems around them have eaten the software world, and for good reason. Beyond the usual advantages - branching, merging, and easy rollbacks, many of these hosted git servers now come with a whole slew of other productivity tooling.

Especially notable are those that move your CI closer to your source code, such as GitHub Actions, and GitLab CI/CD.

2. Do you practice trunk-based development?

Trunk-based development rolls up a bunch of good practices under one system.

It forces you to have one good main branch that is always deployable (and by implication, always able to roll back), and encourages merging small features one at a time.

Having an always-deployable main means that your deployment process becomes a lot more boring (which is great!), and is often indicative of a process that supports developers, rather than requiring long hours spent resolving merge conflicts and preparing release notes.

3. Do you merge little and often?

It's been known for some time now that large pull requests tend to get cursory reviews at best. On top of this, squirrelling away to work on a single feature for a long time means you are not spending adequate time making sure that you are building the right thing!

This also means using small, ticket-scoped feature branches, where the changes have a very tight scope.

4. Do two people read code before it is merged?

You'll notice I was very careful to avoid mentioning how this should take place. For some, pull requests are the right tool, but pairing and mob programming are also sufficient.

Nobody should be solely responsible for any code.

5. Do you require changes to pass checks before they can be merged?

One of the leading causes of outages is deployments. You should do your best to make sure that broken code never gets deployed in the first place.

6. Can you test your changes in a production-like environment before you deploy them?

There are many ways to go about this. You could spin up a small clone of your production env, run the tests, and then kill it. Where this is not possible, you can run tests against mirrored traffic or even run a canary.

7. Do you deploy to production as soon as main is updated?

Your deployments should be automated and happen right upon merge. This removes a burden from the team delivering a product and allows them to focus on features and reliability rather than long-winded release ceremonies. It can be hard to get here if you're currently releasing once a day, week, etc. – a mature approach to managing the risks of deployment is required, as well as battle-tested deployment processes and tools.

The earlier you start doing this, the easier it will be.

8. Does your deploy process self-heal?

When a deployment fails, can you roll back automatically? In addition to this, you should be able to roll back manually where necessary (though it's generally best to fail forwards!)

This also necessitates the use of blue-green deploys, canarying, healthchecks, and myriad other strategies to mitigate outage risk. It's very powerful to be able to turn a possible outage into a mere degradation.

9. Does your Infrastructure as Code live alongside the service it hosts?

It's a good idea to colocate any IaC with the software it's running rather than keeping the two in separate repositories. This dodges any dependency management between the two, and in many cases will save you a pipeline or two.

It's an antipattern (in the author's opinion) to have all infrastructure code completely separate from the application it supports. Common or shared infrastructure could be argued to have its own place, but a product should have all its pieces as close together as possible.

Monorepos are an extreme example of this philosophy.

10. Do you use feature flags?

Releases are a terrible mechanism for launching new features. You want to be able to run that shiny new feature in production as soon as possible, and you can't do that if you conflate a feature's launch with its release. This also means that you can preview and refine changes with flagship customers before rolling them out more widely.

11. Do you include ticket IDs in your commits or branches?

You need to be able to tie every commit back to the ticket that spawned it. It might not be you debugging a change that you merged, so it needs to be really easy to go back and find out why something was changed in order to make the right decision to fix it.

12. Can you still deploy from your own machine?

A key factor in developing software and infrastructure quickly is tight feedback loops. While it's probably not a great idea to be deploying directly to production from your own machine, having the ability to might be useful in a pinch, too.

You should be able to deploy to a dev environment (shared or ephemeral) so that you can easily validate your work in situ.

13. Can you show what will happen when a branch is merged?

Most IaC tools offer the ability to diff the changes they want to make. It's vitally important that when you go to merge some changes in, you know what the changes are, why you're making them (see point 11), and the effect the changes will have on the product or system.

This could be a cdk diff, or a visual diff if you're making a change to a frontend. Seldom is the code itself the interesting and crucial part of why you're making a change. The effect of your changeset should be evident not only to reviewers but also to bleary-eyed SREs at 4am.

Thanks to Josh Finch for his valuable feedback on this post.


Posted 2022-07-07
From 7eb48eb80ff9fe50eb5c7c442720551b9348ea46 Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Fri, 29 Jul 2022 09:19:52 +0000 Subject: [PATCH 29/43] www-build-35 --- posts/the-continuous-delivery-test.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/posts/the-continuous-delivery-test.html b/posts/the-continuous-delivery-test.html index 16fbdc4..61d18a0 100644 --- a/posts/the-continuous-delivery-test.html +++ b/posts/the-continuous-delivery-test.html @@ -25,7 +25,7 @@

sourceless

contact -

The Continuous Delivery Test

In 2000, Joel Spolsky published a piece on what he believed were the key factors that separated high-performing teams from the rest, in a post titled The Joel Test: 12 Steps to Better Code. It contains many insights that are still useful to this day; however, the world, software, and the teams that make it have moved on in the nearly 22 years since that post.

In 2015, John Kodumal of LaunchDarkly published an updated Joel Test for Continuous Delivery. While being far more up-to-date, it's still slipped a little in relevance.

If this post were to have an alternate title, it'd be 'Front-load Your Risks'. All of the advice below seeks to move risks away from the act of deployment and move them to earlier steps of the development process.

So, here's my best shot at a CI/CD Joel Test for the 2020s.

1. Do you use a distributed version control system?

Git, GitHub, and the ecosystems around them have eaten the software world, and for good reason. Beyond the usual advantages - branching, merging, and easy rollbacks, many of these hosted git servers now come with a whole slew of other productivity tooling.

Especially notable are those that move your CI closer to your source code, such as GitHub Actions, and GitLab CI/CD.

2. Do you practice trunk-based development?

Trunk-based development rolls up a bunch of good practices under one system.

It forces you to have one good main branch that is always deployable (and by implication, always able to roll back), and encourages merging small features one at a time.

Having an always-deployable main means that your deployment process becomes a lot more boring (which is great!), and is often indicative of a process that supports developers, rather than requiring long hours spent resolving merge conflicts and preparing release notes.

3. Do you merge little and often?

It's been known for some time now that large pull requests tend to get cursory reviews at best. On top of this, squirrelling away to work on a single feature for a long time means you are not spending adequate time making sure that you are building the right thing!

This also means using small, ticket-scoped feature branches, where the changes have a very tight scope.

4. Do two people read code before it is merged?

You'll notice I was very careful to avoid mentioning how this should take place. For some, pull requests are the right tool, but pairing and mob programming are also sufficient.

Nobody should be solely responsible for any code.

5. Do you require changes to pass checks before they can be merged?

One of the leading causes of outages is deployments. You should do your best to make sure that broken code never gets deployed in the first place.

6. Can you test your changes in a production-like environment before you deploy them?

There are many ways to go about this. You could spin up a small clone of your production env, run the tests, and then kill it. Where this is not possible, you can run tests against mirrored traffic or even run a canary.

7. Do you deploy to production as soon as main is updated?

Your deployments should be automated and happen right upon merge. This removes a burden from the team delivering a product and allows them to focus on features and reliability rather than long-winded release ceremonies. It can be hard to get here if you're currently releasing once a day, week, etc. – a mature approach to managing the risks of deployment is required, as well as battle-tested deployment processes and tools.

The earlier you start doing this, the easier it will be.

8. Does your deploy process self-heal?

When a deployment fails, can you roll back automatically? In addition to this, you should be able to roll back manually where necessary (though it's generally best to fail forwards!)

This also necessitates the use of blue-green deploys, canarying, healthchecks, and myriad other strategies to mitigate outage risk. It's very powerful to be able to turn a possible outage into a mere degradation.

9. Does your Infrastructure as Code live alongside the service it hosts?

It's a good idea to colocate any IaC with the software it's running rather than keeping the two in separate repositories. This dodges any dependency management between the two, and in many cases will save you a pipeline or two.

It's an antipattern (in the author's opinion) to have all infrastructure code completely separate from the application it supports. Common or shared infrastructure could be argued to have its own place, but a product should have all its pieces as close together as possible.

Monorepos are an extreme example of this philosophy.

10. Do you use feature flags?

Releases are a terrible mechanism for launching new features. You want to be able to run that shiny new feature in production as soon as possible, and you can't do that if you conflate a feature's launch with its release. This also means that you can preview and refine changes with flagship customers before rolling them out more widely.

11. Do you include ticket IDs in your commits or branches?

You need to be able to tie every commit back to the ticket that spawned it. It might not be you debugging a change that you merged, so it needs to be really easy to go back and find out why something was changed in order to make the right decision to fix it.

12. Can you still deploy from your own machine?

A key factor in developing software and infrastructure quickly is tight feedback loops. While it's probably not a great idea to be deploying directly to production from your own machine, having the ability to might be useful in a pinch, too.

You should be able to deploy to a dev environment (shared or ephemeral) so that you can easily validate your work in situ.

13. Can you show what will happen when a branch is merged?

Most IaC tools offer the ability to diff the changes they want to make. It's vitally important that when you go to merge some changes in, you know what the changes are, why you're making them (see point 11), and the effect the changes will have on the product or system.

This could be a cdk diff, or a visual diff if you're making a change to a frontend. Seldom is the code itself the interesting and crucial part of why you're making a change. The effect of your changeset should be evident not only to reviewers but also to bleary-eyed SREs at 4am.

Thanks to Josh Finch for his valuable feedback on this post.

+

The Continuous Delivery Test

In 2000, Joel Spolsky published a piece on what he believed were the key factors that separated high-performing teams from the rest, in a post titled The Joel Test: 12 Steps to Better Code. It contains many insights that are still useful to this day; however, the world, software, and the teams that make it have moved on in the nearly 22 years since that post.

In 2015, John Kodumal of LaunchDarkly published an updated Joel Test for Continuous Delivery. While being far more up-to-date, it's still slipped a little in relevance.

If this post were to have an alternate title, it'd be 'Front-load Your Risks'. All of the advice below seeks to move risks away from the act of deployment and move them to earlier steps of the development process.

So, here's my best shot at a CI/CD Joel Test for the 2020s.

1. Do you use a distributed version control system?

Git, GitHub, and the ecosystems around them have eaten the software world, and for good reason. Beyond the usual advantages - branching, merging, and easy rollbacks, many of these hosted git servers now come with a whole slew of other productivity tooling.

Especially notable are those that move your CI closer to your source code, such as GitHub Actions, and GitLab CI/CD.

2. Do you practice trunk-based development?

Trunk-based development rolls up a bunch of good practices under one system.

It forces you to have one good main branch that is always deployable (and by implication, always able to roll back), and encourages merging small features one at a time.

Having an always-deployable main means that your deployment process becomes a lot more boring (which is great!), and is often indicative of a process that supports developers, rather than requiring long hours spent resolving merge conflicts and preparing release notes.

3. Do you merge little and often?

It's been known for some time now that large pull requests tend to get cursory reviews at best. On top of this, squirrelling away to work on a single feature for a long time means you are not spending adequate time making sure that you are building the right thing!

This also means using small, ticket-scoped feature branches, where the changes have a very tight scope.

4. Do two people read code before it is merged?

You'll notice I was very careful to avoid mentioning how this should take place. For some, pull requests are the right tool, but pairing and mob programming are also sufficient.

Nobody should be solely responsible for any code.

5. Do you require changes to pass checks before they can be merged?

One of the leading causes of outages is deployments. You should do your best to make sure that broken code never gets deployed in the first place.

6. Can you test your changes in a production-like environment before you deploy them?

There are many ways to go about this. You could spin up a small clone of your production env, run the tests, and then kill it. Where this is not possible, you can run tests against mirrored traffic or even run a canary.

7. Do you deploy to production as soon as main is updated?

Your deployments should be automated and happen right upon merge. This removes a burden from the team delivering a product and allows them to focus on features and reliability rather than long-winded release ceremonies. It can be hard to get here if you're currently releasing once a day, week, etc. – a mature approach to managing the risks of deployment is required, as well as battle-tested deployment processes and tools.

The earlier you start doing this, the easier it will be.

8. Does your deploy process self-heal?

When a deployment fails, can you roll back automatically? In addition to this, you should be able to roll back manually where necessary (though it's generally best to fail forwards!)

This also necessitates the use of blue-green deploys, canarying, healthchecks, and myriad other strategies to mitigate outage risk. It's very powerful to be able to turn a possible outage into a mere degradation.

9. Does your Infrastructure as Code live alongside the service it hosts?

It's a good idea to colocate any IaC with the software it's running rather than keeping the two in separate repositories. This dodges any dependency management between the two, and in many cases will save you a pipeline or two.

It's an antipattern (in the author's opinion) to have all infrastructure code completely separate from the application it supports. Common or shared infrastructure could be argued to have its own place, but a product should have all its pieces as close together as possible.

Monorepos are an extreme example of this philosophy.

10. Do you use feature flags?

Releases are a terrible mechanism for launching new features. You want to be able to run that shiny new feature in production as soon as possible, and you can't do that if you conflate a feature's launch with its release. This also means that you can preview and refine changes with flagship customers before rolling them out more widely.

11. Do you include ticket IDs in your commits or branches?

You need to be able to tie every commit back to the ticket that spawned it. It might not be you debugging a change that you merged, so it needs to be really easy to go back and find out why something was changed in order to make the right decision to fix it.

12. Can you still deploy from your own machine?

A key factor in developing software and infrastructure quickly is tight feedback loops. While it's probably not a great idea to be deploying directly to production from your own machine, having the ability to do so might be useful in a pinch.

You should be able to deploy to a dev environment (shared or ephemeral) such that you can easily validate your work in situ.

13. Can you show what will happen when a branch is merged?

Most IaC tools offer the ability to diff the changes they want to make. It's vitally important that when you go to merge some changes in, you know what the changes are, why you're making them (see point 11), and the effect the changes will have on the product or system.

This could be a cdk diff, or a visual diff if you're making a change to a frontend. Seldom is the code itself the interesting and crucial part of why you're making a change. The effect of your changeset should be evident not only to reviewers but also to bleary-eyed SREs at 4am.

Thanks to Josh Finch for his valuable feedback on this post.


Posted 2022-07-07
From fce972c77dd475474f313df8143e362a4fe4aa27 Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Fri, 29 Jul 2022 09:51:44 +0000 Subject: [PATCH 30/43] www-build-36 --- index.html | 2 + ...ut-ticket-ids-in-your-commit-messages.html | 40 +++++++++++++++++++ posts/the-continuous-delivery-test.html | 2 + 3 files changed, 44 insertions(+) create mode 100644 posts/put-ticket-ids-in-your-commit-messages.html diff --git a/index.html b/index.html index 1e8b419..cfaa9eb 100644 --- a/index.html +++ b/index.html @@ -29,6 +29,8 @@

sourceless



+ 2022-07-29 Put Ticket IDs in your Commit Messages
+ 2022-07-07 The Continuous Delivery Test
2022-06-22 Perfect isn't Good Enough
diff --git a/posts/put-ticket-ids-in-your-commit-messages.html b/posts/put-ticket-ids-in-your-commit-messages.html new file mode 100644 index 0000000..2899e8e --- /dev/null +++ b/posts/put-ticket-ids-in-your-commit-messages.html @@ -0,0 +1,40 @@ + + + + + Sourceless - Put Ticket IDs in your Commit Messages + + + + + + + + + + + + +

sourceless

+ + +index + + about + + contact + + +

Put Ticket IDs in your Commit Messages

In my previous post The Continuous Delivery Test I included a point:

  1. Do you include ticket IDs in your commits or branches?

This sparked quite a lot of discussion on hacker news.. I think it'd be useful to highlight some of my reasoning for including this point, and highlight some of the advice given by some of the commenters.

Why you should do it

Link work back to the ticket that spawned it

If you're in anywhere but the smallest companies, you probably have some sort of compliance requirements that require you to be able to link work done back to the planning that caused it to happen.

The reason that compliance frameworks want you to do this is mainly so there is an unbroken chain of culpability that can be used to identify the root cause of a potential issue.

But it's also just good documentation. Do you really want to play archeologist every time you need to figure out why a certain commit was made, or why a certain line of code is a bit weird?

As one lovely HN commenter puts it:

I can't tell you how many times I've dug into the commit history to find where a change happened, then wanted to know the full context, and been glad I could just pull up the years-old ticket directly and see a detailed description of intent and requirements, discussions in the comments, mock-ups, etc etc

Track the content of releases

In some environments you might need to prepare release notes or a changelog.

This is, of course, much easier if you can derive the list of tickets from the delta of what's going in to production.

Measure how well your team is delivering

In Accelerate, Forsgren, Humble, and Kim pick out four metrics that seperate high performing teams from the rest - and they all have to do with deployment.

The first of those metrics is Lead Time, which measures the amount of time it takes from starting a ticket (or the first commit made, depending how you want to measure) to when it's eventually released.

Having some metadata available makes this much easier to do!

It's not that hard

Seriously, it's just habit. It might sound annoying or bureaucratic to you if you've never done it before, but after a couple weeks it'll probably be an unconscious practice that you'll never think about again.

And if typing <10 extra characters at the start of a commit message is really cramping your style, you can always write a prepare-commit-msg git hook.

Why you might not be doing it

Your company is small

If you're starting to grow and compliance is on the horizon, it's much easier to start now than when the deadline looms.

It's a personal project

Yep. Why would you? It's needless overhead.

Merging/branching strategy

I'm probably not going to convince you otherwise, but I think long-lived feature branches suck. They require complex merge patterns, bundle risk, and often require a bureaucratic ritual to merge in to a production branch.

Trunk-based development all the way, and if you can have a branch per ticket with the ticket ID in the branch name, even better.

I need to make an ad-hoc change

This usually falls in to one of two categories.

The first is "I want to make a change off the books". Usually this is a culture problem; you should feel empowered to create small tickets as you see fit to fix small issues. It might also be that your team doesn't create time for care and feeding work.

The second is "I don't know where this change belongs". Can you roll it in to another ticket you're already working on, e.g. one where you're already touching the code in question? Or maybe it's enough work that it should be its own item?

+
+ Posted 2022-07-29 +
+
+ +← The Continuous Delivery Test + + + +
+ + diff --git a/posts/the-continuous-delivery-test.html b/posts/the-continuous-delivery-test.html index 61d18a0..6c0b3a4 100644 --- a/posts/the-continuous-delivery-test.html +++ b/posts/the-continuous-delivery-test.html @@ -34,6 +34,8 @@

The Continuous Delivery Test

In 2000, Joel Spolsky published a piece ← Perfect isn't Good Enough +Put Ticket IDs in your Commit Messages → + From d2bcf4a3674ac8fb3b33ad56acb40cf58ae152ee Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Fri, 29 Jul 2022 09:59:09 +0000 Subject: [PATCH 31/43] www-build-37 --- posts/put-ticket-ids-in-your-commit-messages.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/posts/put-ticket-ids-in-your-commit-messages.html b/posts/put-ticket-ids-in-your-commit-messages.html index 2899e8e..01b0889 100644 --- a/posts/put-ticket-ids-in-your-commit-messages.html +++ b/posts/put-ticket-ids-in-your-commit-messages.html @@ -25,7 +25,7 @@

sourceless

contact -

Put Ticket IDs in your Commit Messages

In my previous post The Continuous Delivery Test I included a point:

  1. Do you include ticket IDs in your commits or branches?

This sparked quite a lot of discussion on hacker news.. I think it'd be useful to highlight some of my reasoning for including this point, and highlight some of the advice given by some of the commenters.

Why you should do it

Link work back to the ticket that spawned it

If you're in anywhere but the smallest companies, you probably have some sort of compliance requirements that require you to be able to link work done back to the planning that caused it to happen.

The reason that compliance frameworks want you to do this is mainly so there is an unbroken chain of culpability that can be used to identify the root cause of a potential issue.

But it's also just good documentation. Do you really want to play archeologist every time you need to figure out why a certain commit was made, or why a certain line of code is a bit weird?

As one lovely HN commenter puts it:

I can't tell you how many times I've dug into the commit history to find where a change happened, then wanted to know the full context, and been glad I could just pull up the years-old ticket directly and see a detailed description of intent and requirements, discussions in the comments, mock-ups, etc etc

Track the content of releases

In some environments you might need to prepare release notes or a changelog.

This is, of course, much easier if you can derive the list of tickets from the delta of what's going in to production.

Measure how well your team is delivering

In Accelerate, Forsgren, Humble, and Kim pick out four metrics that seperate high performing teams from the rest - and they all have to do with deployment.

The first of those metrics is Lead Time, which measures the amount of time it takes from starting a ticket (or the first commit made, depending how you want to measure) to when it's eventually released.

Having some metadata available makes this much easier to do!

It's not that hard

Seriously, it's just habit. It might sound annoying or bureaucratic to you if you've never done it before, but after a couple weeks it'll probably be an unconscious practice that you'll never think about again.

And if typing <10 extra characters at the start of a commit message is really cramping your style, you can always write a prepare-commit-msg git hook.

Why you might not be doing it

Your company is small

If you're starting to grow and compliance is on the horizon, it's much easier to start now than when the deadline looms.

It's a personal project

Yep. Why would you? It's needless overhead.

Merging/branching strategy

I'm probably not going to convince you otherwise, but I think long-lived feature branches suck. They require complex merge patterns, bundle risk, and often require a bureaucratic ritual to merge in to a production branch.

Trunk-based development all the way, and if you can have a branch per ticket with the ticket ID in the branch name, even better.

I need to make an ad-hoc change

This usually falls in to one of two categories.

The first is "I want to make a change off the books". Usually this is a culture problem; you should feel empowered to create small tickets as you see fit to fix small issues. It might also be that your team doesn't create time for care and feeding work.

The second is "I don't know where this change belongs". Can you roll it in to another ticket you're already working on, e.g. one where you're already touching the code in question? Or maybe it's enough work that it should be its own item?

+

Put Ticket IDs in your Commit Messages

In my previous post The Continuous Delivery Test I included a point:

Do you include ticket IDs in your commits or branches?

This sparked quite a lot of discussion on hacker news. I think it'd be useful to highlight some of my reasoning for including this point, and highlight some of the advice given by some of the commenters.

Why you should do it

Link work back to the ticket that spawned it

If you're in anywhere but the smallest companies, you probably have some sort of compliance requirements that require you to be able to link work done back to the planning that caused it to happen.

The reason that compliance frameworks want you to do this is mainly so there is an unbroken chain of culpability that can be used to identify the root cause of a potential issue.

But it's also just good documentation. Do you really want to play archeologist every time you need to figure out why a certain commit was made, or why a certain line of code is a bit weird?

As one lovely HN commenter puts it:

I can't tell you how many times I've dug into the commit history to find where a change happened, then wanted to know the full context, and been glad I could just pull up the years-old ticket directly and see a detailed description of intent and requirements, discussions in the comments, mock-ups, etc etc

Track the content of releases

In some environments you might need to prepare release notes or a changelog.

This is, of course, much easier if you can derive the list of tickets from the delta of what's going in to production.

Measure how well your team is delivering

In Accelerate, Forsgren, Humble, and Kim pick out four metrics that seperate high performing teams from the rest - and they all have to do with deployment.

The first of those metrics is Lead Time, which measures the amount of time it takes from starting a ticket (or the first commit made, depending how you want to measure) to when it's eventually released.

Having some metadata available makes this much easier to do!

It's not that hard

Seriously, it's just habit. It might sound annoying or bureaucratic to you if you've never done it before, but after a couple weeks it'll probably be an unconscious practice that you'll never think about again.

And if typing <10 extra characters at the start of a commit message is really cramping your style, you can always write a prepare-commit-msg git hook.

Why you might not be doing it

Your company is small

If you're starting to grow and compliance is on the horizon, it's much easier to start now than when the deadline looms.

It's a personal project

Yep. Why would you? It's needless overhead.

Merging/branching strategy

I'm probably not going to convince you otherwise, but I think long-lived feature branches suck. They require complex merge patterns, bundle risk, and often require a bureaucratic ritual to merge in to a production branch.

Trunk-based development all the way, and if you can have a branch per ticket with the ticket ID in the branch name, even better.

I need to make an ad-hoc change

This usually falls in to one of two categories.

The first is "I want to make a change off the books". Usually this is a culture problem; you should feel empowered to create small tickets as you see fit to fix small issues. It might also be that your team doesn't create time for care and feeding work.

The second is "I don't know where this change belongs". Can you roll it in to another ticket you're already working on, e.g. one where you're already touching the code in question? Or maybe it's enough work that it should be its own item?


Posted 2022-07-29
From 1aae5620a7ddfefa031a503ddcc5d653cf6ce884 Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Fri, 29 Jul 2022 10:01:47 +0000 Subject: [PATCH 32/43] www-build-38 --- posts/put-ticket-ids-in-your-commit-messages.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/posts/put-ticket-ids-in-your-commit-messages.html b/posts/put-ticket-ids-in-your-commit-messages.html index 01b0889..d03fc50 100644 --- a/posts/put-ticket-ids-in-your-commit-messages.html +++ b/posts/put-ticket-ids-in-your-commit-messages.html @@ -25,7 +25,7 @@

sourceless

contact -

Put Ticket IDs in your Commit Messages

In my previous post The Continuous Delivery Test I included a point:

Do you include ticket IDs in your commits or branches?

This sparked quite a lot of discussion on hacker news. I think it'd be useful to highlight some of my reasoning for including this point, and highlight some of the advice given by some of the commenters.

Why you should do it

Link work back to the ticket that spawned it

If you're in anywhere but the smallest companies, you probably have some sort of compliance requirements that require you to be able to link work done back to the planning that caused it to happen.

The reason that compliance frameworks want you to do this is mainly so there is an unbroken chain of culpability that can be used to identify the root cause of a potential issue.

But it's also just good documentation. Do you really want to play archeologist every time you need to figure out why a certain commit was made, or why a certain line of code is a bit weird?

As one lovely HN commenter puts it:

I can't tell you how many times I've dug into the commit history to find where a change happened, then wanted to know the full context, and been glad I could just pull up the years-old ticket directly and see a detailed description of intent and requirements, discussions in the comments, mock-ups, etc etc

Track the content of releases

In some environments you might need to prepare release notes or a changelog.

This is, of course, much easier if you can derive the list of tickets from the delta of what's going in to production.

Measure how well your team is delivering

In Accelerate, Forsgren, Humble, and Kim pick out four metrics that seperate high performing teams from the rest - and they all have to do with deployment.

The first of those metrics is Lead Time, which measures the amount of time it takes from starting a ticket (or the first commit made, depending how you want to measure) to when it's eventually released.

Having some metadata available makes this much easier to do!

It's not that hard

Seriously, it's just habit. It might sound annoying or bureaucratic to you if you've never done it before, but after a couple weeks it'll probably be an unconscious practice that you'll never think about again.

And if typing <10 extra characters at the start of a commit message is really cramping your style, you can always write a prepare-commit-msg git hook.

Why you might not be doing it

Your company is small

If you're starting to grow and compliance is on the horizon, it's much easier to start now than when the deadline looms.

It's a personal project

Yep. Why would you? It's needless overhead.

Merging/branching strategy

I'm probably not going to convince you otherwise, but I think long-lived feature branches suck. They require complex merge patterns, bundle risk, and often require a bureaucratic ritual to merge in to a production branch.

Trunk-based development all the way, and if you can have a branch per ticket with the ticket ID in the branch name, even better.

I need to make an ad-hoc change

This usually falls in to one of two categories.

The first is "I want to make a change off the books". Usually this is a culture problem; you should feel empowered to create small tickets as you see fit to fix small issues. It might also be that your team doesn't create time for care and feeding work.

The second is "I don't know where this change belongs". Can you roll it in to another ticket you're already working on, e.g. one where you're already touching the code in question? Or maybe it's enough work that it should be its own item?

+

Put Ticket IDs in your Commit Messages

In my previous post The Continuous Delivery Test I included a point:

Do you include ticket IDs in your commits or branches?

This sparked quite a lot of discussion on hacker news. I think it'd be useful to highlight some of my reasoning for including this point, and highlight some of the advice given by some of the commenters.

Why you should do it

Link work back to the ticket that spawned it

If you're in anywhere but the smallest companies, you probably have some sort of compliance requirements that require you to be able to link work done back to the planning that caused it to happen.

The reason that compliance frameworks want you to do this is mainly so there is an unbroken chain of culpability that can be used to identify the root cause of a potential issue.

But it's also just good documentation. Do you really want to play archeologist every time you need to figure out why a certain commit was made, or why a certain line of code is a bit weird?

As one lovely HN commenter puts it:

'I can't tell you how many times I've dug into the commit history to find where a change happened, then wanted to know the full context, and been glad I could just pull up the years-old ticket directly and see a detailed description of intent and requirements, discussions in the comments, mock-ups, etc etc'

Track the content of releases

In some environments you might need to prepare release notes or a changelog.

This is, of course, much easier if you can derive the list of tickets from the delta of what's going in to production.

Measure how well your team is delivering

In Accelerate, Forsgren, Humble, and Kim pick out four metrics that seperate high performing teams from the rest - and they all have to do with deployment.

The first of those metrics is Lead Time, which measures the amount of time it takes from starting a ticket (or the first commit made, depending how you want to measure) to when it's eventually released.

Having some metadata available makes this much easier to do!

It's not that hard

Seriously, it's just habit. It might sound annoying or bureaucratic to you if you've never done it before, but after a couple weeks it'll probably be an unconscious practice that you'll never think about again.

And if typing <10 extra characters at the start of a commit message is really cramping your style, you can always write a prepare-commit-msg git hook.

Why you might not be doing it

Your company is small

If you're starting to grow and compliance is on the horizon, it's much easier to start now than when the deadline looms.

It's a personal project

Yep. Why would you? It's needless overhead.

Merging/branching strategy

I'm probably not going to convince you otherwise, but I think long-lived feature branches suck. They require complex merge patterns, bundle risk, and often require a bureaucratic ritual to merge in to a production branch.

Trunk-based development all the way, and if you can have a branch per ticket with the ticket ID in the branch name, even better.

I need to make an ad-hoc change

This usually falls in to one of two categories.

The first is "I want to make a change off the books". Usually this is a culture problem; you should feel empowered to create small tickets as you see fit to fix small issues. It might also be that your team doesn't create time for care and feeding work.

The second is "I don't know where this change belongs". Can you roll it in to another ticket you're already working on, e.g. one where you're already touching the code in question? Or maybe it's enough work that it should be its own item?


Posted 2022-07-29
From 871e20c4b5093c58c6d6cb12a35aeb5eed8254c9 Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Tue, 16 Aug 2022 11:15:25 +0000 Subject: [PATCH 33/43] www-build-39 --- index.html | 2 + .../make-your-own-free-password-manager.html | 51 +++++++++++++++++++ ...ut-ticket-ids-in-your-commit-messages.html | 2 + 3 files changed, 55 insertions(+) create mode 100644 posts/make-your-own-free-password-manager.html diff --git a/index.html b/index.html index cfaa9eb..6159d09 100644 --- a/index.html +++ b/index.html @@ -29,6 +29,8 @@

sourceless



+ 2022-08-16 Make your own (free) password manager
+ 2022-07-29 Put Ticket IDs in your Commit Messages
2022-07-07 The Continuous Delivery Test
diff --git a/posts/make-your-own-free-password-manager.html b/posts/make-your-own-free-password-manager.html new file mode 100644 index 0000000..1385876 --- /dev/null +++ b/posts/make-your-own-free-password-manager.html @@ -0,0 +1,51 @@ + + + + + Sourceless - Make your own (free) password manager + + + + + + + + + + + + +

sourceless

+ + +index + + about + + contact + + +

Make your own (free) password manager

Before I say anything else, it should be noted that this solution requires a little bit of background knowledge to set up and use. At the very least you'll need to be comfortable on the command line in linux/osx, especially with installing packages, git, ssh, and a little gpg. Don't worry if you don't know all of that – a little familiarity should be enough.

Why I rolled my own

You might be wondering what the point is of setting up your own password manager is when so many good, paid alternatives exist – and you'd be right!

There is however, some advantage in knowing exactly how your passwords are encrypted and being able to integrate your password store with EVERYTHING.

And it's run at no cost to me.

Standard warnings apply; the UX will not be as good. If you do not back up your GPG keys, you could lose access to your passwords forever. The security of your password manager is only as good as the security of your system.

Features and composition

Our password manager will have the following features:

  • Encrypted at rest
  • Command line, web browser, and mobile clientship
  • Per-device revocation
  • Cross-device sync

We'll make it with these components:

Make sure you have all the above installed before continuing!

Steps

1. Generate a gpg key

There's lots of guides on doing this, but here's an example (from 2022, if you're reading this in the future, google it first because best practice has probably changed!).

gpg --default-new-key-algo "ed25519/cert,sign+cv25519/encr" --quick-generate-key "my@email.com"
+

This will generate a new multi-purpose ed25519 key with no expiration date.

It's up to you if you want to use this to generate subkeys to use for the password store. I would, however, recommend that you make one key per device sou you can revoke access if a device is lost or stolen!

If you've already got a gpg key and want to use it – use that.

**And before anything else - back up your key! On a storage drive, paper, obelisk, yubikey - and in more than one place!**

2. Init the password store

pass init <your gpg key id from step 1>
+

That's it! If you want to use multiple keys (e.g. one per device), just add any additional IDs after the first.

3. Add your first password

pass generate my-first-password 100
+

This will generate a random 100-character password for you named my-first-password.

It'll print on the terminal in the first instance, and you probably don't want that, so you can pass the -c flag to send the password directly to your clipboard instead.

pass -c my-first-password
+

To edit a password, use pass edit:

pass edit my-first password
+

You'll see that on the first line of this file is your generated password. You can add more lines with notes or key-value pairs, which some clients can use for autofill:

<generated password here>
+Url: login.website.com
+Username: my-username
+

For more commands, see the password-store docs.

4. Set up sync

First, init the pass git repository:

pass git init
+

Then, go to your chosen git hosting provider and create a private repo. Once you have an empty private repo, you can go ahead and add the remote:

pass git remote add origin <repo git url>
+

Then, do your first push:

pass git push -u origin
+

Now when you go to view your repo, you'll see an encrypted file called my-first-password.gpg, which can only be read if you have your gpg key to hand.

If you want to auto-sync whenever a password is changed, add a post-commit hook to ~/.password-store/.git/hooks that pushs to your repo.

5. Integrating with other devices

Take a look at the list of compatible clients to find pass clients for your other devices. Most have pretty good docs on how to set them up, and most offer autofill and automatic syncing.

I would suggest creating a new gpg key or sub-key for each device so you can revoke them individually. For an extra layer of security, you can add a password to the keys, but this will impact UX.

6. Migrating from your old password manager

Now the only remaining step is to move your old passwords!

Fortunately there's a plethora of tools available!

+
+ Posted 2022-08-16 +
+
+ +← Put Ticket IDs in your Commit Messages + + + +
+ + diff --git a/posts/put-ticket-ids-in-your-commit-messages.html b/posts/put-ticket-ids-in-your-commit-messages.html index d03fc50..b0a7be2 100644 --- a/posts/put-ticket-ids-in-your-commit-messages.html +++ b/posts/put-ticket-ids-in-your-commit-messages.html @@ -34,6 +34,8 @@

Put Ticket IDs in your Commit Messages

In my previous post

Why I rolled my own

You might be wondering what the point is of setting up your own password manager is when so many good, paid alternatives exist – and you'd be right!

There is however, some advantage in knowing exactly how your passwords are encrypted and being able to integrate your password store with EVERYTHING.

And it's run at no cost to me.

Standard warnings apply; the UX will not be as good. If you do not back up your GPG keys, you could lose access to your passwords forever. The security of your password manager is only as good as the security of your system.

Features and composition

Our password manager will have the following features:

We'll make it with these components:

Make sure you have all the above installed before continuing!

Steps

1. Generate a gpg key

There's lots of guides on doing this, but here's an example (from 2022, if you're reading this in the future, google it first because best practice has probably changed!).

gpg --default-new-key-algo "ed25519/cert,sign+cv25519/encr" --quick-generate-key "my@email.com"
+            

Make your own (free) password manager

Before I say anything else, it should be noted that this solution requires a little bit of background knowledge to set up and use. At the very least you'll need to be comfortable on the command line in linux/osx, especially with installing packages, git, ssh, and a little gpg. Don't worry if you don't know all of that – a little familiarity should be enough.

Why I rolled my own

You might be wondering what the point is of setting up your own password manager is when so many good, paid alternatives exist – and you'd be right!

There is however, some advantage in knowing exactly how your passwords are encrypted and being able to integrate your password store with EVERYTHING.

And it's run at no cost to me.

Standard warnings apply; the UX will not be as good. If you do not back up your GPG keys, you could lose access to your passwords forever. The security of your password manager is only as good as the security of your system.

Features and composition

Our password manager will have the following features:

  • Encrypted at rest
  • Command line, web browser, and mobile clientship
  • Per-device revocation
  • Cross-device sync

We'll make it with these components:

Make sure you have all the above installed before continuing!

Steps

1. Generate a gpg key

There's lots of guides on doing this, but here's an example (from 2022, if you're reading this in the future, google it first because best practice has probably changed!).

gpg --default-new-key-algo "ed25519/cert,sign+cv25519/encr" \
+    --quick-generate-key "my@email.com"
 

This will generate a new multi-purpose ed25519 key with no expiration date.

It's up to you if you want to use this to generate subkeys to use for the password store. I would, however, recommend that you make one key per device sou you can revoke access if a device is lost or stolen!

If you've already got a gpg key and want to use it – use that.

**And before anything else - back up your key! On a storage drive, paper, obelisk, yubikey - and in more than one place!**

2. Init the password store

pass init <your gpg key id from step 1>
 

That's it! If you want to use multiple keys (e.g. one per device), just add any additional IDs after the first.

3. Add your first password

pass generate my-first-password 100
 

This will generate a random 100-character password for you named my-first-password.

It'll print on the terminal in the first instance, and you probably don't want that, so you can pass the -c flag to send the password directly to your clipboard instead.

pass -c my-first-password

From 4bbbbb1e83ccbfc2a9a7490ace5bc44e5d24f448 Mon Sep 17 00:00:00 2001
From: Site Builder Bot 
Date: Mon, 17 Jul 2023 10:37:12 +0000
Subject: [PATCH 35/43] www-build-41

---
 about.html                                    |  2 +-
 contact.html                                  |  2 +-
 index.html                                    |  4 +-
 posts/how-i-built-this-site.html              |  2 +-
 .../make-your-own-free-password-manager.html  |  4 +-
 posts/perfect-isnt-good-enough.html           |  2 +-
 posts/pifs-1-functions.html                   | 40 +++++++++++++++++++
 ...ut-ticket-ids-in-your-commit-messages.html |  2 +-
 posts/relearning-to-learn.html                |  2 +-
 posts/the-continuous-delivery-test.html       |  2 +-
 posts/the-documentation-triangle.html         |  2 +-
 11 files changed, 54 insertions(+), 10 deletions(-)
 create mode 100644 posts/pifs-1-functions.html

diff --git a/about.html b/about.html
index 76f09a3..a1379fc 100644
--- a/about.html
+++ b/about.html
@@ -7,7 +7,7 @@
         
         
         
-        
+        
         
         
         
diff --git a/contact.html b/contact.html
index 223456e..a93af30 100644
--- a/contact.html
+++ b/contact.html
@@ -7,7 +7,7 @@
         
         
         
-        
+        
         
         
         
diff --git a/index.html b/index.html
index 6159d09..e65f5df 100644
--- a/index.html
+++ b/index.html
@@ -7,7 +7,7 @@
         
         
         
-        
+        
         
         
         
@@ -29,6 +29,8 @@ 

sourceless



+ 2023-07-17 Programming in Functional Style: Functions
+ 2022-08-16 Make your own (free) password manager
2022-07-29 Put Ticket IDs in your Commit Messages
diff --git a/posts/how-i-built-this-site.html b/posts/how-i-built-this-site.html index 07083a0..955febf 100644 --- a/posts/how-i-built-this-site.html +++ b/posts/how-i-built-this-site.html @@ -7,7 +7,7 @@ - + diff --git a/posts/make-your-own-free-password-manager.html b/posts/make-your-own-free-password-manager.html index 7e406d1..d795f38 100644 --- a/posts/make-your-own-free-password-manager.html +++ b/posts/make-your-own-free-password-manager.html @@ -7,7 +7,7 @@ - + @@ -46,6 +46,8 @@

Make your own (free) password manager

Before I say anyth ← Put Ticket IDs in your Commit Messages +Programming in Functional Style: Functions → + diff --git a/posts/perfect-isnt-good-enough.html b/posts/perfect-isnt-good-enough.html index 9c7362d..eec0bd6 100644 --- a/posts/perfect-isnt-good-enough.html +++ b/posts/perfect-isnt-good-enough.html @@ -7,7 +7,7 @@ - + diff --git a/posts/pifs-1-functions.html b/posts/pifs-1-functions.html new file mode 100644 index 0000000..d91b3ed --- /dev/null +++ b/posts/pifs-1-functions.html @@ -0,0 +1,40 @@ + + + + + Sourceless - Programming in Functional Style: Functions + + + + + + + + + + + + +

sourceless

+ + +index + + about + + contact + + +

Programming in Functional Style: Functions

If you've been programming for more than a couple of years, you've probably heard of functional programming. You might even have picked up a functional language and played around with it.

Functional programming languages span a range of styles. On the one hand, you have LISP-style languages, the masters of which pull off incredible feats of language reinvention. On the other, you have Haskell wizards, whose carefully structured types give their programs and data structures properties that C programmes can only dream of.

However, functional programming is not confined to functional languages; the languages merely support the use of functional programs. So what does it mean to be functional?

Surely every programming language is functional, in the sense that it does something?

True – but "functional" in this context means centering your programs around functions.

Functions

You know what a function is, right? Well, you probably have some conception at least. You migh have heard it in a maths class, or you know it's what you make every time you write def or function().

Here's a very loose definition:

A function f is a transformation that takes some input X and returns some output f(X).

This limited definition does fall apart somewhat quickly, unfortunately.

Or does it?

Counterexample 1: Multiple inputs

Functions in <favourite language> can take multiple arguments, but the definition given only allows a single input!

I won't go into detail in this post about the various ways we can deal with this, but a simple solution to this is lists.

Something that looks like a function with N arguments can be transformed into a function with one argument that is a list of length N

Counterexample 2: The state of the world

Functions in <favourite language> might behave differently depending on their context!

This means that for some input X, there might be a different output for f(X)!

Unless, that is...

When something looks like a function, but changes depending on its context, you can turn it into a function by including the context in the input.

An example of this is reading a file. Depending what's on disk, you'll get a different result! But if you consider what's on disk to be part of the input...

Purity

I lied to you with the earlier definition of a function. What I actually gave was the definition of a pure function.

Why do we care about a function being pure, though? Isn't it a lot of hassle to rewrite inputs and pass the entire world to the function every time? Well yes, okay, if you insist. I promise that sometimes there's a good reason to want it though.

The best reason is that **you can always tell what a pure function's output will be just from its outputs**.

Sound useful yet? No? Uh... well, look, what does that imply? What can you do with a pure function that your everday javascript function doesn't let you do?

Referential Integrity

Okay, don't let your eyes glaze over. I promise that I'll stop using five-dollar words.

Consider that in a pure function, you can always tell what the output will bu just by knowing the input.

So, it's easier to reason about! Especially when you've got a lot of these pure functions glued together. And to wind back to 'referential integrity', all it means is that you can tell what the output will be just by looking at the input. There's no outside context involved.

Some languages, like Haskell, enforce this. Most others don't care. But you'll find this idea of things being easy to reason about pop up everywhere.

You just have to look.

Think about dependency injection. What is it really? It's about making a core program that you can plug the context into, so that you can make it easier to reason about – usually with the goal of making it easier to test!

There are other reasons you might have to want a program to be easy to reason aboub, such as wanting to prove it works a certain way, or wanting to match some existing modeling method.

But the practical upshot for most is that it makes building and testing code WAY easier.

Memoization

Sorry! I can't help myself! Does it help if I just say 'caching' instead?

Because that's all memoization really is. Caching at a micro level. And if you think about it, purity is really important to caching. If you want to load an image from a webserver quick, you want to cache it, right? But you can only do that if you're reasonably sure that the image is going to be the same one every time you ask for it.

So purity really matters when you want to cache something and avoid extra work.

Bringing it all together

So, what did we learn?

A pure function f tranforms some input X to an output f(X)

Pure functions are:

  • Easier to reason about
  • Easier to test
  • Have referential integrity
  • Can be easily memoized

I plan on doing a few more of these, so please reach out if this post helped you!

+
+ Posted 2023-07-17 +
+
+ +← Make your own (free) password manager + + + +
+ + diff --git a/posts/put-ticket-ids-in-your-commit-messages.html b/posts/put-ticket-ids-in-your-commit-messages.html index b0a7be2..57590b1 100644 --- a/posts/put-ticket-ids-in-your-commit-messages.html +++ b/posts/put-ticket-ids-in-your-commit-messages.html @@ -7,7 +7,7 @@ - + diff --git a/posts/relearning-to-learn.html b/posts/relearning-to-learn.html index c789043..4352038 100644 --- a/posts/relearning-to-learn.html +++ b/posts/relearning-to-learn.html @@ -7,7 +7,7 @@ - + diff --git a/posts/the-continuous-delivery-test.html b/posts/the-continuous-delivery-test.html index 6c0b3a4..b55f7ed 100644 --- a/posts/the-continuous-delivery-test.html +++ b/posts/the-continuous-delivery-test.html @@ -7,7 +7,7 @@ - + diff --git a/posts/the-documentation-triangle.html b/posts/the-documentation-triangle.html index da8f7aa..fc08a8c 100644 --- a/posts/the-documentation-triangle.html +++ b/posts/the-documentation-triangle.html @@ -7,7 +7,7 @@ - + From 6e9973ded1edfb4c52634f579aaaf49a57976e55 Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Mon, 17 Jul 2023 10:39:56 +0000 Subject: [PATCH 36/43] www-build-42 --- contact.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contact.html b/contact.html index a93af30..d805e7c 100644 --- a/contact.html +++ b/contact.html @@ -25,7 +25,7 @@

sourceless

contact -

E: laurence@[this website]\ T: @sourceless\ GH: sourceless\ HN: sourceless\ L: laurencejosephsmith

+ From 59c0dc610d4a59f6c10770a40cc28c54ae27eb92 Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Mon, 17 Jul 2023 10:43:51 +0000 Subject: [PATCH 37/43] www-build-43 --- assets/css/main.css | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/assets/css/main.css b/assets/css/main.css index ed58a98..138f692 100644 --- a/assets/css/main.css +++ b/assets/css/main.css @@ -34,3 +34,9 @@ pre { background: #1F2933; padding: 1em; } + +blockquote { + border-left: 0.5em solid white; + padding-left: 1.5em; + margin-left: 2em; +} From dbe5032467014e19f3cac824b7b377790df26890 Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Mon, 17 Jul 2023 10:44:31 +0000 Subject: [PATCH 38/43] www-build-44 --- posts/pifs-1-functions.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/posts/pifs-1-functions.html b/posts/pifs-1-functions.html index d91b3ed..35fddf1 100644 --- a/posts/pifs-1-functions.html +++ b/posts/pifs-1-functions.html @@ -25,7 +25,7 @@

sourceless

contact -

Programming in Functional Style: Functions

If you've been programming for more than a couple of years, you've probably heard of functional programming. You might even have picked up a functional language and played around with it.

Functional programming languages span a range of styles. On the one hand, you have LISP-style languages, the masters of which pull off incredible feats of language reinvention. On the other, you have Haskell wizards, whose carefully structured types give their programs and data structures properties that C programmes can only dream of.

However, functional programming is not confined to functional languages; the languages merely support the use of functional programs. So what does it mean to be functional?

Surely every programming language is functional, in the sense that it does something?

True – but "functional" in this context means centering your programs around functions.

Functions

You know what a function is, right? Well, you probably have some conception at least. You migh have heard it in a maths class, or you know it's what you make every time you write def or function().

Here's a very loose definition:

A function f is a transformation that takes some input X and returns some output f(X).

This limited definition does fall apart somewhat quickly, unfortunately.

Or does it?

Counterexample 1: Multiple inputs

Functions in <favourite language> can take multiple arguments, but the definition given only allows a single input!

I won't go into detail in this post about the various ways we can deal with this, but a simple solution to this is lists.

Something that looks like a function with N arguments can be transformed into a function with one argument that is a list of length N

Counterexample 2: The state of the world

Functions in <favourite language> might behave differently depending on their context!

This means that for some input X, there might be a different output for f(X)!

Unless, that is...

When something looks like a function, but changes depending on its context, you can turn it into a function by including the context in the input.

An example of this is reading a file. Depending what's on disk, you'll get a different result! But if you consider what's on disk to be part of the input...

Purity

I lied to you with the earlier definition of a function. What I actually gave was the definition of a pure function.

Why do we care about a function being pure, though? Isn't it a lot of hassle to rewrite inputs and pass the entire world to the function every time? Well yes, okay, if you insist. I promise that sometimes there's a good reason to want it though.

The best reason is that **you can always tell what a pure function's output will be just from its outputs**.

Sound useful yet? No? Uh... well, look, what does that imply? What can you do with a pure function that your everday javascript function doesn't let you do?

Referential Integrity

Okay, don't let your eyes glaze over. I promise that I'll stop using five-dollar words.

Consider that in a pure function, you can always tell what the output will bu just by knowing the input.

So, it's easier to reason about! Especially when you've got a lot of these pure functions glued together. And to wind back to 'referential integrity', all it means is that you can tell what the output will be just by looking at the input. There's no outside context involved.

Some languages, like Haskell, enforce this. Most others don't care. But you'll find this idea of things being easy to reason about pop up everywhere.

You just have to look.

Think about dependency injection. What is it really? It's about making a core program that you can plug the context into, so that you can make it easier to reason about – usually with the goal of making it easier to test!

There are other reasons you might have to want a program to be easy to reason aboub, such as wanting to prove it works a certain way, or wanting to match some existing modeling method.

But the practical upshot for most is that it makes building and testing code WAY easier.

Memoization

Sorry! I can't help myself! Does it help if I just say 'caching' instead?

Because that's all memoization really is. Caching at a micro level. And if you think about it, purity is really important to caching. If you want to load an image from a webserver quick, you want to cache it, right? But you can only do that if you're reasonably sure that the image is going to be the same one every time you ask for it.

So purity really matters when you want to cache something and avoid extra work.

Bringing it all together

So, what did we learn?

A pure function f tranforms some input X to an output f(X)

Pure functions are:

  • Easier to reason about
  • Easier to test
  • Have referential integrity
  • Can be easily memoized

I plan on doing a few more of these, so please reach out if this post helped you!

+

Programming in Functional Style: Functions

If you've been programming for more than a couple of years, you've probably heard of functional programming. You might even have picked up a functional language and played around with it.

Functional programming languages span a range of styles. On the one hand, you have LISP-style languages, the masters of which pull off incredible feats of language reinvention. On the other, you have Haskell wizards, whose carefully structured types give their programs and data structures properties that C programmes can only dream of.

However, functional programming is not confined to functional languages; the languages merely support the use of functional programs. So what does it mean to be functional?

Surely every programming language is functional, in the sense that it does something?

True – but "functional" in this context means centering your programs around functions.

Functions

You know what a function is, right? Well, you probably have some conception at least. You migh have heard it in a maths class, or you know it's what you make every time you write def or function().

Here's a very loose definition:

A function f is a transformation that takes some input X and returns some output f(X).

This limited definition does fall apart somewhat quickly, unfortunately.

Or does it?

Counterexample 1: Multiple inputs

Functions in <favourite language> can take multiple arguments, but the definition given only allows a single input!

I won't go into detail in this post about the various ways we can deal with this, but a simple solution to this is lists.

Something that looks like a function with N arguments can be transformed into a function with one argument that is a list of length N

Counterexample 2: The state of the world

Functions in <favourite language> might behave differently depending on their context!

This means that for some input X, there might be a different output for f(X)!

Unless, that is...

When something looks like a function, but changes depending on its context, you can turn it into a function by including the context in the input.

An example of this is reading a file. Depending what's on disk, you'll get a different result! But if you consider what's on disk to be part of the input...

Purity

I lied to you with the earlier definition of a function. What I actually gave was the definition of a pure function.

Why do we care about a function being pure, though? Isn't it a lot of hassle to rewrite inputs and pass the entire world to the function every time? Well yes, okay, if you insist. I promise that sometimes there's a good reason to want it though.

The best reason is that **you can always tell what a pure function's output will be just from its outputs**.

Sound useful yet? No? Uh... well, look, what does that imply? What can you do with a pure function that your everday javascript function doesn't let you do?

Referential Integrity

Okay, don't let your eyes glaze over. I promise that I'll stop using five-dollar words.

Consider that in a pure function, you can always tell what the output will bu just by knowing the input.

So, it's easier to reason about! Especially when you've got a lot of these pure functions glued together. And to wind back to 'referential integrity', all it means is that you can tell what the output will be just by looking at the input. There's no outside context involved.

Some languages, like Haskell, enforce this. Most others don't care. But you'll find this idea of things being easy to reason about pop up everywhere.

You just have to look.

Think about dependency injection. What is it really? It's about making a core program that you can plug the context into, so that you can make it easier to reason about – usually with the goal of making it easier to test!

There are other reasons you might have to want a program to be easy to reason aboub, such as wanting to prove it works a certain way, or wanting to match some existing modeling method.

But the practical upshot for most is that it makes building and testing code WAY easier.

Memoization

Sorry! I can't help myself! Does it help if I just say 'caching' instead?

Because that's all memoization really is. Caching at a micro level. And if you think about it, purity is really important to caching. If you want to load an image from a webserver quick, you want to cache it, right? But you can only do that if you're reasonably sure that the image is going to be the same one every time you ask for it.

So purity really matters when you want to cache something and avoid extra work.

Bringing it all together

So, what did we learn?

A pure function f tranforms some input X to an output f(X)

Pure functions:

  • Are easier to reason about
  • Are easier to test
  • Have referential integrity
  • Can be easily memoized

I plan on doing a few more of these, so please reach out if this post helped you!


Posted 2023-07-17
From 1c5fb6b15e63fb3602189673a3a2da9536781668 Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Tue, 22 Jul 2025 09:46:38 +0000 Subject: [PATCH 39/43] www-build-48 --- about.html | 4 ++-- contact.html | 4 ++-- index.html | 2 +- posts/how-i-built-this-site.html | 2 +- posts/make-your-own-free-password-manager.html | 2 +- posts/perfect-isnt-good-enough.html | 2 +- posts/pifs-1-functions.html | 2 +- posts/put-ticket-ids-in-your-commit-messages.html | 2 +- posts/relearning-to-learn.html | 2 +- posts/the-continuous-delivery-test.html | 2 +- posts/the-documentation-triangle.html | 2 +- 11 files changed, 13 insertions(+), 13 deletions(-) diff --git a/about.html b/about.html index a1379fc..e5daedc 100644 --- a/about.html +++ b/about.html @@ -7,7 +7,7 @@ - + @@ -25,7 +25,7 @@

sourceless

contact -

Hi, I'm Laurence Pakenham-Smith.

I'm an SRE Manager in the AdTech industry. In previous lives I've done SRE, security, and software in Healthcare and Government.

Notable past projects include:

My topics of particular interest are:

  • Building and running high performing teams
  • User-first security, compliance, and governance
  • Logic programming
  • Type systems

I've worked on a lot of projects in a lot of languages and frameworks; the best of those were backed by great teams that knew their tools inside out.

If you want to talk, or just want to see a CV, check out my linkedin.

+

Hi, I'm Aurora Mae.

I'm an Director of SRE in the AdTech industry. In previous lives I've done SRE, security, and software in Healthcare and Government.

Notable past projects include:

My topics of particular interest are:

  • Building and running high performing teams
  • User-first security, compliance, and governance
  • Logic programming
  • Type systems

I've worked on a lot of projects in a lot of languages and frameworks; the best of those were backed by great teams that knew their tools inside out.

If you want to talk, or just want to see a CV, check out my linkedin.

diff --git a/contact.html b/contact.html index d805e7c..43b2af6 100644 --- a/contact.html +++ b/contact.html @@ -7,7 +7,7 @@ - + @@ -25,7 +25,7 @@

sourceless

contact - + diff --git a/index.html b/index.html index e65f5df..aa7ba63 100644 --- a/index.html +++ b/index.html @@ -7,7 +7,7 @@ - + diff --git a/posts/how-i-built-this-site.html b/posts/how-i-built-this-site.html index 955febf..f98cebb 100644 --- a/posts/how-i-built-this-site.html +++ b/posts/how-i-built-this-site.html @@ -7,7 +7,7 @@ - + diff --git a/posts/make-your-own-free-password-manager.html b/posts/make-your-own-free-password-manager.html index d795f38..a0bd150 100644 --- a/posts/make-your-own-free-password-manager.html +++ b/posts/make-your-own-free-password-manager.html @@ -7,7 +7,7 @@ - + diff --git a/posts/perfect-isnt-good-enough.html b/posts/perfect-isnt-good-enough.html index eec0bd6..832ccad 100644 --- a/posts/perfect-isnt-good-enough.html +++ b/posts/perfect-isnt-good-enough.html @@ -7,7 +7,7 @@ - + diff --git a/posts/pifs-1-functions.html b/posts/pifs-1-functions.html index 35fddf1..6039e8f 100644 --- a/posts/pifs-1-functions.html +++ b/posts/pifs-1-functions.html @@ -7,7 +7,7 @@ - + diff --git a/posts/put-ticket-ids-in-your-commit-messages.html b/posts/put-ticket-ids-in-your-commit-messages.html index 57590b1..916a42c 100644 --- a/posts/put-ticket-ids-in-your-commit-messages.html +++ b/posts/put-ticket-ids-in-your-commit-messages.html @@ -7,7 +7,7 @@ - + diff --git a/posts/relearning-to-learn.html b/posts/relearning-to-learn.html index 4352038..3ad05bc 100644 --- a/posts/relearning-to-learn.html +++ b/posts/relearning-to-learn.html @@ -7,7 +7,7 @@ - + diff --git a/posts/the-continuous-delivery-test.html b/posts/the-continuous-delivery-test.html index b55f7ed..fc2b20c 100644 --- a/posts/the-continuous-delivery-test.html +++ b/posts/the-continuous-delivery-test.html @@ -7,7 +7,7 @@ - + diff --git a/posts/the-documentation-triangle.html b/posts/the-documentation-triangle.html index fc08a8c..4fd9fad 100644 --- a/posts/the-documentation-triangle.html +++ b/posts/the-documentation-triangle.html @@ -7,7 +7,7 @@ - + From 4432c11df114e8f8571af64b42298ce0ee3e82fa Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Sat, 14 Mar 2026 07:09:30 +0000 Subject: [PATCH 40/43] www-build-49 --- about.html | 4 ++-- contact.html | 2 +- index.html | 2 +- posts/how-i-built-this-site.html | 2 +- posts/make-your-own-free-password-manager.html | 2 +- posts/perfect-isnt-good-enough.html | 2 +- posts/pifs-1-functions.html | 2 +- posts/put-ticket-ids-in-your-commit-messages.html | 2 +- posts/relearning-to-learn.html | 2 +- posts/the-continuous-delivery-test.html | 2 +- posts/the-documentation-triangle.html | 2 +- 11 files changed, 12 insertions(+), 12 deletions(-) diff --git a/about.html b/about.html index e5daedc..24e24c8 100644 --- a/about.html +++ b/about.html @@ -7,7 +7,7 @@ - + @@ -25,7 +25,7 @@

sourceless

contact -

Hi, I'm Aurora Mae.

I'm an Director of SRE in the AdTech industry. In previous lives I've done SRE, security, and software in Healthcare and Government.

Notable past projects include:

My topics of particular interest are:

  • Building and running high performing teams
  • User-first security, compliance, and governance
  • Logic programming
  • Type systems

I've worked on a lot of projects in a lot of languages and frameworks; the best of those were backed by great teams that knew their tools inside out.

If you want to talk, or just want to see a CV, check out my linkedin.

+

Hi, I'm Laurence.

I'm an Director of SRE in the AdTech industry. In previous lives I've done SRE, security, and software in Healthcare and Government.

Notable past projects include:

My topics of particular interest are:

  • Building and running high performing teams
  • User-first security, compliance, and governance
  • Logic programming
  • Type systems

I've worked on a lot of projects in a lot of languages and frameworks; the best of those were backed by great teams that knew their tools inside out.

If you want to talk, or just want to see a CV, check out my linkedin.

diff --git a/contact.html b/contact.html index 43b2af6..fcac559 100644 --- a/contact.html +++ b/contact.html @@ -7,7 +7,7 @@ - + diff --git a/index.html b/index.html index aa7ba63..8754a0b 100644 --- a/index.html +++ b/index.html @@ -7,7 +7,7 @@ - + diff --git a/posts/how-i-built-this-site.html b/posts/how-i-built-this-site.html index f98cebb..9ecc862 100644 --- a/posts/how-i-built-this-site.html +++ b/posts/how-i-built-this-site.html @@ -7,7 +7,7 @@ - + diff --git a/posts/make-your-own-free-password-manager.html b/posts/make-your-own-free-password-manager.html index a0bd150..9333db0 100644 --- a/posts/make-your-own-free-password-manager.html +++ b/posts/make-your-own-free-password-manager.html @@ -7,7 +7,7 @@ - + diff --git a/posts/perfect-isnt-good-enough.html b/posts/perfect-isnt-good-enough.html index 832ccad..9e24331 100644 --- a/posts/perfect-isnt-good-enough.html +++ b/posts/perfect-isnt-good-enough.html @@ -7,7 +7,7 @@ - + diff --git a/posts/pifs-1-functions.html b/posts/pifs-1-functions.html index 6039e8f..8f8951d 100644 --- a/posts/pifs-1-functions.html +++ b/posts/pifs-1-functions.html @@ -7,7 +7,7 @@ - + diff --git a/posts/put-ticket-ids-in-your-commit-messages.html b/posts/put-ticket-ids-in-your-commit-messages.html index 916a42c..58e2590 100644 --- a/posts/put-ticket-ids-in-your-commit-messages.html +++ b/posts/put-ticket-ids-in-your-commit-messages.html @@ -7,7 +7,7 @@ - + diff --git a/posts/relearning-to-learn.html b/posts/relearning-to-learn.html index 3ad05bc..7f1215a 100644 --- a/posts/relearning-to-learn.html +++ b/posts/relearning-to-learn.html @@ -7,7 +7,7 @@ - + diff --git a/posts/the-continuous-delivery-test.html b/posts/the-continuous-delivery-test.html index fc2b20c..d293722 100644 --- a/posts/the-continuous-delivery-test.html +++ b/posts/the-continuous-delivery-test.html @@ -7,7 +7,7 @@ - + diff --git a/posts/the-documentation-triangle.html b/posts/the-documentation-triangle.html index 4fd9fad..1c1370c 100644 --- a/posts/the-documentation-triangle.html +++ b/posts/the-documentation-triangle.html @@ -7,7 +7,7 @@ - + From 64f9482140dcba73af33bfed0882cb392d8d9cb2 Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Sat, 14 Mar 2026 07:09:46 +0000 Subject: [PATCH 41/43] www-build-50 --- contact.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contact.html b/contact.html index fcac559..567a5c1 100644 --- a/contact.html +++ b/contact.html @@ -25,7 +25,7 @@

sourceless

contact - + From ef5deb276c769b86223d2e7bc24597a73e4c3fa3 Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Mon, 30 Mar 2026 10:42:11 +0000 Subject: [PATCH 42/43] www-build-51 --- index.html | 2 ++ posts/pifs-1-functions.html | 2 ++ posts/the-phoenix-reborn.html | 40 +++++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+) create mode 100644 posts/the-phoenix-reborn.html diff --git a/index.html b/index.html index 8754a0b..6ae9318 100644 --- a/index.html +++ b/index.html @@ -29,6 +29,8 @@

sourceless



+ 2026-03-30 The Phoenix Reborn
+ 2023-07-17 Programming in Functional Style: Functions
2022-08-16 Make your own (free) password manager
diff --git a/posts/pifs-1-functions.html b/posts/pifs-1-functions.html index 8f8951d..564cb25 100644 --- a/posts/pifs-1-functions.html +++ b/posts/pifs-1-functions.html @@ -34,6 +34,8 @@

Programming in Functional Style: Functions

If you've been programming ← Make your own (free) password manager +The Phoenix Reborn → + diff --git a/posts/the-phoenix-reborn.html b/posts/the-phoenix-reborn.html new file mode 100644 index 0000000..bc68ccf --- /dev/null +++ b/posts/the-phoenix-reborn.html @@ -0,0 +1,40 @@ + + + + + Sourceless - The Phoenix Reborn + + + + + + + + + + + + +

sourceless

+ + +index + + about + + contact + + +

The Phoenix Reborn

If you haven't read "The Phoenix Project" yet, this is your sign from the universe telling you that it's time. Go on, this post will still be here when you get back?

Still here? Cool.

A very quick Phoenix Project Recap

An extremely condensed take of the central point of "The Phoenix Project" is:

Shorten feedback loops as much as possible

In the book and day-to-day devops, that's achieved in several ways:

  • Colocating ops resources on dev teams, instead of siloing them in separate orgs
  • Making use of CI to provide fast feedback in a dev-like environment
  • Making use of tests in the development flow
  • Having prod-like environments available for testing

Each of these seeks to reduce the amount of time a problem sits waiting before it can be addressed by someone with the knowledge to fix it.

Code is free but you are still in chains

The change in quality of output from top-tier LLMs in late 2025 changed the game. Code is now easy to produce in good quality and high quantity. The new gap is one that has always existed: *understand whole problems and write a plan detailed enough to make a solution*.

Spec-driven development is a particularly promising output of this; structured input that captures every possible problem, solution, and decision in a small problem space.

But specs alone aren't enough; fortunately, however, Claude and co are very, VERY good at writing tests, pipelines, and just about any other verification tooling you could ever want, including lightweight (or heavyweight!) formal methods.

Give the AI the tools it needs to succeed

This is the only takeaway that you need from this post. *You must shorten the feedback loops for the AI as much as possible*. You need to make it possible for it to test its own work if you want high quality outputs.

At a minimum:

  • Linter
  • Autoformatter
  • Tests
  • CI/CD pipelines (and access to read/run them!)

Make your AI aware of them, make it use them, and make it constantly review its own work (or get another model to do it).

+
+ Posted 2026-03-30 +
+
+ +← Programming in Functional Style: Functions + + + +
+ + From c0748def6773d1e931b6da41a6cca8fbcec83c13 Mon Sep 17 00:00:00 2001 From: Site Builder Bot Date: Mon, 30 Mar 2026 10:52:42 +0000 Subject: [PATCH 43/43] www-build-52 --- posts/the-phoenix-reborn.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/posts/the-phoenix-reborn.html b/posts/the-phoenix-reborn.html index bc68ccf..7402dd0 100644 --- a/posts/the-phoenix-reborn.html +++ b/posts/the-phoenix-reborn.html @@ -25,7 +25,7 @@

sourceless

contact -

The Phoenix Reborn

If you haven't read "The Phoenix Project" yet, this is your sign from the universe telling you that it's time. Go on, this post will still be here when you get back?

Still here? Cool.

A very quick Phoenix Project Recap

An extremely condensed take of the central point of "The Phoenix Project" is:

Shorten feedback loops as much as possible

In the book and day-to-day devops, that's achieved in several ways:

  • Colocating ops resources on dev teams, instead of siloing them in separate orgs
  • Making use of CI to provide fast feedback in a dev-like environment
  • Making use of tests in the development flow
  • Having prod-like environments available for testing

Each of these seeks to reduce the amount of time a problem sits waiting before it can be addressed by someone with the knowledge to fix it.

Code is free but you are still in chains

The change in quality of output from top-tier LLMs in late 2025 changed the game. Code is now easy to produce in good quality and high quantity. The new gap is one that has always existed: *understand whole problems and write a plan detailed enough to make a solution*.

Spec-driven development is a particularly promising output of this; structured input that captures every possible problem, solution, and decision in a small problem space.

But specs alone aren't enough; fortunately, however, Claude and co are very, VERY good at writing tests, pipelines, and just about any other verification tooling you could ever want, including lightweight (or heavyweight!) formal methods.

Give the AI the tools it needs to succeed

This is the only takeaway that you need from this post. *You must shorten the feedback loops for the AI as much as possible*. You need to make it possible for it to test its own work if you want high quality outputs.

At a minimum:

  • Linter
  • Autoformatter
  • Tests
  • CI/CD pipelines (and access to read/run them!)

Make your AI aware of them, make it use them, and make it constantly review its own work (or get another model to do it).

+

The Phoenix Reborn

If you haven't read "The Phoenix Project" yet, this is your sign from the universe telling you that it's time. Go on, this post will still be here when you get back.

Still here? Cool.

A very quick Phoenix Project Recap

An extremely condensed take on the central point of "The Phoenix Project" is:

Shorten feedback loops as much as possible

In the book and day-to-day DevOps, that's achieved in several ways:

  • Colocating ops resources on dev teams, instead of siloing them in separate orgs
  • Making use of CI to provide fast feedback in a dev-like environment
  • Making use of tests in the development flow
  • Having prod-like environments available for testing

Each of these seeks to reduce the amount of time a problem sits waiting before it can be addressed by someone with the knowledge to fix it.

Code is free but specification is still expensive

The step in quality of output from top-tier LLMs in late 2025 changed the game. Code is now easy to produce in good quality and high quantity. The new gap is one that has always existed: understand whole problems and write a plan detailed enough to make a solution.

Spec-driven development is a particularly promising output of this; structured input that captures every possible problem, solution, and decision in a small problem space.

But specs alone aren't enough; fortunately, however, Claude and co are very, VERY good at writing tests, pipelines, and just about any other verification tooling you could ever want, including lightweight (or heavyweight!) formal methods.

Give the AI the tools it needs to succeed

This is the only takeaway that you need from this post. *You must shorten the feedback loops for the AI as much as possible*. You need to make it possible for it to test its own work if you want high quality outputs.

At a minimum:

  • Linter
  • Autoformatter
  • Tests
  • CI/CD pipelines

This is how you provide fast feedback and get good results; it's exactly the same principle that devops was built on.

Make your AI aware of them, make it use them, and make it constantly review its own work (or get another model to do it).


Posted 2026-03-30