Skip to content
Merged
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
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @PhilippTheServer @maltonoloco
3 changes: 3 additions & 0 deletions .github/workflows/check-wiki.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ jobs:
with:
python-version: '3.14'

- name: Community files
run: test -f CODE_OF_CONDUCT.md && test -f CONTRIBUTING.md && test -f .github/CODEOWNERS

- name: Check every endpoint is documented and every documented path exists
run: python3 tools/check_wiki.py

Expand Down
72 changes: 72 additions & 0 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Code of Conduct

OpenTaberna is built by people who care about getting things right, and who sometimes
get loud when they don't. That is fine. What is not fine is taking it out on each other.

## The one rule that makes this project different

**Swear at code all you like. Never swear at people.**

Allowed:

- "This function is a goddamn mess."
- "Who the hell thought a 400-line regex was a good idea? Let's rip it out."
- "This build is fucked again."

Not allowed:

- "You're an idiot for writing this."
- "Only a moron would ship this."
- Anything aimed at a person's intelligence, competence, identity or worth, whether it
contains swear words or not.

Criticise the work, never the person who made it. Assume the author had a reason, ask
what it was, and then say how to make it better. If you would be embarrassed to say it to
their face in a room with everyone else present, don't write it.

## What we expect

- Be respectful of differing viewpoints and experience levels.
- Give feedback that is concrete and actionable, and take feedback the same way.
- Own your mistakes, apologise to the people affected, and learn from it.
- Focus on what is best for the project and the people using it.

## What we do not tolerate

- Insults, slurs or demeaning remarks about anyone, including profanity directed at a
person.
- Harassment, in public or in private, including continued contact after being asked to
stop.
- Discrimination based on age, body size, disability, ethnicity, sex characteristics,
gender identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity and orientation.
- Sexualised language or imagery, and unwelcome sexual attention.
- Publishing others' private information without their explicit permission.
- Trolling, and deliberately derailing discussions.

## Scope

This applies in every OpenTaberna space — repositories, issues, pull requests, reviews,
chats — and when you represent the project elsewhere.

## Reporting

Report anything that breaks this code to the maintainers, @PhilippTheServer or
@maltonoloco. Reports are handled privately, and the reporter's identity is protected.

## Enforcement

Maintainers decide what counts as a breach and respond in proportion:

1. **Correction** — a private note explaining what was wrong. A public apology may be
requested.
2. **Warning** — a formal warning with consequences for repeat behaviour.
3. **Temporary ban** — no interaction with the project for a set period.
4. **Permanent ban** — for repeated or severe breaches, including harassment.

Maintainers may remove or edit comments, commits, code, issues and other contributions
that break this code.

## Attribution

Adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 2.1.
37 changes: 37 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Contributing

Thanks for helping out. Read the [Code of Conduct](CODE_OF_CONDUCT.md) first — swearing
about code is fine, swearing at people is not.

## How a change gets in

`main` is protected. Only the maintainers, @PhilippTheServer and @maltonoloco, can push
to it directly. Everyone else goes through a pull request:

1. **Open an issue** describing the behaviour you expect once it is solved. Small fixes
too — it is where the discussion lives.
2. **Branch** from `main` (or fork, if you have no write access).
3. **Commit and push** your branch.
4. **Open a pull request** against `main` and link the issue with `Closes #N` in the
body.
5. **CI must pass.** These checks are required before the PR can be merged:
- `Wiki matches the API`
- `Wiki.js stack serves the pages with no login`
6. **A maintainer must approve.** Every file is owned by @PhilippTheServer and
@maltonoloco (see [.github/CODEOWNERS](.github/CODEOWNERS)); one of them has to
review and approve. New commits after an approval need a fresh approval.
7. **Squash merge.** The PR lands as a single commit on `main`; delete the branch
afterwards.

## Before you open the PR

Run the same checks locally so CI has no surprises:

```sh
python3 tools/check_wiki.py
docker compose up -d db wiki && docker compose run --rm bootstrap
python3 tools/check_wikijs.py
```

Update the docs in the same PR as the change, not afterwards, and add a test that would
fail if your fix regressed.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ That is the point at which the check bites: pulling in a snapshot with a new end
the check fail until somebody documents it. Refreshing the snapshot and updating the pages
belong in the same change.

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) and the [Code of Conduct](CODE_OF_CONDUCT.md).

## Conventions

- Front matter stays. Wiki.js uses `title`, `description`, `published`, `date`, `tags`,
Expand Down
5 changes: 4 additions & 1 deletion tools/check_wiki.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@
ROOT = Path(__file__).resolve().parent.parent
SNAPSHOT = ROOT / "openapi.snapshot.json"

# Present in the repository, deliberately not published as a wiki page.
NOT_WIKI_PAGES = {"README", "CODE_OF_CONDUCT", "CONTRIBUTING"}

# Paths the wiki is allowed to mention without them being API endpoints.
IGNORED_PATHS = {"/health/live"}

Expand Down Expand Up @@ -66,7 +69,7 @@ def wiki_pages() -> list[Path]:
return sorted(
p
for p in ROOT.rglob("*.md")
if ".git" not in p.parts and p.name != "README.md"
if ".git" not in p.parts and p.stem not in NOT_WIKI_PAGES
)


Expand Down
2 changes: 1 addition & 1 deletion tools/check_wikijs.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
WIKI_URL = os.environ.get("WIKI_URL", "http://localhost:3000").rstrip("/")

# Present in the repository, deliberately not published as a wiki page.
NOT_WIKI_PAGES = {"README"}
NOT_WIKI_PAGES = {"README", "CODE_OF_CONDUCT", "CONTRIBUTING"}

LOGIN_MARKERS = ("login-container", "loginBgUrl", "Sign In")

Expand Down
5 changes: 4 additions & 1 deletion tools/serve.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
ROOT = Path(__file__).resolve().parent.parent
PORT = 8090

# Present in the repository, deliberately not published as a wiki page.
NOT_WIKI_PAGES = {"README", "CODE_OF_CONDUCT", "CONTRIBUTING"}

SHELL = """<!doctype html>
<html lang="en">
<head>
Expand Down Expand Up @@ -169,7 +172,7 @@ def pages() -> list[str]:
found = sorted(
p.relative_to(ROOT).as_posix()
for p in ROOT.rglob("*.md")
if ".git" not in p.parts and p.name != "README.md"
if ".git" not in p.parts and p.stem not in NOT_WIKI_PAGES
)
# home first, it is the landing page
found.sort(key=lambda p: (p != "home.md", p))
Expand Down
5 changes: 3 additions & 2 deletions wikijs/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
mirror, not a forum.
3. Points the Local File System storage target at the mounted repository and
imports every Markdown page.
4. Removes README, which documents the repository rather than the project.
4. Removes README, CODE_OF_CONDUCT and CONTRIBUTING, which document the
repository rather than the project.
5. Rebuilds the sidebar so every page is reachable without knowing its URL.
6. Verifies guests can read without logging in, and grants it if not.

Expand All @@ -37,7 +38,7 @@
ADMIN_PASSWORD = os.environ.get("ADMIN_PASSWORD", "opentaberna-local-admin")

# Pages that exist in the repository but are not wiki content.
NOT_WIKI_PAGES = {"README"}
NOT_WIKI_PAGES = {"README", "CODE_OF_CONDUCT", "CONTRIBUTING"}

GUEST_GROUP_ID = 2
READ_PERMISSIONS = ["read:pages", "read:assets", "read:comments"]
Expand Down
Loading