fixed jenkins file and updated readme
Locusworks Team/portal-webapp/pipeline/head This commit looks good

This commit is contained in:
iparenteau committed 2026-09-04 15:39:29 -05:00
1 parent a6df549919
commit f0716b0073
3 files changed
+135 -159

No files matched your search

Vendored
+1 -2
View File
@@ -41,16 +41,15 @@ pipeline {
stage('Prepare OWASP cache') { stage('Prepare OWASP cache') {
steps { steps {
withCredentials([string(credentialsId: 'nvd-api-key', variable: 'NVD_API_KEY')]) {
lock(resource: 'owasp-nvd-cache') { lock(resource: 'owasp-nvd-cache') {
withMaven(maven: 'maven-3.9.16', globalMavenSettingsConfig: 'locusworks-settings') { withMaven(maven: 'maven-3.9.16', globalMavenSettingsConfig: 'locusworks-settings') {
// Dependency-Check uses nvdApiKey from pom.xml.
sh 'mkdir -p "$HOME/.cache/dependency-check"' sh 'mkdir -p "$HOME/.cache/dependency-check"'
sh 'mvn -B org.owasp:dependency-check-maven:13.0.0:update-only -DdataDirectory="$HOME/.cache/dependency-check"' sh 'mvn -B org.owasp:dependency-check-maven:13.0.0:update-only -DdataDirectory="$HOME/.cache/dependency-check"'
} }
} }
} }
} }
}
stage('Build and test') { stage('Build and test') {
steps { steps {
+134 -137
View File
@@ -1,173 +1,170 @@
# SETUP - Development # Portal
---
1. Clone the repository from BigMac:
- Add your public key to BigMac account.
- Clone the repository: `git clone "ssh://git@bigmac.locusworks.net:8010/saipt/portal-webapp.git"`
2. Create/Edit `settings.xml` in your `.m2` folder (see next section for example)
3. Change directories into the project and run `mvn clean install` (this may take a while).
4. Start the executable Spring Boot application with `java -jar portal_webapp/target/portal_webapp-1.0.0-RELEASE.jar`.
5. Browse to `http://localhost:8080/portal/`.
Application configuration is stored under `${user.home}/.portal` by default. Override this persistent location with the `PORTAL_HOME` environment variable or the `-Dportal.home=/path/to/portal` JVM property. The directory contains `portal.properties`, the AES seed, logger settings, logs, and temporary key files. Portal manages scripts, repositories, credentials, files, and scheduled jobs. Its Angular client is bundled into an executable Spring Boot JAR with embedded Tomcat.
Local runs use a persistent H2 database by default. Set `dbType=mysql` in `portal.properties` only when an external MySQL server is intended; H2 and MySQL have separate connection and credential properties. ## Requirements
External MySQL deployments require MySQL Server 8.4 or newer with Connector/J 26.7.0. | Component | Configuration |
| --- | --- |
| Java | JDK 21; check the active runtime with `mvn -v` |
| Maven | Maven 3.9.x; Jenkins uses `maven-3.9.16` |
| Backend | Spring Boot 4.1.1, embedded Tomcat 11.0.25 |
| Frontend | Angular 22; Node.js 24.20.0 and npm 12.0.2 provisioned by Maven |
| Default database | Persistent H2 in MySQL compatibility mode |
| External database | MySQL Server 8.4+ with Connector/J 26.7.0 |
## npm Versions are defined in [pom.xml](pom.xml) and [portal_client/package.json](portal_client/package.json). The frontend lockfile pins the installed npm dependency tree. Building requires access to the Locusworks Nexus repository, npm registry, and dependency-check data services. A global Node.js or npm installation is not required for Maven builds.
---
npm is used to install the Angular client dependencies declared in `portal_client/package.json`.
The Maven build provisions the supported Node.js LTS and npm versions declared in the root `pom.xml`; a global installation is not required for Maven builds. ## Build and run
From `portal_client`, run `npm ci` for a reproducible install, `npm test` for unit tests, and `npm run build` for the production bundle. Angular CLI discovers application imports and static assets directly; no legacy asset-injection manifest is required. Add your SSH public key to your Gitea account, then clone and build:
The `allowScripts` entries in `package.json` approve specific versions of the native Angular build helpers. Review and renew those entries when upgrading the corresponding packages. SockJS remains an explicitly allowed CommonJS dependency for the server's SockJS transport. STOMP uses its ESM entry through the TypeScript path mapping because version 7.3.0's browser export selects UMD. ```sh
git clone ssh://gitea@gitea.locusworks.net:7999/locusworks/portal-webapp.git
cd portal-webapp
mvn clean install
java -jar portal_webapp/target/portal_webapp-1.0.0-RELEASE.jar
```
## Dependency checks Open **http://localhost:8080/portal/**. The entry page redirects to `/portal/client/`, which uses hash-based routing. Use the corresponding JAR filename if the project version has changed.
`mvn clean install` runs OWASP Dependency-Check. NVD, RetireJS, and the npm lockfile audit remain enabled; the npm audit includes development dependencies. The Node Package Analyzer skips development dependencies to avoid treating uninstalled native binaries for other platforms as missing application packages. The build installs frontend dependencies with `npm ci`, builds and tests the client, compiles and tests the Java modules, runs dependency checks, packages the executable JAR, and installs Maven artifacts into the local repository. It does not publish to Nexus or start the application.
Sonatype OSS Index requires credentials and is opt-in. Configure a Maven `settings.xml` server with ID `oss-index`, your account username, and API token, then run `mvn clean install -Dportal.ossIndexEnabled=true` to include it. ### Maven settings
## H2 tests The POM defines the `locusworks-public` dependency/plugin repository and the `nexus-release` and `nexus-snapshot` deployment repositories. If authentication is required, configure matching server IDs in your user Maven settings (`~/.m2/settings.xml`, or `%USERPROFILE%\.m2\settings.xml` on Windows):
---
Tests use an isolated in-memory H2 database through the `portal.database.*` system-property overrides. Production continues to default to MySQL.
Run the common-module datasource test with:
`mvn -pl portal_common -am test`
## Settings.xml
---
If developing on the NGGN the proxy settings are needed to download the libraries
Sample:
```xml ```xml
<settings xmlns="http://maven.apache.org/SETTINGS/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <settings xmlns="http://maven.apache.org/SETTINGS/1.2.0">
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd">
<proxies>
<proxy>
<id>locusworks-proxy</id>
<active>true</active>
<protocol>http</protocol>
<host>eastproxy.locusworks.net</host>
<port>80</port>
<username>(your MyID)</username>
<password>(your login password)</password>
</proxy>
<proxy>
<id>locusworks-proxy2</id>
<active>true</active>
<protocol>https</protocol>
<host>eastproxy.locusworks.net</host>
<port>80</port>
<username>(your MyID)</username>
<password>(your login password)</password>
</proxy>
</proxies>
<servers> <servers>
<server> <server>
<id>flyway-localhost</id> <id>locusworks-public</id>
<username>root</username> <username>${env.NEXUS_USERNAME}</username>
<password>(mysql root password)</password> <password>${env.NEXUS_PASSWORD}</password>
</server> </server>
</servers> </servers>
</settings> </settings>
``` ```
## Running Spring Boot Supply those environment variables before building. Add `nexus-release` and `nexus-snapshot` server entries when publishing. The Nexus base URL defaults to `https://nexus.locusworks.net` and can be overridden with `-Dnexus.repo=https://your-nexus-host`.
---
The application is packaged as an executable JAR and does not require a separately installed application server. Spring Boot supplies the embedded web server. For production, NGINX or Apache can proxy ports 80 and 443 to the application on port 8080.
#### NGINX ## Application configuration
1. In the default /etc/nginx/conf.d add a file called portal.conf
2. Populated it with the values below Portal resolves its writable home directory in this order:
``` conf
proxy_cache_path /tmp/NGINX_cache/ keys_zone=backcache:10m;
map $http_upgrade $connection_upgrade { 1. JVM property `-Dportal.home=/path/to/portal`.
2. Environment variable `PORTAL_HOME`.
3. `${user.home}/.portal`.
```sh
java -Dportal.home=/var/lib/portal -jar portal_webapp/target/portal_webapp-1.0.0-RELEASE.jar
```
On Windows, use an absolute path such as `-Dportal.home=D:/Portal/data`. Put JVM properties before `-jar`.
The home directory holds `portal.properties`, the AES seed, `portal-loggers.properties`, logs, temporary key files, and the default H2 database under `data/`. Keep it separate from build output and preserve it when replacing the JAR. Encrypted settings depend on the AES seed, so back them up together.
| File | Purpose |
| --- | --- |
| [application.properties](portal_webapp/src/main/resources/application.properties) | Spring Boot context path, session, multipart, and JPA settings |
| [portal.properties](portal_webapp/src/main/resources/portal.properties) | Defaults used to initialize and reconcile the persistent Portal configuration |
For another HTTP port, append `--server.port=8081` to the Java command. The frontend assumes the `/portal` context path; changing it also requires updating client paths and rebuilding.
### Databases
New installations default to `dbType=h2`. H2 uses a persistent file database and needs no separate database server. Existing installations retain their configured `dbType`; there is no automatic production switch to MySQL.
For external MySQL, set `dbType=mysql` and configure `dbHost`, `dbPort`, `dbUsername`, `dbPassword`, `dbRootUser`, and `dbRootPassword` in the persistent Portal settings. Runtime migrations use the root connection; normal application access uses the application connection. H2 has separate `h2Url`, `h2Username`, and `h2Password` settings.
Nonblank database passwords in `portal.properties` are read as encrypted values. Use Portal's configuration facilities to save encrypted credentials instead of putting plaintext in those fields. Connector/J 26.7.0 requires MySQL Server 8.4 or newer; see the [MySQL release notes](https://dev.mysql.com/doc/relnotes/connector-j/en/news-26-7-0.html).
## Frontend development
Build the complete project once to provision the pinned tools. From `portal_client`, use the local executables to avoid picking up a different global npm version.
PowerShell:
```powershell
.\node\node.exe .\node\node_modules\npm\bin\npm-cli.js ci
.\node\node.exe .\node\node_modules\npm\bin\npm-cli.js run build
.\node\node.exe .\node\node_modules\npm\bin\npm-cli.js test
```
Linux/macOS:
```sh
./node/node ./node/node_modules/npm/bin/npm-cli.js ci
./node/node ./node/node_modules/npm/bin/npm-cli.js run build
./node/node ./node/node_modules/npm/bin/npm-cli.js test
```
With matching Node.js and npm versions on `PATH`, the equivalent commands are `npm ci`, `npm run build`, and `npm test`. The `start` script runs the Angular development server, but this project has no backend proxy configuration; API calls and realtime connections expect the `/portal` backend on the same origin. Use the packaged application for an integrated local run.
Client output goes to `portal_client/dist/` and is copied into the backend JAR at build time. Rebuild the backend to include changed client assets. Login, dashboard, and feature pages load on demand; the initial-bundle warning budget remains 500 kB.
The `allowScripts` entries in `package.json` approve specific versions of native build helpers. Review and renew them when upgrading those dependencies. SockJS is explicitly allowed as a CommonJS dependency for the existing transport. STOMP uses its shipped ESM entry through the TypeScript path mapping because its 7.3.0 browser export selects UMD. npm warnings and failures remain visible; routine npm notices are omitted.
## Tests and dependency checks
Run the complete verification with `mvn clean install`. To run the datasource test and its prerequisite Java modules:
```sh
mvn -pl portal_common -am test
```
The datasource test uses isolated in-memory H2 through `portal.database.*` JVM overrides and clears them afterward. It does not test an external MySQL instance. Frontend tests use Vitest through Angular CLI, including lazy login rendering and authentication redirects. Java test results are written to each module's `target/surefire-reports/` directory.
OWASP Dependency-Check runs during `verify`, which is included in `install`. HTML reports are written to `target/dependency-check-report.html` in the root and module directories. NVD, RetireJS, and npm lockfile auditing remain enabled. The npm audit includes development dependencies; the Node Package Analyzer skips them to avoid warnings about uninstalled native binaries for other platforms. The POM sets `failOnError=false` for Dependency-Check, so review its output and reports even when Maven succeeds.
Sonatype OSS Index requires credentials and is opt-in. Add a server named `oss-index` to Maven settings with your account username and API token as the password, then run:
```sh
mvn clean install -Dportal.ossIndexEnabled=true
```
## Deployment
Deploy `portal_webapp/target/portal_webapp-<version>.jar` and run it with Java 21 under your service manager. A separately installed Tomcat is not required. Configure a persistent Portal home writable by the service account.
[scripts/deploy-server.sh](scripts/deploy-server.sh) copies the built JAR to `deploy/portal.jar` by default. `PORTAL_DEPLOY_DIR` changes the destination; `PORTAL_SERVICE` requests a systemd service restart after copying. In this helper, `PORTAL_HOME` refers to the **source checkout**, unlike the application's runtime data directory. Use `-Dportal.home` in the Java service command to keep those locations distinct.
### Reverse proxy
Terminate HTTPS at NGINX or Apache and preserve `/portal/` when forwarding to the backend on port 8080. Realtime endpoints need WebSocket upgrades as well as ordinary HTTP forwarding.
For NGINX, place the `map` in the `http` context and the `location` inside your site's HTTPS `server` block:
```nginx
map $http_upgrade $connection_upgrade {
default upgrade; default upgrade;
'' close; '' close;
} }
upstream portal_app { # Inside the HTTPS server block:
# Use IP Hash for session persistence location /portal/ {
ip_hash; proxy_pass http://127.0.0.1:8080;
# List of Portal application instances
server 127.0.0.1:8080;
}
server {
listen 80;
server_name portal.viprcenter.com;
client_max_body_size 0;
# Redirect all HTTP requests to HTTPS
location / {
return 301 https://$server_name$request_uri;
}
}
server {
listen 443 ssl http2;
server_name portal.viprcenter.com;
client_max_body_size 0;
ssl_certificate /etc/nginx/ssl/portal.viprcenter.com.crt;
ssl_certificate_key /etc/nginx/ssl/portal.viprcenter.com.key;
ssl_session_cache shared:SSL:1m;
ssl_prefer_server_ciphers on;
# WebSocket configuration
location / {
proxy_pass http://portal_app;
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade; proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade; proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $remote_addr; proxy_set_header X-Forwarded-Proto $scheme;
} proxy_read_timeout 600s;
} }
``` ```
3. Save the file Supply your hostname, TLS certificates, and HTTP-to-HTTPS redirect in the surrounding configuration. Match proxy upload limits to the application's limits (10 MB by default). See [NGINX WebSocket proxying](https://nginx.org/en/docs/http/websocket.html). For Apache, enable `mod_proxy` and `mod_proxy_http` and configure WebSocket forwarding for your installed version; see the [Apache proxy documentation](https://httpd.apache.org/docs/2.4/mod/mod_proxy.html).
4. Modify `/etc/nginx/nginx.conf` ## Jenkins
5. In the http section of the conf file add `include /etc/nginx/conf.d/portal.conf` [Jenkinsfile](Jenkinsfile) defines a multibranch pipeline that checks out source, assigns a build version, updates a shared OWASP cache, runs `mvn clean verify`, publishes Java test results, archives JARs, and conditionally publishes Maven artifacts to Nexus.
6. Restart NGINX | Branch | Version | Publish to Nexus |
| --- | --- | --- |
| `release/<version>` | `<version>.<build-number>-RELEASE` | Yes |
| `develop` | `develop.<build-number>-SNAPSHOT` | Yes |
| Other branches | `0.0.<build-number>-<sanitized-branch>-SNAPSHOT` | No |
7. Navigate to the url. It should redirect to 443 The Jenkins agent needs a shell environment, JDK 21, Maven installation `maven-3.9.16`, and managed settings configuration `locusworks-settings`. Dependency-Check uses the existing `nvdApiKey` configuration in `pom.xml`; no separate Jenkins NVD credential is required. The pipeline uses the `owasp-nvd-cache` lock. Its deploy stage publishes artifacts; it does not restart an application server.
#### Apache
1. In apaches `httpd.conf` file add the following
``` conf
Listen 80
Listen 443
<VirtualHost *:80>
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(.*)$
RewriteRule ^(.*)$ https://%1$1 [R=Permanent,L,QSA]
</VirtualHost>
<VirtualHost *:443>
SSLEngine On
SSLCertificateFile /etc/apache/ssl/portal.viprcenter.com.crt
SSLCertificateKeyFile /etc/apache/ssl/portal.viprcenter.com.key
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:8080/
ProxyPassReverse / http://127.0.0.1:8080/
</VirtualHost>
```
2. Restart and try navigating
-20
View File
@@ -1,25 +1,5 @@
<settings xmlns="http://maven.apache.org/SETTINGS/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <settings xmlns="http://maven.apache.org/SETTINGS/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd"> xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd">
<proxies>
<proxy>
<id>locusworks-proxy</id>
<active>true</active>
<protocol>http</protocol>
<host>eastproxy.locusworks.net</host>
<port>80</port>
<username>(your MyID)</username>
<password>(your login password)</password>
</proxy>
<proxy>
<id>locusworks-proxy2</id>
<active>true</active>
<protocol>https</protocol>
<host>eastproxy.locusworks.net</host>
<port>80</port>
<username>(your MyID)</username>
<password>(your login password)</password>
</proxy>
</proxies>
<servers> <servers>
<server> <server>
<id>flyway-localhost</id> <id>flyway-localhost</id>