Aman-Mittal opened a new pull request, #379:
URL: https://github.com/apache/fineract-backoffice-ui/pull/379

   Closes every P1 from the release-readiness audit that this repository can 
close on its own, so the dev-list proposal can be about the decisions the PMC 
has to make rather than the work still outstanding. Tracked on #377.
   
   | Blocker | State |
   |---|---|
   | **V1** — version is `0.0.0` | fixed |
   | **D1** — no release documentation | fixed |
   | **E1** — container cannot reach a backend | fixed, verified by running it |
   | **E2** — compose defaults to a third-party demo host | fixed |
   | **E3** — image build ignores the lockfile | fixed |
   | **E4** — entrypoint drops config keys | fixed |
   | **E5** — floating base image tags | fixed |
   | **E8** — no CI job builds the image | fixed |
   | **L1** — LGPL devDependency | fixed in #378 |
   
   What remains for the PMC is genuinely theirs: artifact scope, the target 
Fineract version, the final version number, and when the "not release-ready" 
notice comes out. That notice stays.
   
   ## Business Value
   
   The audit could say "not ready" but not "here is why it stays that way". 
Every item above is something a deployer or a release manager hits directly.
   
   The container one is the sharpest. Anyone who followed the documented 
deployment got an application that loaded, showed a login screen, and could not 
sign in — because every API call returned the application's own HTML. That is 
the first experience an evaluating institution would have had, and it would 
have looked like the software was broken rather than misconfigured. It now 
works from `docker compose up`, and a CI job asserts it keeps working.
   
   The release process matters for a different reason: the PMC is being asked 
to approve a *process* as much as a payload. Writing it down before the vote 
means reviewers can object to the method while it is still cheap to change, 
rather than discovering it in the middle of a release.
   
   ## E1 — the container, verified rather than asserted
   
   The audit found this by running the image; the fix is verified the same way, 
from a clean container against a live Fineract:
   
   ```
   GET /                          -> 200 text/html          the application
   GET /api/v1/offices  (auth)    -> 200 application/json   Fineract's answer
   GET /api/v1/offices  (no auth) -> 400                    Fineract's answer, 
not the shell
   GET /api/v1/probe.js           -> 400 application/json   proxied, not served 
off disk
   
   [{"id":1,"name":"Head Office","nameDecorated":"Head Office", ...
   ```
   
   nginx now proxies `/api/` to the upstream Fineract, so the browser only ever 
talks to this origin and the CSP keeps `connect-src 'self'` instead of being 
widened per deployment.
   
   Two things in that config are load-bearing and would look like mistakes 
without the reason:
   
   **`location ^~ /api/`.** A plain prefix match does not stop nginx evaluating 
the static-asset regex below it, so any API path ending in `.js` would be 
served from the filesystem — a 404 for a request that should have reached the 
backend. That is the `/api/v1/probe.js` assertion above.
   
   **`X-Forwarded-Proto` defaults to `https`, not `$scheme`.** Fineract decides 
whether its channel requirement is met from that header. Measured against the 
stock image, five requests each:
   
   ```
   header absent               302 302 302 302 302    Location: 
https://<host>/...
   X-Forwarded-Proto: https    200 200 200 200 200
   ```
   
   Forwarding `$scheme` produces a container that works only where TLS is 
already terminated in front of it and redirects everywhere else. The 
nginx→Fineract hop is itself TLS, so `https` is a true statement about the 
connection Fineract is answering. `FINERACT_FORWARDED_PROTO` overrides it for 
deployments behind another proxy.
   
   ## E2–E5 — the rest of the deployment
   
   - **`npm ci`, not `npm install`.** CI has an entire job forbidding `npm 
install` for the build; the image had been exempt from the one place it matters 
most. Without it the image is not reproducible from the lockfile that the SBOM 
and the licence scan both describe.
   - **Both base images pinned by digest.** A release image that cannot be 
rebuilt from its own Dockerfile a year later is not much of an artifact.
   - **The compose file brings up its own Fineract and PostgreSQL.** It 
previously defaulted to a public demo instance operated by someone else, so an 
operator's first run sent the credentials they typed off-project.
   - **The entrypoint writes `config.json` whole.** It used to write two keys 
and drop the other three, which left `allowedApiOrigins` — backing a release 
gate — unsettable in a container. Every key now has a default, so the file is 
complete by construction. `RBAC_ENABLED` and `DEVELOPER_TOOLS_ENABLED` are 
rejected unless exactly `true` or `false`, because `=no` would otherwise land 
in the JSON as a truthy string and a deployment that believed it had turned 
RBAC off would have it on.
   
   ## A gate that would have gone quiet
   
   The GA `headers` gate reads the nginx server block. Renaming that file to 
