Skip to content

chore(deps): update dependencies within their current major versions - #98

Merged
HendrikThePendric merged 19 commits into
masterfrom
chore/deps-refresh
Oct 22, 2026
Merged

HendrikThePendric merged 19 commits into
masterfrom
chore/deps-refresh

Conversation

@karolinelien

@karolinelien karolinelien commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #93 so the multi-version e2e setup applies; retarget to master once that merges.

Why

  • Dependencies were last refreshed in May 2025, and ten dependabot PRs had piled up, one of them failing CI.

What

Version changes

Production image: npm prune --production drops all devDependencies, so only the first four rows reach the running service.

Package From To Type Why it's low risk
puppeteer 24.5.0 24.43.1 runtime, minor Same major. Its one type change (pageerror payload) is handled. Residual risk: the image drives Alpine 3.20's system Chromium, not Puppeteer's bundled Chrome, so the e2e run must pass before merge
axios 1.8.4 1.20.0 runtime, minor Same major; only used in RequestHandler, whose requests the integration tests exercise through nock
minimatch 10.0.1 10.2.6 runtime, minor Same major; one call matching response URLs against a glob in AppScraper
globals 15.15.0 17.13.0 major, lint only Only imported by eslint.config.js; never loaded by the service. Lint passes
nock 13.5.6 15.0.2 dev, major Test-only HTTP mocking; all 21 unit tests pass
supertest 7.1.0 7.3.1 dev, minor Test-only; exposed the port clash fixed in this PR, now 21/21
@types/supertest 6.0.2 6.0.3 dev, patch Types only; typecheck passes
typescript 5.8.2 5.9.3 dev, minor Compiler; typecheck and build pass
@types/node 22.14.0 22.20.5 dev, minor Types only, same Node 22 line; typecheck passes
eslint, @eslint/js 9.23.0 9.39.5 dev, minor Lint only; lint passes
typescript-eslint, @typescript-eslint/eslint-plugin, @typescript-eslint/parser 8.29.0 8.71.2 dev, minor Lint only; lint passes
@dhis2/cli-style 10.7.7 10.7.10 dev, patch Lint/format config; lint passes
@commitlint/cli, config-conventional, types 19.8.0 19.8.1 dev, patch Commit-message hook; commits in this PR passed it
lint-staged 15.5.0 15.5.2 dev, patch Pre-commit hook; commits in this PR passed it
@release-it/conventional-changelog 10.0.0 10.0.6 dev, patch Release tooling, same major; release-it itself stays at 18.1.2
dotenv 16.4.7 16.6.1 dev, minor Local start:* scripts only
nodemon 3.1.9 3.1.14 dev, patch Local start:dev only
rimraf 6.0.1 6.1.3 dev, minor Build cleanup; build passes

Transitive packages were refreshed by npm update and npm audit fix within the ranges their parents allow.

How verified

  • npm run lint and npm run build pass.
  • npm run test:unit: 21/21, twice in a node:lts container and once on Windows.

AI Assisted

karolinelien and others added 16 commits October 12, 2026 17:51
Since DHIS2 2.42 the legacy app paths the scrape instructions point to
(dhis-web-data-visualizer, dhis-web-maps, api/apps/line-listing,
dhis-web-event-visualizer, dhis-web-event-reports) are redirected to
/apps/<name>, where the global shell loads the app in an iframe. The
scraper only searches the top-level document, so every item timed out
(E2201) and no dashboard could be converted on 2.42+. Every goto step
now opens <app>/index.html with redirect=false, the bypass the global
shell itself uses for its iframe (GlobalShellFilter in dhis2-core). On
2.41 there is no shell and the parameter is ignored.

The admin login clicked the login button and returned immediately,
while the login app's POST /api/auth/login was still in flight. Work
that arrived in that window (right after a service start, a worker
replacement or a re-login) failed impersonation with a 401 (E2301).
The worker now posts to /api/auth/login itself and only continues once
loginStatus is SUCCESS. This endpoint exists since 2.41.0 and no longer
depends on the login app's markup.

