recipe-maintainer: public snapshot (secrets + deployment plans removed, single commit)

Sanitized single-commit public mirror of recipe-maintainer.
- Removed test-ssh/.testenv (live creds); added test-ssh/.testenv.example placeholders.
- Removed plans/ and planned-updates/ (deployment-planning docs) so no client/
  deployment domains appear in the public repo.
- All other secret stores were already gitignored.
- docs.coopcloud.tech retained as a submodule (public upstream).
This commit is contained in:
2026-06-16 20:18:24 +00:00
commit f283a371bb
253 changed files with 15975 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
name = "hedgedoc"
+25
View File
@@ -0,0 +1,25 @@
# HedgeDoc — First-Time Setup
## Prerequisites
- DNS: `hedgedoc.<domain_suffix>` must resolve to the server
## Steps
1. **Create the app:**
```bash
abra app new hedgedoc --server <SERVER> --domain hedgedoc.<DOMAIN_SUFFIX> --no-input
```
2. **Generate secrets:**
```bash
abra app secret generate hedgedoc.<DOMAIN_SUFFIX> --all -m --no-input
```
Save output to `recipe-info/testsecrets/hedgedoc.<DOMAIN_SUFFIX>`.
3. **Deploy:**
```bash
abra app deploy hedgedoc.<DOMAIN_SUFFIX> --chaos --force --no-input
```
4. **Verify:** curl `https://hedgedoc.<DOMAIN_SUFFIX>` returns HTTP 200.
+20
View File
@@ -0,0 +1,20 @@
# HedgeDoc Tests
## Target
- **URL:** https://hedgedoc.<DOMAIN_SUFFIX>
## Automated Checks
Run the scripts in `tests/` to perform automated testing:
- `health_check.py` — Confirms the instance is reachable and returns HTTP 200.
- `create_note.py` — Creates a note via the API, downloads it, and verifies the content matches. Covers note creation and persistence.
- `websocket_check.py` — Verifies the Socket.IO transport is responding with a valid handshake.
## Manual Verification
Full UI/UX testing (visual rendering, interactive editing experience) still benefits from human browser testing:
1. Open https://hedgedoc.<DOMAIN_SUFFIX> in a browser.
2. Confirm the HedgeDoc landing page loads without errors.
+75
View File
@@ -0,0 +1,75 @@
#!/usr/bin/env python3
"""Create and verify a note on HedgeDoc."""
import argparse
import os
import sys
import time
import urllib.request
import urllib.error
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', '..'))
from utils.tests.helpers import resolve_domain
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--domain', default=os.environ.get('TEST_DOMAIN'))
args = parser.parse_args()
domain = args.domain or resolve_domain('hedgedoc')
url = f"https://{domain}"
timestamp = str(int(time.time()))
test_content = f"# Test Note {timestamp}\n\nThis is an automated test note created at {timestamp}."
print(f"Creating a test note on {url} ...")
# POST a new note and capture the redirect URL
data = test_content.encode('utf-8')
req = urllib.request.Request(f"{url}/new", data=data, method="POST")
req.add_header("Content-Type", "text/markdown")
try:
# HedgeDoc returns a redirect - we need to NOT follow it
opener = urllib.request.build_opener(NoRedirectHandler())
resp = opener.open(req, timeout=15)
redirect_url = resp.headers.get('Location', '')
except urllib.error.HTTPError as e:
if e.code in (301, 302, 303, 307, 308):
redirect_url = e.headers.get('Location', '')
else:
print(f"FAIL: POST /new returned HTTP {e.code}")
sys.exit(1)
if not redirect_url:
print("FAIL: No redirect URL returned from POST /new")
sys.exit(1)
# Extract the note ID from the redirect URL (last path segment)
note_id = redirect_url.rstrip('/').split('/')[-1]
print(f"Created note: {note_id}")
# Download the note content and verify it matches
print("Downloading note content ...")
download_req = urllib.request.Request(f"{url}/{note_id}/download")
try:
with urllib.request.urlopen(download_req, timeout=15) as resp:
downloaded = resp.read().decode('utf-8')
except Exception as e:
print(f"FAIL: Could not download note: {e}")
sys.exit(1)
if f"Test Note {timestamp}" in downloaded:
print(f"PASS: Note created and content verified (id: {note_id})")
else:
print("FAIL: Downloaded content does not match posted content")
print(f"Expected to find: Test Note {timestamp}")
print(f"Got: {downloaded}")
sys.exit(1)
class NoRedirectHandler(urllib.request.HTTPRedirectHandler):
def redirect_request(self, req, fp, code, msg, headers, newurl):
raise urllib.error.HTTPError(newurl, code, msg, headers, fp)
if __name__ == '__main__':
main()
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env python3
"""Health check for HedgeDoc."""
import argparse
import os
import sys
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', '..'))
from utils.tests.helpers import http_get, resolve_domain
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--domain', default=os.environ.get('TEST_DOMAIN'))
args = parser.parse_args()
domain = args.domain or resolve_domain('hedgedoc')
url = f"https://{domain}"
print(f"Checking HedgeDoc at {url} ...")
status, _ = http_get(url)
if status == 200:
print(f"PASS: HedgeDoc returned HTTP {status}")
else:
print(f"FAIL: HedgeDoc returned HTTP {status} (expected 200)")
sys.exit(1)
if __name__ == '__main__':
main()
+38
View File
@@ -0,0 +1,38 @@
#!/usr/bin/env python3
"""Check Socket.IO transport on HedgeDoc."""
import argparse
import os
import sys
import urllib.request
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', '..'))
from utils.tests.helpers import resolve_domain
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--domain', default=os.environ.get('TEST_DOMAIN'))
args = parser.parse_args()
domain = args.domain or resolve_domain('hedgedoc')
url = f"https://{domain}"
print(f"Checking Socket.IO transport on {url} ...")
req = urllib.request.Request(f"{url}/socket.io/?EIO=4&transport=polling")
try:
with urllib.request.urlopen(req, timeout=15) as resp:
response = resp.read().decode('utf-8')
except Exception as e:
print(f"FAIL: Could not connect to Socket.IO endpoint: {e}")
sys.exit(1)
if response.startswith('0{'):
print("PASS: Socket.IO handshake successful")
else:
print("FAIL: Unexpected Socket.IO response")
print(f"Got: {response}")
sys.exit(1)
if __name__ == '__main__':
main()
+14
View File
@@ -0,0 +1,14 @@
# HedgeDoc Upstream
## Main Project
- **Repository:** https://github.com/hedgedoc/hedgedoc
- **Releases:** https://github.com/hedgedoc/hedgedoc/releases
- **Website:** https://hedgedoc.org
## Images
| Service | Image | Release Notes |
|---------|-------|---------------|
| app | `quay.io/hedgedoc/hedgedoc` | https://github.com/hedgedoc/hedgedoc/releases |
| db | `postgres` | https://www.postgresql.org/docs/release/ |