`.template` would have turned the gate `unknown` — and `unknown` did not block. 
So it is repointed, **and** `ga-check.mjs` now fails on an undetermined 
blocking gate.
   
   A check that cannot read its input has not said yes. This repository has 
already had a release gate that existed and was never run; a gate that silently 
stops checking is the same failure wearing a green tick.
   
   ## E8 — the CI job that would have caught all of this
   
   A 200 on `/` proves nothing. The new `Container Image` job builds the image, 
starts a real Fineract, runs the container against it, and asserts:
   
   - the application is served
   - `config.json` carries every key the application reads
   - `/api/v1/offices` answers as Fineract and **not** as the SPA shell — 
content type is checked, because a wrong 200 is the failure mode
   - an API path ending in `.js` is proxied rather than served locally
   - security headers survive on a proxied response
   
   ## V1 — the version
   
   `0.0.0` → `1.0.0-rc.1`, matching the audit's recommendation. The final 
number is the PMC's to choose.
   
   `npm run check:version` rejects `0.0.0` and non-SemVer, and on a tag build 
asserts the tag names the same version `package.json` does — the quiet failure 
being someone tagging `1.0.0` from a tree that still says `1.0.0-rc.1`, leaving 
the tarball, the image and the SBOM disagreeing with the tag the vote was held 
on. CI now runs on tags so it has something to compare.
   
   **One correction to my own audit finding.** It claimed the version also 
reaches `remoteEntry.json`. It does not — the many `0.0.0`s in that file are 
native-federation's placeholders for internal chunks (`@nf-internal/chunk-*`), 
unrelated to `package.json`. The SBOM claim is the one that holds, and it is 
verified:
   
   ```
   before: pkg:npm/[email protected]
   after:  pkg:npm/[email protected]
   ```
   
   ## D1 — the release process
   
   `RELEASING.md` covers the TLP path end to end: signing key and KEYS, the 
decisions the PMC has to make first, cutting and tagging, building the tarball 
through `git archive` so nothing untracked can leak in, signatures and 
checksums, staging on `dist.apache.org`, the vote thread with what a reviewer 
is expected to check, and publishing.
   
   Two steps are called out because they are the ones most easily got wrong: 
**run RAT over the tarball, not the working tree** (a run over a git checkout 
says nothing about the artifact), and **verify the tarball builds**.
   
   It closes with the failures this project has actually had, so the next 
release manager inherits a list rather than folklore.
   
   `CHANGELOG.md` describes 1.0.0-rc.1 including the known limitations, not 
only the functionality — the three features Fineract refuses on PostgreSQL, the 
partially translated locales, the WCAG AA contrast shortfall, validation 
against Fineract head rather than a pinned release, and the migration note 
about route-level authorization.
   
   ## Documentation corrections
   
   | Was | Is |
   |---|---|
   | Threat model: `rbacEnabled` is a build flag in `environment.ts` | a 
runtime `config.json` key — with the trust implication now stated, since anyone 
who can write that file can turn the client-side layer off without a rebuild |
   | "Angular 21" in the threat model and `AGENTS.md` | Angular 22 |
   | README links `GEMINI.md` | removed; the file does not exist and is not 
tracked |
   | `NOTICE` and README: "Copyright 2025" | 2025-2026 |
   | README deployment section: three sketches, one showing an `/api/` proxy 
that nginx did not implement | the deployment that now exists, with the full 
environment-variable table |
   
   ## Testing
   
   | Gate | Result |
   |---|---|
   | `lint:prune`, HTML lint | pass |
   | `test:eslint-rules` | 26/26 |
   | `format:check` | pass |
   | `i18n:check`, `check:icons` | pass |
   | `check:internal-endpoints`, `check:route-permissions` | pass |
   | **`check:version`** | pass — and verified to fail on a mismatched tag |
   | `typecheck:e2e`, `api:surface` | pass |
   | `check-license.sh`, `check:licenses`, `check:licenses:selftest` | pass |
   | `build` | pass |
   | Unit tests | **1093 SUCCESS** |
   | `ga:check` | 8/9, **0 blocking, 0 undetermined**; adapter backlog 
unchanged at 416 |
   | Container image | built and run against a live Fineract; all five 
assertions above verified by hand before the CI job was written |
   
   ## Breaking changes
   
   **For container deployments only**, and deliberate:
   
   `FINERACT_API_URL` now names the **upstream** Fineract as reachable *from 
the container*, not a browser-visible URL. A deployment that set it to a 
browser-facing address must change it to the address nginx should proxy to. 
This is the change that makes the container work at all — the previous meaning 
could not, because the CSP refused the cross-origin request it implied.
   
   `deploy/nginx.conf` is replaced by `deploy/nginx.conf.template`. A 
deployment that mounted its own `nginx.conf` over the old path is unaffected; 
one that copied the file as a starting point should re-copy.
   
   Nothing changes for the application itself.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to