Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate a checklist from all recommendations #1

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,8 @@ jobs:
run: |
./mdbook build
./mdbook test

- name: Confirm that the checklist is up to date
run: |
./export_checklist.py
git diff --exit-code
77 changes: 77 additions & 0 deletions checklist.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Checklist

This checklist summarizes the recommendations in all the chapters.
The main purpose of this page is to have a markdown checklist that
we can copy into an issue for internal due diligence processes. It
is not part of the book itself. Rebuild with `export_checklist.py`.

## P0

#### Software development best practices
- [ ] [Respect licenses of upstream software.](https://handbook.chorus.one/node-software/development-practices.html#respect-licenses)
- [ ] [Break down changes into logical parts and write a clear commit message for each change.](https://handbook.chorus.one/node-software/development-practices.html#good-commits)
- [ ] [Use comments to clarify non-obvious code.](https://handbook.chorus.one/node-software/development-practices.html#use-comments)

#### Open source software
- [ ] [Be transparent about the provenance of your source code.](https://handbook.chorus.one/node-software/open-source.html#provenance-transparency)

## P1

#### Build process
- [ ] [Ensure your software can be built on a stock Ubuntu LTS installation.](https://handbook.chorus.one/node-software/build-process.html#builds-on-ubuntu)
- [ ] [Don’t require Docker as part of your build process.](https://handbook.chorus.one/node-software/build-process.html#no-docker)
- [ ] [Don’t fetch untrusted binaries from the Internet as part of your build scripts.](https://handbook.chorus.one/node-software/build-process.html#no-fetch-untrusted-binaries)
- [ ] [Include a `rust-toolchain.toml` file in your repository.](https://handbook.chorus.one/node-software/build-process.html#use-rust-toolchain)

#### Software development best practices
- [ ] [Write automated tests that are included in the repository.](https://handbook.chorus.one/node-software/development-practices.html#automated-tests)
- [ ] [Have a code review process.](https://handbook.chorus.one/node-software/development-practices.html#code-review)
- [ ] [Write clear pull request, merge request, or changelist descriptions.](https://handbook.chorus.one/node-software/development-practices.html#write-clear-pr-descriptions)
- [ ] [Set up continuous integration.](https://handbook.chorus.one/node-software/development-practices.html#continuous-integration)

#### Monitoring
- [ ] [Expose Prometheus metrics.](https://handbook.chorus.one/node-software/monitoring.html#expose-prometheus-metrics)
- [ ] [Expose metrics privately.](https://handbook.chorus.one/node-software/monitoring.html#expose-metrics-privately)

#### Open source software
- [ ] [Release the project under an open source license.](https://handbook.chorus.one/node-software/open-source.html#publish-open-source)

#### Release engineering
- [ ] [Publish the source code in a public Git repository.](https://handbook.chorus.one/node-software/release-engineering.html#public-git-repo)
- [ ] [Mark releases with a Git tag.](https://handbook.chorus.one/node-software/release-engineering.html#use-git-tags)
- [ ] [Use _annotated_ Git tags.](https://handbook.chorus.one/node-software/release-engineering.html#use-annotated-tags)
- [ ] [Do not — never ever — re-tag.](https://handbook.chorus.one/node-software/release-engineering.html#no-retagging)
- [ ] [When using submodules, use `https` transport urls.](https://handbook.chorus.one/node-software/release-engineering.html#submodule-use-https-transport)

## P2

#### Software development best practices
- [ ] [Write fuzz tests for code that deals with user input (network or user data).](https://handbook.chorus.one/node-software/development-practices.html#fuzz-tests)
- [ ] [Set up a bug bounty program.](https://handbook.chorus.one/node-software/development-practices.html#bug-bounty-program)
- [ ] [Set up a responsible disclosure policy.](https://handbook.chorus.one/node-software/development-practices.html#responsible-disclosure-policy)

#### Monitoring
- [ ] [Ensure telemetry can be disabled.](https://handbook.chorus.one/node-software/monitoring.html#telemetry-can-be-disabled)

#### Open source software
- [ ] [Ensure that node operators can build security fixes from source.](https://handbook.chorus.one/node-software/open-source.html#security-fixes-source)

#### Release engineering
- [ ] [Publish metadata about the release in an easily discoverable location.](https://handbook.chorus.one/node-software/release-engineering.html#publish-release-metadata)
- [ ] [Use the same number of parts in every version number.](https://handbook.chorus.one/node-software/release-engineering.html#version-number-parts)
- [ ] [Use consistent suffixes to mark pre-release versions.](https://handbook.chorus.one/node-software/release-engineering.html#consistent-suffixes)
- [ ] [Publish a release at least one week before an update deadline.](https://handbook.chorus.one/node-software/release-engineering.html#publish-headroom)
- [ ] [Do not release on Fridays.](https://handbook.chorus.one/node-software/release-engineering.html#no-release-friday)
- [ ] [Do not release just before a holiday.](https://handbook.chorus.one/node-software/release-engineering.html#no-release-holiday)

## P3

#### Monitoring
- [ ] [Respect Prometheus metric and label naming standards.](https://handbook.chorus.one/node-software/monitoring.html#respect-prometheus-standards)

#### Open source software
- [ ] [Build in the open.](https://handbook.chorus.one/node-software/open-source.html#build-in-the-open)

#### Release engineering
- [ ] [Keep a changelog.](https://handbook.chorus.one/node-software/release-engineering.html#keep-a-changelog)

115 changes: 115 additions & 0 deletions export_checklist.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
#!/usr/bin/env python3
# Copyright 2024 Chorus One, licensed CC BY-NC-SA 4.0.
"""
export_checklist.py -- Export all recommendations as Markdown checklist.
"""

from collections import defaultdict
from typing import Dict, Iterable, List, NamedTuple, Optional

import textwrap
import os
import sys


class Recommendation(NamedTuple):
chapter: str
file: str
id: str
priority: int
title: str

def get_url(self) -> str:
slug = self.file.removeprefix("src/").removesuffix(".md")
return f"https://handbook.chorus.one/{slug}.html#{self.id}"


def list_md_files() -> Iterable[str]:
for root, dirs, files in os.walk("src"):
for file in files:
if file.endswith(".md"):
yield os.path.join(root, file)


def list_recommendations(fname: str) -> Iterable[Recommendation]:
chapter: Optional[str] = None

with open(fname, "r", encoding="utf-8") as f:
for i, line in enumerate(f):
if line.startswith("# "):
chapter = line[2:].strip()

if line.startswith("#### "):
try:
# Recommendation lines are of the form `#### Title {.prio # #id}\n".
title = line.removeprefix("#### ")
title, meta = title.rsplit("{", maxsplit=1)
meta = meta.strip().removesuffix("}")
prio_str, id_str = meta.split(" ", maxsplit=1)
assert prio_str.startswith(
".p"
), "Recommendation line must end in `{.pN #id}`."
assert id_str.startswith(
"#"
), "Recommendation line must end in `{.pN #id}`."
assert chapter is not None, "Must have # chapter title before ####."

yield Recommendation(
chapter=chapter,
file=fname,
id=id_str[1:],
priority=int(prio_str[2:]),
title=title.strip(),
)

except Exception as exc:
print(f"Error in {fname} at line {i + 1}:", file=sys.stderr)
print(f"{i + 1} | {line}", end="", file=sys.stderr)
print(f"Error: {exc}", file=sys.stderr)
sys.exit(1)


def main() -> None:
by_priority: Dict[int, List[Recommendation]] = defaultdict(lambda: [])
out_fname = "checklist.md"

for fname in sorted(list_md_files()):
# In the intro we list the priority categories, they are not themselves
# recommendations.
if fname == "src/node-software/intro.md":
continue

for rec in list_recommendations(fname):
by_priority[rec.priority].append(rec)

with open(out_fname, "w", encoding="utf-8") as f:
f.write(textwrap.dedent(
"""
# Checklist

This checklist summarizes the recommendations in all the chapters.
The main purpose of this page is to have a markdown checklist that
we can copy into an issue for internal due diligence processes. It
is not part of the book itself. Rebuild with `export_checklist.py`.
"""
).strip())
f.write("\n\n")

for priority, recommendations in sorted(by_priority.items()):
f.write(f"## P{priority}\n")

chapter = ""
for rec in recommendations:
if rec.chapter != chapter:
f.write(f"\n#### {rec.chapter}\n")
chapter = rec.chapter

f.write(f" - [ ] [{rec.title}]({rec.get_url()})\n")

f.write("\n")

print(f"Checklist written to {out_fname}.")


if __name__ == "__main__":
main()
2 changes: 1 addition & 1 deletion src/node-software/build-process.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ that download from official registries are of course fine.
> This section is a work in progress.

<!-- TODO: Fill out Go build advice.
#### Include a `go.mod` file that specifies which version of the Go toolchain your project should be built with.
TODO #### Include a `go.mod` file that specifies which version of the Go toolchain your project should be built with.
-->

## Rust recommendations
Expand Down