diff --git a/api/src/routes/public/status.test.ts b/api/src/routes/public/status.test.ts index e6852a695e4..744784b591d 100644 --- a/api/src/routes/public/status.test.ts +++ b/api/src/routes/public/status.test.ts @@ -1,4 +1,5 @@ import { setupServer, superRequest } from '../../../jest.utils'; +import { DEPLOYMENT_VERSION } from '../../utils/env'; describe('/status', () => { setupServer(); @@ -11,4 +12,13 @@ describe('/status', () => { expect(response.body).toStrictEqual({ msg: 'pong' }); expect(response.status).toBe(200); }); + + test('GET returns 200 status code with version', async () => { + const response = await superRequest('/status/version', { + method: 'GET' + }); + + expect(response.body).toStrictEqual({ version: DEPLOYMENT_VERSION }); + expect(response.status).toBe(200); + }); }); diff --git a/api/src/routes/public/status.ts b/api/src/routes/public/status.ts index 8484c815c87..b5b21089507 100644 --- a/api/src/routes/public/status.ts +++ b/api/src/routes/public/status.ts @@ -1,5 +1,7 @@ import { type FastifyPluginCallbackTypebox } from '@fastify/type-provider-typebox'; +import { DEPLOYMENT_VERSION } from '../../utils/env'; + /** * Plugin for the health check endpoint. * @@ -18,5 +20,10 @@ export const statusRoute: FastifyPluginCallbackTypebox = ( return { msg: 'pong' }; }); + fastify.get('/status/version', async (req, _reply) => { + fastify.log.child({ req }).debug('version'); + return { version: DEPLOYMENT_VERSION }; + }); + done(); }; diff --git a/api/src/utils/env.ts b/api/src/utils/env.ts index 89a7d6b2c31..45112bf9c11 100644 --- a/api/src/utils/env.ts +++ b/api/src/utils/env.ts @@ -90,6 +90,7 @@ if (process.env.FREECODECAMP_NODE_ENV !== 'development') { assert.notEqual(process.env.COOKIE_SECRET, 'a_cookie_secret'); assert.ok(process.env.SENTRY_DSN); assert.ok(process.env.SENTRY_ENVIRONMENT); + assert.ok(process.env.DEPLOYMENT_VERSION); // The following values can exist in development, but production-like // environments need to override the defaults. assert.notEqual( @@ -210,3 +211,4 @@ function undefinedOrBool(val: string | undefined): undefined | boolean { } export const SCREENSHOT_SERVICE_LOCATION = process.env.SCREENSHOT_SERVICE_LOCATION; +export const DEPLOYMENT_VERSION = process.env.DEPLOYMENT_VERSION || 'unknown';