Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0d8123ed4a | |||
| db1d28a75b | |||
| 64bcd0ab9f |
@@ -1 +1 @@
|
||||
{".":"3.45.2"}
|
||||
{".":"3.45.3"}
|
||||
|
||||
@@ -5,6 +5,14 @@ All notable changes to PicPeak will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [3.45.3](https://github.com/PicPeak/picpeak/compare/v3.45.2...v3.45.3) (2026-07-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **update:** target docker-compose.production.yml in dashboard update steps ([64bcd0a](https://github.com/PicPeak/picpeak/commit/64bcd0ab9f35b207ed21f41cfa05c1499ad4cbae))
|
||||
* **update:** target docker-compose.production.yml in dashboard update steps + gate mailhog (stable) ([db1d28a](https://github.com/PicPeak/picpeak/commit/db1d28a75ba9036e5bd5d87930bcac704c83341b))
|
||||
|
||||
## [3.45.2](https://github.com/PicPeak/picpeak/compare/v3.45.1...v3.45.2) (2026-07-17)
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* Regression tests for the Docker update instructions (environmentService).
|
||||
*
|
||||
* A production install (docker-compose.production.yml) must get `-f
|
||||
* docker-compose.production.yml` in every update command — bare `docker compose`
|
||||
* targets docker-compose.yml, a different build-based stack that also starts the
|
||||
* dev-only mailhog, which left production users stranded on the old version
|
||||
* (reported against 3.44.0 → 3.45.2).
|
||||
*/
|
||||
const { detectEnvironment, generateUpdateInstructions } = require('../../src/services/environmentService');
|
||||
|
||||
describe('detectEnvironment — production compose detection', () => {
|
||||
const orig = process.env.PICPEAK_RELEASE_CHANNEL;
|
||||
afterEach(() => {
|
||||
if (orig === undefined) delete process.env.PICPEAK_RELEASE_CHANNEL;
|
||||
else process.env.PICPEAK_RELEASE_CHANNEL = orig;
|
||||
});
|
||||
|
||||
it('flags isProductionCompose when PICPEAK_RELEASE_CHANNEL is set', async () => {
|
||||
process.env.PICPEAK_RELEASE_CHANNEL = 'stable';
|
||||
const env = await detectEnvironment();
|
||||
expect(env.isProductionCompose).toBe(true);
|
||||
});
|
||||
|
||||
it('does not flag it when the var is absent (default docker-compose.yml)', async () => {
|
||||
delete process.env.PICPEAK_RELEASE_CHANNEL;
|
||||
const env = await detectEnvironment();
|
||||
expect(env.isProductionCompose).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('generateUpdateInstructions — Docker commands', () => {
|
||||
const cmds = (env) => generateUpdateInstructions(env, '3.45.2').steps.map((s) => s.command);
|
||||
|
||||
it('targets docker-compose.production.yml for a production install', () => {
|
||||
const commands = cmds({ isDocker: true, isProductionCompose: true });
|
||||
expect(commands).toEqual([
|
||||
'docker compose -f docker-compose.production.yml pull',
|
||||
'docker compose -f docker-compose.production.yml up -d',
|
||||
'docker compose -f docker-compose.production.yml logs -f backend',
|
||||
]);
|
||||
// And the warning tells them where to run it.
|
||||
const { warnings } = generateUpdateInstructions({ isDocker: true, isProductionCompose: true }, '3.45.2');
|
||||
expect(warnings.join(' ')).toMatch(/docker-compose\.production\.yml/);
|
||||
});
|
||||
|
||||
it('uses bare commands + a hint when not a production compose', () => {
|
||||
const commands = cmds({ isDocker: true, isProductionCompose: false });
|
||||
expect(commands).toEqual([
|
||||
'docker compose pull',
|
||||
'docker compose up -d',
|
||||
'docker compose logs -f backend',
|
||||
]);
|
||||
const { warnings } = generateUpdateInstructions({ isDocker: true, isProductionCompose: false }, '3.45.2');
|
||||
// Still nudges production users to add -f in case detection missed.
|
||||
expect(warnings.join(' ')).toMatch(/-f docker-compose\.production\.yml/);
|
||||
});
|
||||
});
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "picpeak-backend",
|
||||
"version": "3.45.2",
|
||||
"version": "3.45.3",
|
||||
"description": "Backend for PicPeak event photo sharing platform",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
|
||||
@@ -47,11 +47,23 @@ async function detectEnvironment() {
|
||||
type = 'standalone';
|
||||
}
|
||||
|
||||
// Detect a production compose install. The backend runs INSIDE a container and
|
||||
// cannot see the host's compose files (the image only carries backend/), so we
|
||||
// can't stat docker-compose.production.yml. Instead we key off an env var the
|
||||
// production compose sets in the backend environment (PICPEAK_RELEASE_CHANNEL)
|
||||
// and the default docker-compose.yml does not. When present, the update
|
||||
// instructions must target that file explicitly — bare `docker compose`
|
||||
// operates on docker-compose.yml, a different (build-based) stack that also
|
||||
// starts the dev-only mailhog and leaves the real production containers on the
|
||||
// old version.
|
||||
const isProductionCompose = Boolean(process.env.PICPEAK_RELEASE_CHANNEL);
|
||||
|
||||
return {
|
||||
type,
|
||||
isDocker,
|
||||
isGit,
|
||||
hasDockerCompose,
|
||||
isProductionCompose,
|
||||
platform: process.platform,
|
||||
nodeVersion: process.version,
|
||||
appVersion
|
||||
@@ -94,25 +106,36 @@ function generateUpdateInstructions(env, targetVersion) {
|
||||
|
||||
if (env.isDocker) {
|
||||
instructions.environmentName = 'Docker';
|
||||
// Production installs use docker-compose.production.yml (the file the README
|
||||
// documents and the only one with pinned GHCR images + no dev-only mailhog).
|
||||
// Bare `docker compose` targets docker-compose.yml instead, so a production
|
||||
// user who runs it stays on the old version and gets a stray mailhog. When we
|
||||
// detect a production compose (PICPEAK_RELEASE_CHANNEL set), point every
|
||||
// command at that file with `-f`.
|
||||
const composeFile = env.isProductionCompose ? '-f docker-compose.production.yml ' : '';
|
||||
instructions.steps = [
|
||||
{
|
||||
description: 'Pull latest images',
|
||||
command: 'docker compose pull',
|
||||
command: `docker compose ${composeFile}pull`,
|
||||
note: 'Downloads the new version images'
|
||||
},
|
||||
{
|
||||
description: 'Recreate containers with new images',
|
||||
command: 'docker compose up -d',
|
||||
command: `docker compose ${composeFile}up -d`,
|
||||
note: 'Restarts containers with new version'
|
||||
},
|
||||
{
|
||||
description: 'Watch logs for startup (optional)',
|
||||
command: 'docker compose logs -f backend',
|
||||
command: `docker compose ${composeFile}logs -f backend`,
|
||||
note: 'Press Ctrl+C to exit logs',
|
||||
optional: true
|
||||
}
|
||||
];
|
||||
instructions.warnings.push('Make sure you are in the directory containing your docker-compose.yml file');
|
||||
if (env.isProductionCompose) {
|
||||
instructions.warnings.push('Run these from the directory containing your docker-compose.production.yml file.');
|
||||
} else {
|
||||
instructions.warnings.push('Make sure you are in the directory containing your compose file. If you installed with docker-compose.production.yml, add `-f docker-compose.production.yml` to each command.');
|
||||
}
|
||||
} else if (env.isGit) {
|
||||
instructions.environmentName = 'Git (Development)';
|
||||
instructions.steps = [
|
||||
|
||||
@@ -141,10 +141,16 @@ services:
|
||||
networks:
|
||||
- picpeak-network
|
||||
|
||||
# Local mail catcher for development/testing only — never wanted in a real
|
||||
# deployment. Gated behind the `dev` profile so a plain `docker compose up -d`
|
||||
# does NOT start it; opt in with `docker compose --profile dev up -d`. Nothing
|
||||
# depends on it (SMTP_HOST comes from .env), so gating is safe.
|
||||
mailhog:
|
||||
image: mailhog/mailhog:latest
|
||||
container_name: picpeak-mailhog
|
||||
restart: unless-stopped
|
||||
profiles:
|
||||
- dev
|
||||
ports:
|
||||
- "${MAILHOG_SMTP_PORT:-1025}:1025"
|
||||
- "${MAILHOG_UI_PORT:-8025}:8025"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "picpeak-frontend",
|
||||
"private": true,
|
||||
"version": "3.45.2",
|
||||
"version": "3.45.3",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
Reference in New Issue
Block a user