Files
engineering/README.md

145 lines
8.0 KiB
Markdown

# Engineering
Versioned skills, Java standards, formatting, coverage checks, and the Gitea
Actions / Maven Java 25 / npm / Docker Compose recipe. Architecture and
specifications belong to [landscape](http://192.168.2.28:3000/wanjakrah/landscape).
Source attribution is in SOURCE.md; upstream skill licenses accompany each skill.
## Start a project
Clone this repository and check out a released tag. Use JDK 25, Maven, Python 3,
Git, Docker with Compose, and a supported Node version for a frontend.
```sh
python3 create-project.py my-project ../my-project --version v1.0.0 --components both --runner engineering
```
Choose `backend`, `frontend`, or `both`. The command refuses existing destinations
and creates local files only. The backend starter is Quarkus; the frontend starter
uses npm and a minimal static page. Replace these starters with application code
while preserving the configured build commands and container contracts.
Initialize the resulting Git repository and commit its generated resources.
Create the remote repository separately, configure its runner and secrets, then
push. The runner label must match an available **host** runner with the required
tools. `--runner` deliberately has no machine-specific default.
## Consumer layout and configuration
`engineering.lock.json` selects a repository, immutable semantic version tag and
full commit SHA. `scripts/engineering.py` is the independent bootstrap, and
`generated/` is the committed release snapshot. No sibling checkout or global
skill installation is needed for ordinary use. Regeneration uses Git credentials
or a Git credential helper; never place credentials in the lockfile URL.
```sh
mvn -N -Pregenerate-engineering validate
python3 scripts/engineering.py --check
mvn -Dformat.mode=check clean verify
java generated/ci/Ci.java verify
java generated/ci/Ci.java test
java generated/ci/Ci.java release-test
```
The Maven regeneration profile skips formatting and works without `generated/`.
CI checks regeneration in a temporary checkout before running the pipeline. Added,
removed, modified and executable-bit changes fail the check. Runtime `target/`
and Python cache output are not release resources. Updates remove obsolete
generated files and never overwrite project-owned files outside `generated/`.
`engineering.properties` supplies project defaults; environment variables take
precedence. Required settings are `PROJECT_NAME` and at least one of
`BACKEND_MODULE` / `FRONTEND_MODULE`. Modules must be relative paths within the
project. Image names are `<PROJECT_NAME>-backend` and `<PROJECT_NAME>-frontend`;
changing PROJECT_NAME configures that namespace without changing shared code.
`BACKEND_CONTEXT` defaults to `.`, and `FRONTEND_CONTEXT` to its module path.
Both Dockerfiles provide a `prebuilt` target packaging verified output and a
default standalone source build. `FORMAT_DIRECTORIES` lists comma-separated
handwritten Java directories. Backend verification prepares a standards classpath,
runs the shared standards checker and requires 80% line coverage. Application
waivers remain in `tooling/standards/waivers.tsv`; no waiver is supplied by default.
`FRONTEND_TEST_COMMAND` is a JSON argument array, defaulting to the established
Vitest JUnit command; the starter sets `["npm","test"]`. Frontend verification
runs npm ci, lint, tests, and build. `BROWSER_TESTS=true` enables the recipe's
Playwright/JaCoCo integration for a backend and frontend. Configure
`CI_READINESS_URL`, `PLAYWRIGHT_IMAGE`, `CI_DATABASE`, `DATABASE_NAME` and
`DATABASE_USER` as appropriate. The browser recipe expects backend port 8080,
frontend port 8080, a backend JaCoCo agent and CLI prepared by Maven, and npm's
`e2e` script. Projects without that integration leave BROWSER_TESTS=false.
## Gitea setup
Build workflows need a host runner, `TARGET_PLATFORM` (for example linux/amd64),
and `REGISTRY_USER` / `REGISTRY_TOKEN` secrets with the repository/package access
needed for registry publication. The runner must also be able to read the pinned
engineering repository during the regeneration check. For private engineering,
install a read-only credential helper on the runner. Application registry and
release tokens are not used as implicit bootstrap credentials.
Publication is restricted to main after verification. Immutable commit images
are pulled back and checked before moving main tags. A host lock serializes
publication; a newer main prevents an older run from moving those tags.
Manual deployment and rollback workflows require variables `DEPLOY_HOST`,
`DEPLOY_USER`, `DEPLOY_SSH_PORT`, `DEPLOY_DIRECTORY`, `DEPLOY_REGISTRY`, and secrets
`RELEASE_TOKEN`, `DEPLOY_SSH_KEY`, `DEPLOY_KNOWN_HOSTS`. Release eligibility requires
a successful main-push build.yaml run. Keep build.yaml's filename when adapting
the recipe. Configure Gitea access, registry access and SSH host trust explicitly.
Runner setup mechanisms are available as `configure-gitea`, `configure-docker`
and `install-runner`. Supply GITEA_SERVER_URL, CI_REPOSITORY, RUNNER_LABEL and
INSECURE_REGISTRY where applicable; the latter is only for a deliberately trusted
internal HTTP registry. Runner configuration and service templates are project
files under ci/runner/. Installation currently supports Linux x86_64 host runners.
## Deployment and recovery
Projects own deploy/compose.yaml, deploy/health.sh and production.env. Set
COMPOSE_PROJECT, DEPENDENCY_SERVICES and REQUIRED_DEPLOY_SECRETS in project
configuration. Backend/frontend services use BACKEND_IMAGE / FRONTEND_IMAGE,
RELEASE_SHA and RELEASE_VERSION. Missing roles are represented by `-` in release
state; at least one image is required. Dependency services are started without
recreating their storage. Application containers alone are recreated on releases.
The remote mechanism requires a dedicated directory with owner-only
production.env containing BIND_IP, FRONTEND_PORT, DOCKER_BIN, DOCKER_CONFIG and
DOCKER_SUDO. The bind IP must be private, and the port 1024..65535. Provision a
pull-only registry login. `generated/deploy/provision.sh` accepts directory,
registry user, registry, bind IP, port and Docker executable. Optional
`generated/deploy/enable-docker.sh` takes deployment account and Docker executable
and must be run by an administrator after reviewing the Docker permission grant.
deploy/health.sh defines `application_health`, returning nonzero until the app is
ready. It can use the shared `compose` and `docker_cmd` functions. Health scripts,
Compose configuration, digests and deployment settings are retained per release.
For pre-S19 retained releases lacking health.sh/settings, the current project
health function/settings provide compatibility; verify them before rolling back
across this migration. Existing release-state JSON remains compatible.
Locking, a pending journal, digest/revision checks, bounded readiness checks and
automatic recovery protect replacement. An ambiguous state write or failed
recovery retains the journal and lock for manual inspection. Inspect retained
state, pending.json, history and diagnostics before repairing a deployment; never
blindly delete a lock. Each application must document its own recovery procedure
and database-schema rollback limits. Production deployment remains manual.
## Releases and upgrades
Release the resources, mechanisms and templates together. Use semantic version
tags `vMAJOR.MINOR.PATCH`; never move or reuse a published tag. Breaking changes
increase MAJOR. Record required project-file changes in UPGRADING.md before tagging.
Consumers update both tag and commit, regenerate, review and commit the diff.
The bootstrap rejects a tag resolving to a different commit and never upgrades
automatically. Templates create project-owned files once; upgrading only replaces
generated/. Bootstrap/profile/workflow changes require deliberate consumer edits.
## Validation
Run `python3 -m unittest discover -s tests`. The example definition is
examples/recipe-demo.json. Generate it with create-project.py and use the same
pipeline as any consumer. `tests/acceptance.py` exercises generated projects and
isolated deployment/rollback without touching production. Validation evidence is
recorded in VALIDATION.md.