ci: releases/symlink deploy with health-check rollback and smoke-test gate - #441
Merged
Conversation
… gate - npm ci (not npm install) so the build always matches package-lock.json, plus a guard that aborts if the installed Next.js version drifts from package.json - ship a versioned release.tar.gz, extract into releases/<release>/ on EC2, install deps there, verify the Next.js version again, then flip the DataExFrontend symlink atomically - boot health check after activation; auto-rolls back to the previous release on failure - dev: promote-dev/rollback-dev jobs make smoke-tests an actual deploy gate — release is only marked last-known-good on a smoke-test pass, and reverted on a smoke-test failure - prod: no smoke-test job exists yet, so the boot health check is its only gate; release is marked good immediately after - add deploy/ec2-migrate-to-releases.sh, the one-time manual migration from a plain DataExFrontend directory to the releases/ layout
The app's actual runtime secrets file on EC2 is .env.local (inside DataExFrontend itself), not .env one level up in DataExchange/ - that one belongs to a separate docker-compose stack (DataExAuth/DataExBackend/ DataExKeycloak). Confirmed via `pm2 env` showing no secrets in PM2's own captured environment, and .env.local's size/presence matching .env.local.example. Without this fix the new releases/ workflow would have symlinked the wrong file and every release would boot with no runtime config.
…ality-gate # Conflicts: # .github/workflows/deploy-Dataspace.yml
saqibmanan
added a commit
that referenced
this pull request
Aug 27, 2026
PR #441's deploy just failed: appleboy/ssh-action's non-interactive shell never sources nvm, leaving PATH pointed at the ancient system node (v10). npm and pm2 are both scripts with a '#!/usr/bin/env node' shebang, so invoking them by absolute path wasn't enough - env still re-resolved node via PATH and picked v10, which can't parse npm v24's node: imports ('Cannot find module node:path'). Failed before touching the DataExFrontend symlink, so the previous release stayed live throughout - no downtime from this. Fix: export NODE_BIN onto PATH before any npm/pm2 invocation, in both the deploy workflow (build-and-deploy activation step, rollback-dev) and the migration script. Verified live on dev-cds that node/npm/pm2 all resolve to v24 with this PATH export.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
mv .next2 .nextin-place swap with areleases/<timestamp-sha>/+ symlink layout, so a bad deploy can be rolled back instead of leaving the app half-updated.npm ci(notnpm install) plus a guard step that aborts the build if the installed Next.js version drifts frompackage.json— a prior incident let a different/canary Next.js version get silently resolved via plainnpm install.releases/<release>/, installs deps there, re-verifies the Next version, then atomically flips theDataExFrontendsymlink and runs a boot health check — auto-rolling back to the previous release if the health check fails.promote-dev/rollback-devjobs make the existingsmoke-testsjob (CivicDataSpace-test'srun-smoke.yml) an actual deploy gate — a release is only marked.last_goodon a smoke-test pass, and reverted on failure. Production has no smoke-test job yet, so its only gate remains the boot health check.shared/.env.local, symlinked into each release. Confirmed viapm2 envon the dev box that the app's real secrets file is.env.localinsideDataExFrontend, not the.envone level up in~/DataExchange/(that one belongs to a separate docker-compose stack — DataExAuth/DataExBackend/DataExKeycloak).deploy/ec2-migrate-to-releases.sh, the one-time manual migration each EC2 box needs before its first deploy under this workflow.Scope — dev only for now
This workflow file is shared between
devandmain(environment-scoped only by GH Actions vars/secrets), but the two boxes are not equally ready:shared/.env.localwired correctlyDo not merge
dev→mainuntil prod has Node v24.13.0 installed via nvm anddeploy/ec2-migrate-to-releases.shhas been run there. That's on the user to do, not something to automate/assume.Test plan
actionlinton the workflow file — cleanbash -non the migration script — cleanDataExFrontend/.env.localcorrectly symlinked toshared/.env.local(1915-byte real file, no secrets missing)