Verified with a local Docker stack per version (2.41.10, 2.42.6, 2.43.2
and master) using the Sierra Leone e2e dump.

AI Assisted

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Run scrape steps through a promise chain instead of awaiting inside a
loop, mark fields that are only set in the constructor as readonly,
return the empty result directly from the async convert method, and
use node: imports and Number.parseInt. No behaviour change.

AI Assisted

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The dashboard details are fetched as the service account with the
recipient's locale as a query parameter. Since DHIS2 2.42 the locale
parameter only takes effect together with translate=true
(UserContextInterceptor, introduced with DHIS2-18061 / DHIS2-18044),
while 2.41 translated by default. Without it the dashboard title and item
headings were rendered in the service account's language instead of the
recipient's.

Verified on 2.42.6 (nb recipient now gets the Norwegian dashboard and
item names) and on 2.41.10 (unchanged).

AI Assisted

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ctor as readonly

Resolves the SonarCloud finding on the file touched by the translate fix.
No behaviour change.

AI Assisted

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…he login

Address review feedback: go back to the sequential for...of loop for the
scrape steps (the reduce-based version only existed to satisfy SonarCloud
S9382, the steps must run in order) and explain why the login first opens
/api/ping on the DHIS2 origin.

AI Assisted

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Go back to the reduce-based sequential promise chain for the scrape
steps. SonarCloud S9382 flags awaits inside a for...of loop, but the
steps must run strictly in order, which a promise chain expresses
without the per-iteration awaits. Agreed in review as the preferred
shape over accepting the findings.

AI Assisted

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Address review feedback: the global shell filter skips the redirect for
both directory-root and index.html paths when redirect=false is in the
query string, so rewriting the path to index.html is unnecessary. That
leaves two lines, which now live inline in the goto step, and removes
the toStandaloneAppUrl helper and its tests.

AI Assisted

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Puppeteer's page.click dispatches a mouse event at the element's centre
coordinates and leaves the mouse there. On the next conversion a worker
could load a pivot table with its Period chip under that stale mouse
position, so the chip's tooltip opened on top of the "HTML (.html)" menu
item. The click then landed on the tooltip, no download tab opened and
waitForTarget timed out after 30s (E2201). Calling element.click() in
the page clicks the intended element regardless of overlays and never
moves the mouse.

AI Assisted

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* chore: run the e2e suite across DHIS2 versions and fix setup decay

The nightly e2e run has failed since January 2026: analytics tables were
only generated for the last year, and the dump's data ends in 2025, so no
analytics table was created and the generation script still reported
success. The dump also cannot be upgraded past 2.41, the DHIS2 health
check relies on curl which the 2.44 image no longer ships, and two cluster
integration tests count a worker message that can arrive after the
response.

- Generate analytics from ANALYTICS_FIRST_YEAR (default 2025) onwards and
  fail when DHIS2 reports an error
- Replace the DHIS2 container health check with a wait script in the
  post-install container
- Run the nightly suite for core-dev 2.41, 2.42, 2.43 and master, building
  the service image from the checked out code
- Wait for trailing worker messages in the single and parallel request
  integration tests, as the worker exit test already does
- Document the corrected dump in DB.md (limited service account, fixed
  periods, receivers group, null org unit cleanup)

AI Assisted

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore: resolve SonarCloud findings in the nightly workflow and setup scripts

Pin the third-party actions in the nightly workflow to full commit SHAs
and use [[ ]] for the retry checks in the setup scripts.

AI Assisted

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore: add a script that creates the e2e database dump

Address review feedback that producing a new dump was manual, finicky
work. scripts/create-e2e-db-dump.sh starts DHIS2 on the stock Sierra
Leone database and applies every change the e2e suite relies on: the
service account, test users and their user groups, the "One of
everything" dashboard, Norwegian translations and locale, fixed periods
in DATA_YEAR, email and push analytics settings, no HTTP caching, and
the push analytics jobs. It then dumps the database without analytics
tables. DB.md documents the script and what it changes.

