# Development ## Prerequisites - Java 21 - Node.js and npm compatible with `frontend/package.json` - Docker Engine and Docker Compose for container testing ## Build and test ### Option 1: Gradle build (requires Java 21 and Node.js) From the repository root: ```bash cd backend ./gradlew clean build ``` This invokes the configured Gradle build, including frontend build tasks. ### Option 2: Docker multi-stage build (requires only Docker) Build the entire application inside Docker — no local Java or Node.js required: ```bash docker build -t htop-web . ``` This uses a multi-stage Dockerfile with three stages: 1. **Frontend** — builds Angular with Node.js 22 Alpine 2. **Builder** — compiles the backend with Gradle and Java 21 JDK 3. **Runtime** — packages only the JAR and Java 21 JRE (~200 MB final image) The Docker build is fully reproducible and does not depend on tools installed on the host machine. ## Frontend development Frontend source code is located in `frontend/`. Install dependencies using the lockfile: ```bash cd frontend npm ci ``` Run the frontend development server using the project's configured npm scripts: ```bash npm start ``` If the project does not define a `start` script, inspect `frontend/package.json` and use its available script, such as `npm run`. ## Run the container ### With Docker Compose (recommended) From the repository root: ```bash docker compose up -d --build docker compose logs -f htop-web ``` The `--build` flag triggers the multi-stage Docker build automatically. ### With Docker only If you built the image manually: ```bash docker run -d \ --name htop-web \ --pid host \ --read-only \ --security-opt no-new-privileges:true \ --tmpfs /tmp:noexec,nosuid,size=64m \ -v /proc:/host/proc:ro \ -v /sys:/host/sys:ro \ -v /etc/hostname:/host/etc/hostname:ro \ -v /etc/os-release:/host/etc/os-release:ro \ -v /var:/host/var:ro \ -v /home:/host/home:ro \ -v /opt:/host/opt:ro \ -v /tmp:/host/tmp:ro \ -v /srv:/host/srv:ro \ -v /usr:/host/usr:ro \ -p 8080:8080 \ htop-web ``` ## Release process ### Prerequisites - Gitea Actions runner must be configured and running. - Repository secrets `REGISTRY_USERNAME` and `REGISTRY_PASSWORD` must be set in **Settings → Secrets** of the Gitea repository. These credentials are used to authenticate with the Gitea Container Registry. ### Creating a release 1. **Update `CHANGELOG.md`** with changes for the new version. 2. **Commit and push** your changes: ```bash git add -A git commit -m "Prepare release v0.2.0" git push origin master ``` 3. **Create and push a Git tag** with Semantic Versioning: ```bash git tag -a v0.2.0 -m "Release v0.2.0: new features and fixes" git push origin v0.2.0 ``` 4. **Gitea Actions** will automatically: - Build the Docker image using the multi-stage Dockerfile - Tag it with the version (`0.2.0`), minor version (`0.2`), and `latest` - Push all three tags to the Gitea Container Registry ### Docker image tags Each release produces three Docker image tags: | Tag | Example | Description | |-----|---------|-------------| | Full version | `gitea.jambotron.com/liosha84/htop-web:0.2.0` | Exact version, use in production | | Minor version | `gitea.jambotron.com/liosha84/htop-web:0.2` | Latest patch of 0.2.x | | Latest | `gitea.jambotron.com/liosha84/htop-web:latest` | Most recent stable release | ### Using a specific version in production In `docker-compose.yml`, always pin to a specific version: ```yaml services: htop-web: image: gitea.jambotron.com/liosha84/htop-web:0.2.0 ``` Avoid using `:latest` in production — it makes rollbacks impossible and breaks reproducibility. ## Contribution guidelines - Keep changes focused and reviewable. - Do not commit generated build output or dependency directories. - Do not commit credentials, private keys, or local environment files. - Update documentation when build or runtime behavior changes. - Run the build before submitting changes.