From ed3df8db386a8e014b2495dde3c717423af650f1 Mon Sep 17 00:00:00 2001 From: Jonathon Herbert Date: Wed, 24 Jun 2026 11:36:52 +0100 Subject: [PATCH 01/12] Use CI and NODE_ENV env vars to determine public path --- .../src/client/decidePublicPath.test.ts | 15 ++------------- dotcom-rendering/src/client/decidePublicPath.ts | 4 ++-- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/dotcom-rendering/src/client/decidePublicPath.test.ts b/dotcom-rendering/src/client/decidePublicPath.test.ts index 85ebbf20e3c..dbe18fe44aa 100644 --- a/dotcom-rendering/src/client/decidePublicPath.test.ts +++ b/dotcom-rendering/src/client/decidePublicPath.test.ts @@ -1,14 +1,5 @@ import { decidePublicPath } from './decidePublicPath'; -const mockHostname = (hostname: string | undefined) => { - Object.defineProperty(window, 'location', { - value: { - hostname, - }, - writable: true, - }); -}; - const mockFrontendAssetsFullURL = (frontendAssetsFullURL: string) => { Object.defineProperty(window, 'guardian', { value: { @@ -24,8 +15,6 @@ describe('decidePublicPath', () => { beforeEach(() => { jest.resetModules(); - mockHostname(undefined); - mockFrontendAssetsFullURL('https://assets.guim.co.uk/'); process.env = { NODE_ENV: undefined, HOSTNAME: undefined }; @@ -41,9 +30,9 @@ describe('decidePublicPath', () => { expect(decidePublicPath()).toEqual('https://assets.guim.co.uk/assets/'); }); - it('with production flag and localhost', () => { + it('with production flag in CI', () => { process.env.NODE_ENV = 'production'; - mockHostname('localhost'); + process.env.CI = 'true'; expect(decidePublicPath()).toEqual('/assets/'); }); diff --git a/dotcom-rendering/src/client/decidePublicPath.ts b/dotcom-rendering/src/client/decidePublicPath.ts index 41bb44db145..6a4247300a8 100644 --- a/dotcom-rendering/src/client/decidePublicPath.ts +++ b/dotcom-rendering/src/client/decidePublicPath.ts @@ -5,9 +5,9 @@ */ export const decidePublicPath = (): string => { const isDev = process.env.NODE_ENV === 'development'; - const isLocalHost = window.location.hostname === 'localhost'; + const isCI = process.env.CI === 'true'; // Use relative path if running locally or in CI - return isDev || isLocalHost + return isDev || isCI ? '/assets/' : `${window.guardian.config.frontendAssetsFullURL}assets/`; }; From 0b35a75a064b7d80fbf5503cbdc37c88c9dec538 Mon Sep 17 00:00:00 2001 From: Jonathon Herbert Date: Wed, 24 Jun 2026 12:50:02 +0100 Subject: [PATCH 02/12] Improve readability in decidePublicPath --- dotcom-rendering/src/client/decidePublicPath.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dotcom-rendering/src/client/decidePublicPath.ts b/dotcom-rendering/src/client/decidePublicPath.ts index 6a4247300a8..e7c755ded81 100644 --- a/dotcom-rendering/src/client/decidePublicPath.ts +++ b/dotcom-rendering/src/client/decidePublicPath.ts @@ -6,8 +6,9 @@ export const decidePublicPath = (): string => { const isDev = process.env.NODE_ENV === 'development'; const isCI = process.env.CI === 'true'; - // Use relative path if running locally or in CI - return isDev || isCI + + const useLocalAssets = isDev || isCI; + return useLocalAssets ? '/assets/' : `${window.guardian.config.frontendAssetsFullURL}assets/`; }; From a1bba7b30f7c105d66fb6d999bea60080a427963 Mon Sep 17 00:00:00 2001 From: Jonathon Herbert Date: Wed, 24 Jun 2026 12:53:42 +0100 Subject: [PATCH 03/12] Add CI env var to webpack's DefinePlugin to make it available in client code --- dotcom-rendering/webpack/webpack.config.js | 1 + 1 file changed, 1 insertion(+) diff --git a/dotcom-rendering/webpack/webpack.config.js b/dotcom-rendering/webpack/webpack.config.js index f4a89198a5c..79bea2c0c9b 100644 --- a/dotcom-rendering/webpack/webpack.config.js +++ b/dotcom-rendering/webpack/webpack.config.js @@ -60,6 +60,7 @@ const commonConfigs = ({ platform }) => ({ new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV), 'process.env.HOSTNAME': JSON.stringify(process.env.HOSTNAME), + 'process.env.CI': JSON.stringify(process.env.CI), }), // Matching modules specified in this regex will not be imported during the webpack build // We use this if there are optional dependencies (e.g in jsdom, ws) to remove uneccesary warnings in our builds / console outpouts. From c90192d3a04a68455b88083c490e573af3d01ea7 Mon Sep 17 00:00:00 2001 From: Jonathon Herbert Date: Wed, 24 Jun 2026 17:50:34 +0100 Subject: [PATCH 04/12] Add USE_LOCAL_ASSETS to makefile dev, makefile dev-prod, and Playwright GHA, to be more explicit about where local assets are necessary, and what drives the decision to use them --- .github/workflows/playwright.yml | 3 ++- dotcom-rendering/makefile | 2 ++ dotcom-rendering/src/client/decidePublicPath.ts | 4 +--- dotcom-rendering/webpack/webpack.config.js | 4 +++- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index e393fd6e75d..489b72b3408 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -39,7 +39,8 @@ jobs: run: pnpm playwright test --shard=${{ matrix.group }}/8 working-directory: ./dotcom-rendering env: - NODE_ENV: production + NODE_ENV: 'production' + USE_LOCAL_ASSETS: true - uses: actions/upload-artifact@v7 if: always() diff --git a/dotcom-rendering/makefile b/dotcom-rendering/makefile index c1cbe880f06..04b1b290102 100644 --- a/dotcom-rendering/makefile +++ b/dotcom-rendering/makefile @@ -43,10 +43,12 @@ prod: NODE_ENV=production node dist/server.js prod-local: export DISABLE_LOGGING_AND_METRICS = true +prod-local: export USE_LOCAL_ASSETS = true prod-local: prod # dev ######################################### +dev: export USE_LOCAL_ASSETS = true dev: clear clean-dist install $(call log, "starting DEV server") @NODE_ENV=development webpack serve --config ./webpack/webpack.config.js diff --git a/dotcom-rendering/src/client/decidePublicPath.ts b/dotcom-rendering/src/client/decidePublicPath.ts index e7c755ded81..5ec070e4c6d 100644 --- a/dotcom-rendering/src/client/decidePublicPath.ts +++ b/dotcom-rendering/src/client/decidePublicPath.ts @@ -4,10 +4,8 @@ * @returns The webpack public path to use */ export const decidePublicPath = (): string => { - const isDev = process.env.NODE_ENV === 'development'; - const isCI = process.env.CI === 'true'; + const useLocalAssets = process.env.USE_LOCAL_ASSETS === 'true'; - const useLocalAssets = isDev || isCI; return useLocalAssets ? '/assets/' : `${window.guardian.config.frontendAssetsFullURL}assets/`; diff --git a/dotcom-rendering/webpack/webpack.config.js b/dotcom-rendering/webpack/webpack.config.js index 79bea2c0c9b..1f58f5bd632 100644 --- a/dotcom-rendering/webpack/webpack.config.js +++ b/dotcom-rendering/webpack/webpack.config.js @@ -60,7 +60,9 @@ const commonConfigs = ({ platform }) => ({ new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV), 'process.env.HOSTNAME': JSON.stringify(process.env.HOSTNAME), - 'process.env.CI': JSON.stringify(process.env.CI), + 'process.env.USE_LOCAL_ASSETS': JSON.stringify( + process.env.USE_LOCAL_ASSETS, + ), }), // Matching modules specified in this regex will not be imported during the webpack build // We use this if there are optional dependencies (e.g in jsdom, ws) to remove uneccesary warnings in our builds / console outpouts. From 5707575a560f4a4991a1d79e003683d52295be09 Mon Sep 17 00:00:00 2001 From: Jonathon Herbert Date: Thu, 25 Jun 2026 11:17:48 +0100 Subject: [PATCH 05/12] Amend test --- .../src/client/decidePublicPath.test.ts | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/dotcom-rendering/src/client/decidePublicPath.test.ts b/dotcom-rendering/src/client/decidePublicPath.test.ts index dbe18fe44aa..e5aca7f5b68 100644 --- a/dotcom-rendering/src/client/decidePublicPath.test.ts +++ b/dotcom-rendering/src/client/decidePublicPath.test.ts @@ -17,22 +17,11 @@ describe('decidePublicPath', () => { mockFrontendAssetsFullURL('https://assets.guim.co.uk/'); - process.env = { NODE_ENV: undefined, HOSTNAME: undefined }; + process.env = { USE_LOCAL_ASSETS: undefined }; }); - it('with development flag', () => { - process.env.NODE_ENV = 'development'; - expect(decidePublicPath()).toEqual('/assets/'); - }); - - it('with production flag', () => { - process.env.NODE_ENV = 'production'; - expect(decidePublicPath()).toEqual('https://assets.guim.co.uk/assets/'); - }); - - it('with production flag in CI', () => { - process.env.NODE_ENV = 'production'; - process.env.CI = 'true'; + it('with USE_LOCAL_ASSETS flag', () => { + process.env.USE_LOCAL_ASSETS = 'true'; expect(decidePublicPath()).toEqual('/assets/'); }); From 0e07458d89b1f9875da1932628a341add0d9afd0 Mon Sep 17 00:00:00 2001 From: Jonathon Herbert Date: Thu, 25 Jun 2026 12:01:17 +0100 Subject: [PATCH 06/12] String for env var --- .github/workflows/playwright.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index 489b72b3408..1d88ac8768b 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -40,7 +40,7 @@ jobs: working-directory: ./dotcom-rendering env: NODE_ENV: 'production' - USE_LOCAL_ASSETS: true + USE_LOCAL_ASSETS: 'true' - uses: actions/upload-artifact@v7 if: always() From 28598d246d965d2df05fdd02eed6070162e36c67 Mon Sep 17 00:00:00 2001 From: Jonathon Herbert Date: Thu, 2 Jul 2026 12:28:42 +0100 Subject: [PATCH 07/12] Test: remove USE_LOCAL_ASSETS in playwright workflow --- .github/workflows/playwright.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index 1d88ac8768b..68cdf48b523 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -40,7 +40,6 @@ jobs: working-directory: ./dotcom-rendering env: NODE_ENV: 'production' - USE_LOCAL_ASSETS: 'true' - uses: actions/upload-artifact@v7 if: always() From d1ef72aa6e4d132619bcd8f843a4edc394ffe356 Mon Sep 17 00:00:00 2001 From: Jonathon Herbert Date: Thu, 2 Jul 2026 20:14:16 +0100 Subject: [PATCH 08/12] =?UTF-8?q?Remove=20DCR=20container=20for=20playwrig?= =?UTF-8?q?ht=20tests=20=E2=80=94=20it's=20not=20used?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/playwright.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index 68cdf48b523..658840e5252 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -14,11 +14,6 @@ jobs: matrix: # keep aligned with the number of shards used by `playwright test` group: [1, 2, 3, 4, 5, 6, 7, 8] - services: - DCR: - image: ${{ inputs.container-image }} - ports: - - 9000:9000 steps: - name: Checkout uses: actions/checkout@v6 @@ -40,6 +35,7 @@ jobs: working-directory: ./dotcom-rendering env: NODE_ENV: 'production' + USE_LOCAL_ASSETS: 'true' - uses: actions/upload-artifact@v7 if: always() From 2f5106f32c14180d50a45e228d563bce4e77d970 Mon Sep 17 00:00:00 2001 From: Jonathon Herbert Date: Thu, 2 Jul 2026 20:21:07 +0100 Subject: [PATCH 09/12] Put the container back. Learning a lot here. --- .github/workflows/playwright.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index 658840e5252..1d88ac8768b 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -14,6 +14,11 @@ jobs: matrix: # keep aligned with the number of shards used by `playwright test` group: [1, 2, 3, 4, 5, 6, 7, 8] + services: + DCR: + image: ${{ inputs.container-image }} + ports: + - 9000:9000 steps: - name: Checkout uses: actions/checkout@v6 From 8938d2405e3d86b174dea24c442b5455bf7e6312 Mon Sep 17 00:00:00 2001 From: Jonathon Herbert Date: Thu, 2 Jul 2026 20:25:01 +0100 Subject: [PATCH 10/12] Pass USE_LOCAL_ASSETS env var to container, not playwright environment --- .github/workflows/playwright.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index 1d88ac8768b..d51d35227ae 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -19,6 +19,8 @@ jobs: image: ${{ inputs.container-image }} ports: - 9000:9000 + env: + USE_LOCAL_ASSETS: 'true' steps: - name: Checkout uses: actions/checkout@v6 @@ -39,8 +41,7 @@ jobs: run: pnpm playwright test --shard=${{ matrix.group }}/8 working-directory: ./dotcom-rendering env: - NODE_ENV: 'production' - USE_LOCAL_ASSETS: 'true' + NODE_ENV: production - uses: actions/upload-artifact@v7 if: always() From 63e85f19d955afdf3249af1007e3e87a8abda2ee Mon Sep 17 00:00:00 2001 From: Jonathon Herbert Date: Thu, 2 Jul 2026 20:41:17 +0100 Subject: [PATCH 11/12] Add USE_LOCAL_ASSETS=true to containerfile --- .github/workflows/playwright.yml | 2 -- dotcom-rendering/Containerfile | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index d51d35227ae..e393fd6e75d 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -19,8 +19,6 @@ jobs: image: ${{ inputs.container-image }} ports: - 9000:9000 - env: - USE_LOCAL_ASSETS: 'true' steps: - name: Checkout uses: actions/checkout@v6 diff --git a/dotcom-rendering/Containerfile b/dotcom-rendering/Containerfile index b068323d4d4..0ab30cbf682 100644 --- a/dotcom-rendering/Containerfile +++ b/dotcom-rendering/Containerfile @@ -11,5 +11,6 @@ EXPOSE 9000 ENV DISABLE_LOGGING_AND_METRICS=true ENV NODE_ENV=production +ENV USE_LOCAL_ASSETS=true ENTRYPOINT ["node", "article-rendering/dist/server.js"] From d07293a22180124758bdca0d0c34bbb895f70a91 Mon Sep 17 00:00:00 2001 From: Jonathon Herbert Date: Thu, 2 Jul 2026 20:49:04 +0100 Subject: [PATCH 12/12] Add USE_LOCAL_ASSETS env var to bundle build --- .github/workflows/container.yml | 2 ++ dotcom-rendering/Containerfile | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/container.yml b/.github/workflows/container.yml index 6ac78859080..7c9a6ed3f91 100644 --- a/.github/workflows/container.yml +++ b/.github/workflows/container.yml @@ -32,6 +32,8 @@ jobs: - name: Generate production bundle run: make riffraff-bundle working-directory: dotcom-rendering + env: + USE_LOCAL_ASSETS: true - name: Build Container Image id: build_image diff --git a/dotcom-rendering/Containerfile b/dotcom-rendering/Containerfile index 0ab30cbf682..b068323d4d4 100644 --- a/dotcom-rendering/Containerfile +++ b/dotcom-rendering/Containerfile @@ -11,6 +11,5 @@ EXPOSE 9000 ENV DISABLE_LOGGING_AND_METRICS=true ENV NODE_ENV=production -ENV USE_LOCAL_ASSETS=true ENTRYPOINT ["node", "article-rendering/dist/server.js"]