Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/Documents/OPERATIONS.md
diff options
context:
space:
mode:
authorLeitwolf112026-10-03 18:21:43 +0300
committerLeitwolf112026-10-03 18:21:43 +0300
commit8738fc4e138745f2d065cf54c25426e3d37c119d (patch)
tree65871899976b4e6f0f04d55a50fa209d92b855e1 /Documents/OPERATIONS.md
parent710dc90b0503cd1de1ae6159e01fb22d1b336aba (diff)
downloadwebsite-docs/current-state.tar.gz
Bring the documentation up to the published site and fill its gapsdocs/current-state
The documents still described a site in maintenance with two languages and a forum page with a language menu. They now describe what is published, and three documents are new. New, under Documents/: - README.md: index of the documentation. - ARCHITECTURE.md: the frontend, the backend and the forum page, what each serves, what the site deliberately does not contain, and how search engines and crawlers are treated. - LOCALIZATION.md: the four languages, how a page picks one, what counts as a visitor's choice, how Hebrew text is laid out, where the text lives and how to add a language. - DEVELOPMENT.md: requirements, the commands of each part, the dependency locks and checksums, the tests and what CI enforces. Updated: - README.md: the site is public; four languages and the browser-language default; a documentation section; the Dokka gate. - CONTENT.md: the forum notice without a language menu; translation rules for four languages, including preferring the term a reader would use over a literal one; the crawler rules as an owner decision. - OPERATIONS.md: the live route table; the release steps for the directory layout on the server, with the SELinux labelling order that caused an outage once; cache keys for the forum files and CDN caching; maintenance mode as a fallback instead of the current state; rollback by directory; checksum regeneration with --refresh-dependencies; the post-release check for four languages and right-to-left text. No source file changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'Documents/OPERATIONS.md')
-rw-r--r--Documents/OPERATIONS.md147
1 files changed, 106 insertions, 41 deletions
diff --git a/Documents/OPERATIONS.md b/Documents/OPERATIONS.md
index 96baa57..3c3bff9 100644
--- a/Documents/OPERATIONS.md
+++ b/Documents/OPERATIONS.md
@@ -12,17 +12,22 @@ compatibility, but it does not make package functions part of this website.
| Host and path | Owner | Current treatment |
| --- | --- | --- |
-| `xsharp-lang.xyz/` | Vue language site | Maintenance response until approval |
-| `xsharp-lang.xyz/docs/overview` | Vue language site | Maintenance response until approval |
-| `xsharp-lang.xyz/docs/getting-started` | Vue language site | Maintenance response until approval |
-| `xsharp-lang.xyz/api/v1/site` | Spring language API | Not exposed during maintenance |
+| `xsharp-lang.xyz/` | Vue language site | Live |
+| `xsharp-lang.xyz/docs/overview` | Vue language site | Live |
+| `xsharp-lang.xyz/docs/getting-started` | Vue language site | Live |
+| `xsharp-lang.xyz/api/v1/site` | Spring language API | Live; the only proxied API path |
| `forum.xsharp-lang.xyz/` | Static placeholder | Live; noindex |
+| `www`, `docs`, `spec` subdomains | Redirect | Permanent redirect to `xsharp-lang.xyz` |
| `viget.xsharp-lang.xyz/*` | Legacy redirect | Permanent redirect to the new package host |
+The main domain is served with `ops/nginx/xsharp.conf`. While it is switched to
+`ops/nginx/xsharp-maintenance.conf`, the three language routes answer 503 and
+`/api/v1/site` is not exposed.
+
Do not use a catch-all `/api/` proxy for this service. The production Nginx
configuration proxies exactly `/api/v1/site`; other `/api/` paths return 404.
The Spring process binds only to `127.0.0.1`. Local runs default to port 5080;
-the checked-in systemd unit sets `PORT=5086`, matching the future Nginx proxy.
+the checked-in systemd unit sets `PORT=5086`, matching the Nginx proxy.
Its `/health` endpoint is for local process checks, not an advertised public
route.
@@ -41,9 +46,12 @@ npm run build
Run the backend gates from `backend/` with Temurin JDK 25:
```text
-gradle test bootJar --no-daemon
+gradle test bootJar dokkaGenerate --no-daemon
```
+`dokkaGenerate` is the documentation gate: a public declaration without KDoc
+fails it.
+
The backend checks in Gradle dependency locks and SHA-256 verification metadata
to keep transitive versions and downloaded artifacts stable. When intentionally
updating dependencies, run these commands from `backend/`, review both generated
@@ -51,9 +59,13 @@ files, then rerun the ordinary backend gates:
```text
gradle dependencies --write-locks --no-daemon
-gradle test jacocoTestReport bootJar --write-verification-metadata sha256 --no-daemon
+gradle --refresh-dependencies --write-verification-metadata sha256 help test jacocoTestReport bootJar dokkaGenerate --no-daemon
```
+Keep `--refresh-dependencies`. Written from a warm local cache, the metadata
+misses files that Gradle did not download again, and the build then fails
+verification on a clean machine while it passes locally.
+
Do not accept a checksum-only change without confirming the artifact version
and source repository; the checksum is an integrity pin, not a trust review.
@@ -61,7 +73,7 @@ The frontend tests assert canonical metadata, sitemap membership, asset shape,
forum non-indexing, and the absence of retired site links. The Spring tests
assert site-only API behavior, health, read-only operation, and missing account
and registry routes. These gates are necessary but not a substitute for a
-browser review of both themes, both languages, and narrow screens.
+browser review of both themes, all four languages, and narrow screens.
## Asset checks
@@ -96,14 +108,18 @@ link with a different brand domain.
## Forum placeholder deployment
The forum is deliberately a static document. It has no form, identity flow,
-post model, database, or discussion endpoint. Its language and theme controls
-operate entirely in the browser. The page and its server response both carry
+post model, database, or discussion endpoint. It shows its notice in the
+language of the browser and has a theme button; both work entirely in the
+browser. The page and its server response both carry
noindex signals. The Nginx policy only allows same-origin CSS, JavaScript, and
images; it does not need `unsafe-inline`.
Files under `forum/` are deployed as a unit. Deploying `index.html` without
its version-matched `site.css`, `site.js`, and two SVG files can leave a
-half-styled page or controls that no longer work. The forum Nginx config
+half-styled page or controls that no longer work. `index.html` refers to the
+stylesheet and the script with a `?v=` value; change that value whenever either
+file changes, because a CDN in front of the host can keep serving the old file,
+or a cached "not found", for hours. The forum Nginx config
permits only those named static paths. After copying, restore SELinux labels,
validate the Nginx configuration, then reload Nginx. Do not turn SELinux off
to work around a labeling mistake.
@@ -113,24 +129,65 @@ Check the public URL for HTTP 200 and for these response properties:
- `X-Robots-Tag: noindex, nofollow`;
- Content Security Policy with same-origin script and style sources;
- `site.css`, `site.js`, and the leopard SVG returning HTTP 200;
-- no login, registration, posting, or package UI; and
-- English by default, with working German and light-mode controls.
+- no login, registration, posting, or package UI;
+- no language menu, and the notice in the language of the browser, English for
+ a browser whose language has no translation; and
+- a working light-mode control.
-The forum can be deployed while the main language domain stays in
+The forum can be deployed while the main language domain is in
maintenance. Opening the real forum later is a separate product decision.
-## Main-site rollout gate
+## Releasing the main site
-The current main-domain server uses `ops/nginx/xsharp-maintenance.conf`.
-The future site config is `ops/nginx/xsharp.conf`. Merely committing the
-future config, building the Vue bundle, or deploying the forum does **not**
-authorize replacing the maintenance config. Keep the two configurations
-mutually exclusive in the live Nginx include directory.
+On the server the site lives in one directory:
-Before opening the main site:
+```text
+/srv/xsharp/website/
+ current/
+ frontend/ contents of frontend/dist
+ forum/ the five forum files
+ backend/ the Spring jar, next to the files of the legacy process
+ previous-<timestamp>/ the release before, kept for rollback
+```
-1. Review the English and German copy against the public language Spec and
- current compiler behavior.
+`current` is a real directory, not a symbolic link. A release replaces it by
+renaming:
+
+1. Build the frontend and the jar from the commit being released, and run the
+ local gates.
+2. On the server, copy `current` to a new directory next to it with
+ `cp -a`, which keeps owners, modes and SELinux labels, and replace the
+ changed parts inside the copy.
+3. Start the new jar on a free loopback port as the service user, request
+ `/health` and `/api/v1/site`, and stop it.
+4. Rename `current` to `previous-<timestamp>` and the new directory to
+ `current`.
+5. Run `restorecon -R` on `current/frontend` and `current/forum`.
+6. Restart the API service, then check the public routes from outside.
+
+Step 5 has to come after step 4. The SELinux rules that let Nginx read the
+files are bound to the paths below `current`. Run on a staging path,
+`restorecon` gives the files the default label of that path, and Nginx then
+answers 403 or 500 for every file. Do not switch SELinux to permissive to get
+around a label.
+
+A CDN in front of the host caches static files, `robots.txt` included, for
+hours. After a release, a changed file at an unchanged URL can look stale from
+outside while the server already has the new one; compare with a request made
+on the server itself before concluding that a release failed.
+
+## Maintenance mode
+
+`ops/nginx/xsharp-maintenance.conf` answers the main domain with 503 and keeps
+the legacy redirect working. `ops/nginx/xsharp.conf` serves the site. Keep the
+two mutually exclusive in the live Nginx include directory. Building the Vue
+bundle or deploying the forum does not by itself authorize switching between
+them.
+
+Before switching the main site from maintenance to public:
+
+1. Review the copy in every published language against the public language
+ Spec and current compiler behavior.
2. Confirm the homepage actually answers why the language exists and does
not describe planned compiler work as a finished feature.
3. Verify the three route bodies, both themes, keyboard focus, and responsive
@@ -160,15 +217,20 @@ true while `xsharp-lang.xyz` itself returns 503. The redirect certificate
uses the existing SAN entry for the old hostname. Do not remove the redirect
in the course of cleaning up language-site copy.
-The redirect remains in the future Nginx config as well. It is routing
+The redirect is part of the site config as well. It is routing
compatibility, not a ViGet API or a user-facing section of the language site.
## Rollback
-Keep the prior Nginx configuration and the last known good frontend artifact
-available until post-rollout checks pass. A rollback returns the main language
-vhost to maintenance, checks `nginx -t`, reloads Nginx, and confirms the
-expected 503. The forum and legacy redirect should remain unaffected.
+Keep the previous release directory until the checks after a release pass. A
+rollback of a release renames `current` away and `previous-<timestamp>` back to
+`current`, runs `restorecon -R` on `current/frontend` and `current/forum`, and
+restarts the API service.
+
+Keep the prior Nginx configuration as well. Taking the main site offline
+returns its vhost to maintenance, checks `nginx -t`, reloads Nginx, and
+confirms the expected 503. The forum and legacy redirect should remain
+unaffected.
Do not roll back by deleting certificates, disabling SELinux, or pointing
unrelated hostnames at the language frontend. If the Spring process fails,
@@ -178,27 +240,30 @@ boundary is clear.
## Monitoring and privacy
-Expected main-domain maintenance responses are 503 with `Retry-After`.
-Expected forum responses are 200 for the five static files and 404 for other
-paths. Expected legacy redirect responses are 308. After the public launch,
-the main language routes should be 200 and `/api/v1/site` should return only
-the website's non-sensitive state. A 200 from a retired login or registry
-route is a regression.
+The main language routes answer 200, and `/api/v1/site` returns only the
+website's non-sensitive state. Expected forum responses are 200 for the five
+static files and 404 for other paths. Expected legacy redirect responses are
+308. In maintenance mode the main domain answers 503 with `Retry-After`. A 200
+from a retired login or registry route is a regression.
Neither the static site nor the forum placeholder should send personal data
-to a third-party analytics service. Theme and language preferences are kept
+to a third-party analytics service. The content security policy allows
+same-origin scripts only, so a script added by an intermediary is blocked by
+the browser rather than run. Theme and language preferences are kept
locally in the browser. Nginx and Spring logs still need normal retention
and access-control practices, but this repository does not define an account
database or a user profile store.
## Post-release review
-After a public rollout, perform the same checks from a clean browser profile
-with no saved language or theme choice. Confirm that the default is dark and
-English. Switch to German, navigate through both documentation routes, and
-confirm the choice persists. Switch to light mode and repeat. The forum has
-its own local preference keys and should not unexpectedly change the main
-site's settings.
+After a release, perform the same checks from a clean browser profile with no
+saved language or theme choice. Confirm that the theme is dark and that the
+language is the browser's when it is one of the four, and English otherwise.
+Choose another language in the menu, navigate through both documentation
+routes, and confirm the choice persists. Choose Hebrew and confirm that text
+runs right to left while the layout and the code blocks stay as they are.
+Switch to light mode and repeat. The forum keeps its own theme key and follows
+the browser language; it should not change the main site's settings.
Inspect the page source as well as the rendered page. The initial HTML has
English home metadata; JavaScript updates metadata after route and locale