diff --git a/.dockerignore b/.dockerignore index a99bc5e71f3..af8c4e5984b 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,6 +1,4 @@ **/node_modules -.git -app backend/tools/ docs/ **/*.stories.* diff --git a/.github/workflows/build-container.yml b/.github/workflows/build-container.yml index 2affc7a117b..810b1989ca2 100644 --- a/.github/workflows/build-container.yml +++ b/.github/workflows/build-container.yml @@ -6,6 +6,7 @@ on: - 'frontend/**' - Makefile - '.github/**' + - Dockerfile jobs: build: diff --git a/Dockerfile b/Dockerfile index 8e25b0e8584..bc783afa8d3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,6 +18,12 @@ RUN cd ./backend && go build -o ./headlamp-server ./cmd/ # Keep npm install separated so source changes don't trigger install FROM base-build AS frontendinstall + +# We need .git and app/ in order to get the version and git version for the frontend/.env file +# that's generated when building the frontend. +COPY ./.git /headlamp/.git +COPY app/package.json /headlamp/app/package.json + COPY frontend/package*.json /headlamp/frontend/ COPY frontend/patches/* /headlamp/frontend/patches/ WORKDIR /headlamp @@ -30,6 +36,9 @@ WORKDIR /headlamp RUN cd ./frontend && npm run build +RUN echo "*** Built Headlamp with version: ***" +RUN cat ./frontend/.env + # Backwards compatibility, move plugin folder to only copy matching plugins. RUN mv plugins plugins-old || true diff --git a/frontend/.gitignore b/frontend/.gitignore index 76a74aed426..8a06d5c4392 100644 --- a/frontend/.gitignore +++ b/frontend/.gitignore @@ -15,6 +15,7 @@ # misc .DS_Store +.env .env.local .env.development.local .env.test.local diff --git a/frontend/make-env.js b/frontend/make-env.js new file mode 100644 index 00000000000..1ff6fc30cba --- /dev/null +++ b/frontend/make-env.js @@ -0,0 +1,28 @@ +'use strict'; + +// Creates the .env file + +const fs = require('fs'); +const {execSync} = require('child_process'); +const appInfo = require('../app/package.json'); + +const gitVersion = execSync('git rev-parse HEAD').toString().trim(); + +const envContents = { + REACT_APP_HEADLAMP_VERSION: appInfo.version, + REACT_APP_HEADLAMP_GIT_VERSION: gitVersion, + REACT_APP_HEADLAMP_PRODUCT_NAME: appInfo.productName, +}; + +function createEnvText() { + let text = ''; + Object.entries(envContents).forEach(([key, value]) => { + text += `${key}=${value}\n` + }) + + return text; +} + +const fileName = process.argv[2] || '.env'; + +fs.writeFileSync(fileName, createEnvText()); diff --git a/frontend/package.json b/frontend/package.json index f47276139b3..03a9d13e0a6 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -86,7 +86,9 @@ "xterm-addon-fit": "^0.5.0" }, "scripts": { + "prestart": "npm run make-version", "start": "react-scripts start", + "prebuild": "npm run make-version", "build": "if-env PUBLIC_URL react-scripts build || cross-env PUBLIC_URL=./ react-scripts build --max_old_space_size=768 && rimraf build/frontend/index.baseUrl.html", "test": "cross-env TEST_TZ=true react-scripts test", "eject": "react-scripts eject", @@ -98,6 +100,7 @@ "build-storybook": "build-storybook -s public -o ../docs/development/storybook", "i18n": "npx --no-install i18next ./src/**/ts* ./src/**/**/*.ts* ./src/**/**/**/*.ts* -c ./src/i18n/i18next-parser.config.js", "tsc": "tsc", + "make-version": "node ./make-env.js", "postinstall": "patch-package" }, "browserslist": { diff --git a/frontend/src/make-env.test.js b/frontend/src/make-env.test.js new file mode 100644 index 00000000000..638859a9904 --- /dev/null +++ b/frontend/src/make-env.test.js @@ -0,0 +1,35 @@ +const os = require('os'); +const path = require('path'); +const { execSync } = require('child_process'); +const { readFileSync } = require('fs'); + +const envFile = path.join(os.tmpdir(), 'tmpEnv'); + +test('Create & verify', () => { + const execFile = path.resolve(path.join(__dirname, '..', 'make-env.js')); + execSync(`node ${execFile} ${envFile}`); + + const envContents = readFileSync(envFile).toString(); + + const lines = envContents.split(/\r?\n/); + const envObj = {}; + + lines.forEach(line => { + // Skip empty lines + if (!line) { + return; + } + + const [key, val] = line.trim().split('='); + + expect(key.trim()).toBeDefined(); + expect(val.trim()).toBeDefined(); + + envObj[key] = val; + }); + + const keys = Object.keys(envObj); + expect(keys).toContain('REACT_APP_HEADLAMP_VERSION'); + expect(keys).toContain('REACT_APP_HEADLAMP_GIT_VERSION'); + expect(keys).toContain('REACT_APP_HEADLAMP_PRODUCT_NAME'); +});