The new dump is published on the 1.0.4 release as
dump-2.41-2025.sql.gz and .env.e2e points at it. ANALYTICS_FIRST_YEAR
moves into .env.e2e so it stays in step with the dump's data year.

The fixtures are regenerated from this dump for dhis2/core:2.41 and for
core-dev 2.41, 2.42, 2.43 and master.

AI Assisted

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore: take the push analytics URL template from the e2e environment

Resolve SonarCloud S5332 (clear-text protocol) in the dump script: the
URL template is now built in docker/e2e-db/docker-compose.yml from HOST
and PORT in .env.e2e instead of being a literal in the script. The
resulting system setting is unchanged.

AI Assisted

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
A worker kept the previously loaded app document when it switched the
impersonated user or when a conversion failed, because subsequent goto
steps only change the hash. A stuck app then failed every later item on
that worker. Navigating to about:blank first forces a full page load;
the codebase had no existing helper for forcing a document reload.

AI Assisted

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
When several workers open Data Visualizer for the same new user at the
same time, each one tries to create the user's analytics userDataStore
keys. All but one get a 409, DV throws an uncaught error and the item
times out. A single retry starts from a full page load, by which time
the keys exist, so the app loads normally. The codebase has no shared
retry helper, so the retry stays local to the scraper.

AI Assisted

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rker

fix: recover the scraper when Data Visualizer fails to load for a new user
fix: click scrape step targets through the DOM
The login path now throws an AuthenticationError carrying the DHIS2
loginStatus, but establishNonExpiringAdminSession caught it and rethrew
a generic message, so the actual cause never reached the logs. Log the
caught error first. Carried over from #90, whose form-login change no
longer applies now that login goes through /api/auth/login.

AI Assisted

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
All integration test files bound the mock cluster to port 1337, and
node --test runs files in parallel, so three of the four binds failed.
supertest 7.1 masked this by silently re-listening the failed server on
a random port; supertest 7.3 records the late EADDRINUSE and fails the
request with it. Listening on port 0 gives every file its own port.

AI Assisted

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brings every dependency to its latest release within the current major,
plus the dev-only majors nock 15 and globals 17, and refreshes the
lockfile with npm update and npm audit fix (84 -> 48 audit findings).
Supersedes dependabot PRs #69, #76, #82, #83, #84, #85, #87, #88, #89.

Puppeteer now types the pageerror payload as Error | unknown, so
logPageEvents reads the message only from an Error instance.

Kept out as larger changes: release-it 19+ (#71), puppeteer 25,
typescript 7, eslint 10, commitlint 21, lint-staged 17, dotenv 18 and
@types/node 26.

AI Assisted

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@karolinelien
karolinelien marked this pull request as ready for review October 19, 2026 15:45
@HendrikThePendric HendrikThePendric added the e2e E2E checks will start running when this label is applied label Oct 22, 2026
@HendrikThePendric
HendrikThePendric changed the base branch from fix/global-shell-standalone-app-url to master October 22, 2026 08:17
@HendrikThePendric
HendrikThePendric enabled auto-merge (squash) October 22, 2026 08:35
HendrikThePendric and others added 2 commits October 22, 2026 11:05
… npm 10

The lockfile was generated with npm 11, which leaves out the optional
conventional-commits-parser@^6.4.0 peer of the git-client nested under
@release-it/conventional-changelog. npm 10.9.1 in the alpine:3.20 Docker
image then fails npm ci with "Missing: conventional-commits-parser@6.4.0
from lock file", breaking the e2e image build. Regenerated with npm
10.9.1; npm ci passes on both npm 10.9.1 and npm 11.

AI Assisted

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@HendrikThePendric
HendrikThePendric merged commit 1709e24 into master Oct 22, 2026
4 checks passed
@HendrikThePendric
HendrikThePendric deleted the chore/deps-refresh branch October 22, 2026 12:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

e2e E2E checks will start running when this label is applied

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants