@madgex/fert 7.0.12 → 7.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -19,7 +19,7 @@ jobs:
19
19
  uses: actions/setup-node@v4
20
20
  with:
21
21
  cache: npm
22
- node-version: 22
22
+ node-version: "lts/*"
23
23
 
24
24
  - name: Setup SSH Keys and known_hosts
25
25
  env:
@@ -1,6 +1,5 @@
1
1
  import path from 'node:path';
2
2
  import { pathToFileURL } from 'node:url';
3
- import merge from 'lodash/merge.js';
4
3
  import * as vite from 'vite';
5
4
  import { buildExternalAssets } from './build-external-assets.js';
6
5
  import { log } from '../../utils/logging.js';
@@ -34,7 +33,7 @@ export async function bundleEntry(fertConfig, options = {}) {
34
33
  },
35
34
  };
36
35
 
37
- merge(viteConfig, dynamicOptions);
36
+ viteConfig = vite.mergeConfig(viteConfig, dynamicOptions);
38
37
 
39
38
  await vite.build(viteConfig);
40
39
 
@@ -3,7 +3,7 @@ import path from 'node:path';
3
3
  import { glob } from 'node:fs/promises';
4
4
  import chalk from 'chalk';
5
5
  import open from 'open';
6
- import chokidar from 'chokidar4';
6
+ import chokidar from 'chokidar5';
7
7
  import { resolveConfig, findFertConfigDir } from '../utils/index.js';
8
8
  import { validateLocalConfigs } from '../utils/configs.js';
9
9
  import { devServer } from '../../server/server.js';
@@ -1,4 +1,3 @@
1
- import axios from 'axios';
2
1
  import chalk from 'chalk';
3
2
  import { log } from '../utils/logging.js';
4
3
  import { PROPERTY_ID_API, ONE_WEEK } from '../../constants.js';
@@ -10,30 +9,29 @@ const cache = new PersistentCacheWithTtl('cpid-cache', {
10
9
 
11
10
  export async function doCpidLookup(clientPropertyId) {
12
11
  const API_URL = new URL(clientPropertyId, PROPERTY_ID_API).toString();
13
-
14
- const results = await axios
15
- .get(API_URL, { timeout: 5000 })
16
- .then((res) => {
17
- return res.data.data;
18
- })
19
- .catch((error) => {
20
- log.error(
21
- `Unable to lookup CPID [${chalk.yellow(
22
- clientPropertyId,
23
- )}] from ${chalk.cyan(API_URL)}: ${chalk.redBright(error.message)}\n`,
24
- );
25
-
26
- throw Error(error.message);
27
- });
28
-
29
- const { brandName, parentId: parentCpid } = results;
30
-
31
- return {
32
- brandName,
33
- parentCpid: parentCpid ?? false,
34
- rootClientPropertyId: parentCpid ?? clientPropertyId,
35
- isAffiliate: !!parentCpid,
36
- };
12
+ try {
13
+ const results = await fetch(API_URL, { signal: AbortSignal.timeout(5000) });
14
+ if (!results.ok) {
15
+ const errorMessage = await results.text();
16
+ throw new Error(`${results.status} - ${errorMessage}`);
17
+ }
18
+ const { data } = await results.json();
19
+ const { brandName, parentId: parentCpid } = data;
20
+ return {
21
+ brandName,
22
+ parentCpid: parentCpid ?? false,
23
+ rootClientPropertyId: parentCpid ?? clientPropertyId,
24
+ isAffiliate: !!parentCpid,
25
+ };
26
+ } catch (error) {
27
+ log.error(
28
+ `Unable to lookup CPID [${chalk.yellow(
29
+ clientPropertyId,
30
+ )}] from ${chalk.cyan(API_URL)}: ${chalk.redBright(error.message)}\n`,
31
+ );
32
+
33
+ throw error;
34
+ }
37
35
  }
38
36
 
39
37
  export async function cpidLookup(clientPropertyId, options = {}) {
@@ -0,0 +1,113 @@
1
+ ## Branding Repository Overview
2
+
3
+ ## What is a Branding Repo?
4
+
5
+ These git repositories contain the Branding, Header & Footers, Configs and other assets for **one** client, and **one** client is represented by a `clientPropertyId (CPID)`, where the repository name will be include the CPID `madgex-<CLIENT_PROPERTY_ID>` e.g. https://github.com/wiley/madgex-ff6102ff-0f4b-43d1-a2c7-83b835b8dee5 .
6
+
7
+ This means there is one Branding Repo per affiliate too, as well as the regular Parent site.
8
+
9
+ > 💁 For example, BMJJobs has 3 Branding Repos.
10
+ >
11
+ > 1. "Parent" - https://github.com/wiley/madgex-8b60330c-d2ec-4cba-b018-acb84bd97719
12
+ > 2. "Affiliate Careers" - https://github.com/wiley/madgex-1a70fdf6-1fa8-4c37-9968-b88f195ff2d8
13
+ > 3. "Affiliate HealthCareers" - https://github.com/wiley/madgex-33837840-d7e8-4453-82d7-8b0ed7c6efe6
14
+
15
+ ### Services in the Branding Repo
16
+
17
+ A Branding Repo will contain **one or many** `services`. Each `service` follows the same structure stated below.
18
+ Outside of some generic stuff like `config`, the majority of your work will be done inside a service folder.
19
+
20
+ The `serviceName` of a `service` is directly tied to the V6 `service` name its for:
21
+
22
+ - [`jobseekers-frontend`](https://github.com/wiley/madgex-jobseekers-frontend/), **also consumed by `V5 ResponsiveJobseekersSite`**
23
+ - [`recruiterservices-frontend`](https://github.com/wiley/madgex-recruiterservices-frontend/), **also consumed by `V5 RecruiterSite`**
24
+
25
+ > [!TIP]
26
+ > **`recruiterservices-frontend` will only be in a "Parent" Branding Repo**, as there is only 1 Recruiter Site, and never separate Recruiter Sites for affiliates. Do not put `recruiterservices-frontend` in an "Affiliate" Branding Repo.
27
+
28
+ ### Branding Repo Contents and Structure
29
+
30
+ This structure **must be followed and are required unless stated**, but some folders and files are optional:
31
+
32
+ <pre>
33
+ .
34
+ ├── config <strong>(optional, configs must go in here)</strong>
35
+ │   ├── JobBoardConfig.careerpathCountryIso.json
36
+ │   ├── ...
37
+ ├── fert.config.js
38
+ ├── jenkinsfile
39
+ ├── .gitignore
40
+ ├── package.json
41
+ └── services
42
+ ├── &lt;service-folder-name&gt;
43
+ │   ├── brand.json
44
+ │   ├── fert.service.config.js
45
+ │   ├── public <strong>(asset must go in here)</strong>
46
+ │   │   ├── fonts
47
+ │   │   │   ├── my-font.woff2 <strong>(optional)</strong>
48
+ │   │   ├── images
49
+ │   │   │   ├── favicon.ico
50
+ │   │   │   └── logo.svg <strong>(optional, recommended)</strong>
51
+ │   │   ├── translation.json <strong>(optional)</strong>
52
+ │   │   ├── redirects.csv <strong>(optional)</strong>
53
+ │   │   ├── ...
54
+ │   ├── src
55
+ │   │   ├── css
56
+ │   │   │   └── styles.css <strong>(optional)</strong>
57
+ │   │   ├── index.js
58
+ │   │   ├── ...
59
+ │   └── templates
60
+ │   ├── footer.njk
61
+ │   └── header.njk
62
+ ├── &lt;another-service-folder-name&gt;
63
+ │   ├── ...
64
+
65
+
66
+ </pre>
67
+
68
+ - you must put **configs** in the `/config` folder
69
+ - **service templates** `header.njk` and `footer.njk` **must exist**, these are expected to exist by the header-footer-podlet service. e.g. `/services/<service-folder-name>/templates/header.njk`
70
+ - **translation overrides** must be the file `/services/<service-folder-name>/public/translation.json`
71
+ - [V6 Redirects](https://wiley-global.atlassian.net/wiki/spaces/MGXDC/pages/100008912/Redirects+on+V6+Jobseekers+Frontend) must be the file `/services/<service-folder-name>/public/redirects.csv`
72
+ - **service assets** must go in `/services/<service-folder-name>/public/**/*`.
73
+ - This serves a dual purpose: this whole `public` folder is uploaded on deployment
74
+ - It is also the special folder that the `Vite` build system uses. When you reference `/public/<filename>` in your code this tells `Vite` its an asset it should know about e.g. `/public/fonts/my-font.woff2`
75
+ - **package.json** - should contain at least `devDependencies` of `@madgex/fert`, and have `dev` and `build` scripts
76
+ - The **CSS** for a service exists for 2 reasons: Font registration & Custom Header/Footer styling (not Themes) **only**. This means this file is cheekily doing 2 jobs, but must never have CSS for anything else in it.
77
+ - **brand.json** - contains design system tokens and is the **only** way to customise site appearance (e.g. button colours, CTA backgrounds, ...). If something cannot be changed via a token, it is not customisable. We do not add CSS to work around this limitation—this ensures maintainability of both the design system and the platform.
78
+ - **fert.config.js** - the root configuration file for FERT. Contains the `clientPropertyId` (CPID) that identifies which client this Branding Repo belongs to. This file is required and must exist at the repository root.
79
+
80
+ ```js
81
+ // /fert.config.js
82
+ module.exports = {
83
+ clientPropertyId: 'ff6102ff-0f4b-43d1-a2c7-83b835b8dee5', // required
84
+ };
85
+ ```
86
+
87
+ - **fert.service.config.js** - per-service configuration file that must exist in each service folder.
88
+
89
+ ```js
90
+ // /services/<service-folder-name>/fert.service.config.js
91
+ module.exports = {
92
+ serviceName: 'jobseekers-frontend', // required, `jobseekers-frontend`, `recruiterservices-frontend`
93
+ entry: './src/index.js', // required - almost always this path
94
+ // optional
95
+ externalAssets: {
96
+ links: ['https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400&display=swap'],
97
+ scripts: [],
98
+ },
99
+ };
100
+ ```
101
+
102
+ ### How does a Branding Repo work?
103
+
104
+ - We use [`@madgex/fert`](https://github.com/wiley/madgex-frontend-rollout-tool) to dev/build/publish Branding Repos and Configs.
105
+ - Locally you'll usually only use `dev` which should be `npm run dev`
106
+ - Internally `"FERT"` runs a local server which contains a copy of the `header-footer-podlet` service used to render `header.njk` and `footer.njk` files.
107
+ - `FERT` also includes a `Vite` dev server which compiles any JS, CSS and the `brand.json`.
108
+ - a Vite dev server is run for **each service**. `jobseekers-frontend` service might be on http://localhost:4001 whereas `recruiterservices-frontend` might be on http://localhost:4021.
109
+ - The service's `brand.json` is used to generate `CSS variables` and `JSON variables` files. `CSS variables` are used in conjunction with [`Madgex Design System CSS`](https://design-system.jb.dev.madgexhosting.net/)
110
+ - Like the Header and Footer, the Design System branding can be previewed via the page contents when viewing the Vite dev server page.
111
+ - `FERT` is used on the [`nomad` Jenkins server](https://nomad.madgexhosting.net) to `build` the Branding Repo
112
+ - JS and CSS are compiled by Vite
113
+ - template, JS and CSS `/public/*` paths are replaced with public asset URLs like https://asset-relay.madgexjb.com/big-work-bag-6tORXNlh/images/logo.png . See [Asset Relay](https://github.com/wiley/madgex-asset-relay)
@@ -0,0 +1,39 @@
1
+ # Branding Repo Checklist
2
+
3
+ ## Generic
4
+
5
+ - [ ] Create **non-master** branch of any new work, this will create a `dev` build/deployment and ensures V5 `UAT` will display the latest changes
6
+ - [ ] Verify your **non-master** branch built and deployed successfully on [nomad](https://nomad.madgexhosting.net) before merging to master (don't want to wait the 5 minute delay? Click "Build now" on your branch, or "Scan multibranch pipeline now" to look for you new branch immediately)
7
+ - [ ] Config files go in the `<root>/config/` folder
8
+
9
+ ## Services
10
+
11
+ - [ ] Make sure all nav link URLs are correct
12
+ - [ ] Ensure all asset paths pointing to local public folder begin with forward slash `/public`
13
+ - [ ] Make sure you are not using any external assets like images where they might disappear/be blocked/cross domain issues. Download and put them in the `/public` folder instead
14
+ - This excludes links/scripts in `fert.service.config.js`
15
+ - [ ] Store fonts locally in `/public/fonts` and register them in your css.
16
+ - Don't use Google Fonts API - download those fonts and register them in CSS
17
+ - Adobe fonts still need to use external link **registered in `fert.service.config.js`** (not in the CSS file directly)
18
+ - [ ] Make sure the css file import is correct in `src/index.js` entry file. If you are not using a css file (no fonts to register) or the file does not exist, remove the import but keep `src/index.js` file even if its empty
19
+ - [ ] If you have `.svg` files, ensure it has a `width` & `height` attribute on the `<svg>` element in the file, this ensures the browser knows its aspect ratio
20
+ - [ ] 🚨 Don't override any `mds` CSS, you must use `brand.json`
21
+ - [ ] Ensure images that are links have `alt` text. A link must have screen-readable text inside it
22
+ - [ ] Image alt text should reflect what you can visually see, if the image has visible text, put this in the alt text first. e.g. Logo visually says `"BMJ Jobs"` and links to homepage, you could have an alt text of `"BMJ Jobs - Home"`
23
+ - [ ] the `/public/images/favicon.ico` file exists
24
+ - [ ] Make sure each service has its own files, and has all required files. Remember **each service is standalone**, there is no sharing of assets, templates, brand.json or anything. Even if `brand.json` is duplicated for each service.
25
+
26
+ ## brand.json
27
+
28
+ - [ ] Make sure you are overriding JSON that exists ([Make sure the structure matches the base JSON](https://github.com/wiley/madgex-design-system/tree/master/packages/%40madgex.design-system/src/tokens))
29
+ - [ ] Don't override font sizes unless the client has some really strict requirements
30
+ - [ ] Don't use `$type`, these are already internally specified, you only need to override `$value`.
31
+ - [ ] Only override a token if its value is different than the default
32
+
33
+ ## Header/Footer Theme
34
+
35
+ - [ ] Check locale is correct, e.g. `en-US` for american/canadian sites
36
+ - [ ] Check `serviceName` matches your service, e.g. `jobseekers-frontend` for `jobseekers-frontend`
37
+ - [ ] All macro **param names** and **`string` values** should be wrapped in `"double quotes"`. e.g. **Keep the macro input as JSON** so it can be easily copied back into Storybook
38
+ - Bad: `cssVarFontFamily: '"My Font", sans-serif'`
39
+ - Good: `"cssVarFontFamily": "\"My Font\", sans-serif"`
@@ -0,0 +1,31 @@
1
+ # Glossary
2
+
3
+ ### Affiliate
4
+
5
+ Also known as a `"Network Skin"` in V5, this is a "child" of a "Parent" site. An "Affiliate" is actually a sub-set of data from the "Parent" site, you can think of it as a filtered view of the "Parent" that also includes its own Branding and customisations to appear like a separate site.
6
+
7
+ In V6 each "Affiliate" gets its own `client-property-id`, so each "Affiliate" has its own [Branding Repo](BRANDING_REPO_OVERVIEW.md).
8
+
9
+ ### [Branding Repo](BRANDING_REPO_OVERVIEW.md)
10
+
11
+ A git repository for each client, holding the Branding information, Header/Footer templates, fonts, configs, translation overrides, V6 Redirects etc. A repository name will be include the CPID `madgex-<CLIENT_PROPERTY_ID>` e.g. https://github.com/wiley/madgex-ff6102ff-0f4b-43d1-a2c7-83b835b8dee5 .
12
+
13
+ ### client
14
+
15
+ Also known as a `client-property-id (CPID)` which represents a Parent client OR an affiliate. This means `BMJJobs` with 1 Parent and 2 Affiliates has **3** `client-property-id`s, and therefore **3** Branding Repos.
16
+
17
+ ### client-property-id (CPID)
18
+
19
+ Main identifier for a `client` in V6. Everything hangs off this GUID, each V6 request contains a header `x-client-property-id` which V6 frontend services use to generate a page and fetch resources. A CPID exists for each Parent client and for each of its affiliates.
20
+
21
+ ### configs
22
+
23
+ For Branding Repos, this means **V6** configs, which are `json` files in the `<root>/config` directory of each `Branding Repo`. For **V5** you should configure these in the `xml` files in `V5 Project Repo`.
24
+
25
+ ### [FERT (FrontEnd Rollout Tool)](../README.md)
26
+
27
+ A commandline tool which provides a development environment (powered by Vite & local dev server), build process (Vite), deployment process (runs in Jenkins), Config validation and boilerplate generation (`npx @madgex/fert init` to set up an empty repo).
28
+
29
+ ### service/ serviceName
30
+
31
+ Represents a service like the Jobseekers Frontend, or Recruiter Site. Almost always is **required to be the V6 name of the service**: `jobseekers-frontend` | `recruiterservices-frontend`
package/docs/README.md ADDED
@@ -0,0 +1,214 @@
1
+ # Building Frontend Branding
2
+
3
+ - [🐣 CHECKLIST](CHECKLIST.md)
4
+ - [🧙 Glossary](GLOSSARY.md)
5
+ - [🎓 Branding Repository Overview](BRANDING_REPO_OVERVIEW.md)
6
+ - [⚽️ Headers and Footers with Themes](https://header-footer-podlet.job.madgexhosting.net/storybook/?path=/docs/getting-started--docs)
7
+ - [🔀 V6 Redirects](https://wiley-global.atlassian.net/wiki/spaces/MGXDC/pages/100008912/Redirects+on+V6+Jobseekers+Frontend)
8
+
9
+ ## 🎒 Getting Started
10
+
11
+ Check out [Branding Repository Overview](BRANDING_REPO_OVERVIEW.md) for the structure of a Branding Repo and its `services`, if you have not seen it yet.
12
+
13
+ Find out your `Client Property ID` by visiting [Madgexverse](https://madgexverse.job.madgexhosting.net). If your CPID does not exist, you can not work on this Branding Repo right now.
14
+
15
+ This will give you your repository `https://github.com/wiley/madgex-<CPID>` e.g. https://github.com/wiley/madgex-ff6102ff-0f4b-43d1-a2c7-83b835b8dee5. If this is a brand new client, the Branding Repo should be automatically created on `master` branch.
16
+
17
+ > **Ask Systems why, if this is not automatically created**
18
+
19
+ ### If you have an **empty** Branding Repo (e.g. a git repository has been set up but has no files)
20
+
21
+ - Switch into a new branch
22
+ - `cd` into your cloned empty git repo. Use `npx @madgex/fert init .` and follow the prompts, this will populate your directory, including at least one `service` where the majority of the work will be done.
23
+ - `npm i` install packages.
24
+
25
+ ### If you have an existing Branding Repo
26
+
27
+ - switch into a new branch
28
+ - You can add a new service folder to `<root>/services/<service-name>` (`jobseekers-frontend` or `recruiterservices-frontend`), following [the Branding Repo service structure here](BRANDING_REPO_OVERVIEW.md).
29
+ - It is good practice to ensure `<root>/package.json` `@madgex/fert` version is the latest.
30
+
31
+ > [!IMPORTANT]
32
+ > To ensure you have the latest node_module packages (especially `header-footer-podlet` within fert), run `npm update`.
33
+
34
+ - `npm run dev` to begin dev servers for all services. Each service will have its own development port, e.g. `jobseekers-frontend` service might be on http://localhost:4001 whereas `recruiterservices-frontend` might be on http://localhost:4021.
35
+ - These ports may change if they are not free (if you are running multiple Branding Repos at the same time!), another port will automatically be chosen
36
+
37
+ > [!IMPORTANT]
38
+ > Remember **each service is standalone**, there is no sharing of assets, templates, brand.json or anything. This means you might end up with duplicates between service like the `brand.json`.
39
+
40
+ ## 🎨 Service brand.json
41
+
42
+ Using these [`base madgex-design-system JSON tokens`](https://github.com/wiley/madgex-design-system/tree/master/packages/%40madgex.design-system/src/tokens) as reference, override `$value`s using the same JSON structure in this single file.
43
+ This JSON file exclusively controls the styling of the V6 pages (and even [emails](https://github.com/wiley/madgex-template-renderer/blob/8daf93aea7f2f1b937a0da39496b23657e118ba6/lib/templates/accountapproved.html.njk#L4) & [social images for jobs](https://github.com/wiley/madgex-display-image-render-api/blob/67e4a1087122329306278912704ca642933883ed/templates/ads/jobboard-basic/index.jsx#L14)).
44
+
45
+ > [!IMPORTANT]
46
+ > If branding can't be done here, do not add custom CSS, we should improve the tokens instead, however the tokens have been fairly stable for many years.
47
+
48
+ Currently V5 does not use `madgex-design-system` and therefore does not use brand.json at all.
49
+
50
+ > Coming soon? Automatic brand.json validation?
51
+
52
+ ## 🚧 Service Header & Footer templates
53
+
54
+ ### Themes vs Custom templates
55
+
56
+ We much prefer to use [Themes](https://header-footer-podlet.job.madgexhosting.net/storybook/?path=/docs/getting-started--docs) (which are built-in to the header-footer-podlet service) for the `header.njk` and `footer.njk` templates. Themes are faster to make, reduces the amount of common errors, automatically gets updates and fixes. Theme CSS is isolated with ShadowDOM so they always look good on V5 or V6.
57
+
58
+ Designers will try to use Themes for new projects and the output should look how they expect.
59
+
60
+ Sometimes we convert pre-existing Custom Headers and Footers to Themes , even if this means small things change. These changes are usually passed to the project manager to verify they are OK to proceed with.
61
+
62
+ Themes work better on V5 than Custom templates. If you must create Custom templates you will need to ensure the CSS acts the same way on both V5 and V6.
63
+
64
+ ### Custom template
65
+
66
+ > Coming soon? Custom template starter-from-theme?
67
+
68
+ Available global Nunjucks context:
69
+
70
+ - `templatePath: string`: Required prefix for importing additional Nunjucks files e.g. `{%- include templatePath + './include/my-other-file.njk' -%}`
71
+ - `path: string`: current page relative URL
72
+ - `normaliseUrl: Filter`: removes trailing slash from a URL, e.g. `{{path === myNavLink | normaliseUrl }}`
73
+ - `getServiceRoute(serviceRouterId,routeId,paramsObj,queryObj):Function` : [ usage](https://github.com/wiley/madgex-hapi-reverse-router/blob/master/packages/@madgex.hapi-reverse-router/README.md#usage-example)
74
+ - `getAbsoluteServiceRoute(serviceRouterId,routeId,paramsObj,queryObj):Function` : [ usage](https://github.com/wiley/madgex-hapi-reverse-router/blob/master/packages/@madgex.hapi-reverse-router/README.md#usage-example)
75
+ - routeId reference for [`"jobseekersite"`](https://jobseekers-frontend.job.madgexhosting.net/api/routing-table/ff6102ff-0f4b-43d1-a2c7-83b835b8dee5)
76
+ - routeId reference for [`"recruitersite"`](https://recruiterservices-frontend.job.madgexhosting.net/api/routing-table/ff6102ff-0f4b-43d1-a2c7-83b835b8dee5)
77
+ - e.g. `{{getServiceRoute('jobseekersite', 'account.login', {}, {Pipline: path})}}`
78
+ - `dayjs:Function`: like momentjs [see here](https://github.com/iamkun/dayjs/tree/dev?tab=readme-ov-file#api)
79
+
80
+ ## 🔠 Service V6 translations
81
+
82
+ Each `service` in a branding repo may have **optional** translation overrides.
83
+
84
+ These live at `<root>/services/<SERVICE_NAME>/public/translation.json`, e.g. https://github.com/wiley/madgex-ff6102ff-0f4b-43d1-a2c7-83b835b8dee5/blob/901e5b2295892747015bd1c9bab7ac307b4e2112/services/jobseekers-frontend/public/translation.json .
85
+
86
+ Base reference for `en-GB` on [jobseekers-frontend](https://github.com/wiley/madgex-jobseekers-frontend/blob/master/locales/en-GB/translation.json).
87
+
88
+ > Coming soon? Automatic translation validation?
89
+
90
+ ## ⚙️ Configs (V6)
91
+
92
+ Configs live in the root of a Branding Repo like `<root>/config/` e.g. https://github.com/wiley/madgex-ff6102ff-0f4b-43d1-a2c7-83b835b8dee5/tree/master/config . Configs are service-agnostic and don't live in the service folders.
93
+
94
+ Configs are validated in Jenkins for each branch of a Branding Repo and will block a deployment if they fail.
95
+
96
+ ### Common Configs for New Sites
97
+
98
+ For a new site, the two configs most commonly changed are:
99
+
100
+ - **[`JobBoardConfig.jobboardUserDataPreferenceSettings.json`](https://github.com/wiley/madgex-config-api-sdk/blob/465594b681724691853779b065cf9276f41f5327/schemas/JobBoardConfig.jobboardUserDataPreferenceSettings.js)** — Controls marketing preferences (e.g. 1st and 3rd party marketing checkboxes), user-related questions, and text displayed before or after marketing sections on forms.
101
+ - **[`JobBoardConfig.jobboardCustomRoutes.json`](https://github.com/wiley/madgex-config-api-sdk/blob/465594b681724691853779b065cf9276f41f5327/schemas/JobBoardConfig.jobboardCustomRoutes.js)** — Customises URL paths for pages (e.g. renaming `/careers` to `/articles` for the article lister) and sets a `prefix` for reverse proxy setups (e.g. when hosting the job board at `bmj.com/careers`).
102
+
103
+ ### Config Reference
104
+
105
+ We validate Configs on build, using a common package called `config-api-sdk` used on all V6 services. This holds reference to all configs [config-api-sdk](https://github.com/wiley/madgex-config-api-sdk/tree/master/schemas).
106
+ These schemas are Joi validation files that expect your config files to be in a correct JSON format.
107
+
108
+ Do not create config for any that are `read-only`, these are usually V5 Configs that need to be configured in the V5 Project Repo.
109
+
110
+ > Coming soon? Automatic config validation at development?
111
+
112
+ ## 🗑️ Adverts (Header leaderboard)
113
+
114
+ ```html
115
+ <div id="ad-leaderboard" class="hfp-leaderboard ad ad--leaderboard ad--leaderboard--empty"></div>
116
+ ```
117
+
118
+ On Themes this empty div is waiting to be populated with GTM. The GTM ad script should provide its own padding. This ad div is outside of the ShadowDOM and thus is affected by the page's global CSS.
119
+
120
+ On Custom templates you can choose to to include the ad div or not.
121
+
122
+ ## 🛠️ Build & Deployment pipeline
123
+
124
+ Builds and deployments happen on the [`nomad` Jenkins server](https://nomad.madgexhosting.net), each branding repo has its own `job`, e.g. https://nomad.madgexhosting.net/job/madgex-ff6102ff-0f4b-43d1-a2c7-83b835b8dee5/
125
+
126
+ While working on a **non-master** branch, builds in Jenkins can give you a good indication of everything working as it should and describe what exactly is being build and deployed, before the **master** branch is updated to build and deploy to production.
127
+
128
+ **non-master** branches on a Branding Repo will trigger builds & deployment to the `development` (asset store) location. These builds will be available for V5 `Local Dev`, `UAT` `QA` & `any Unknown` environments.
129
+
130
+ **master** branches will build and deploy to the `production` (asset store) location. These builds will be available for V6, and V5 `Staging` & `Production` environments.
131
+
132
+ > [!IMPORTANT]
133
+ > Remember deployments will happen automatically along with the build, on each branch updates.
134
+ >
135
+ > Currently it takes **less than 1 minute to build and deploy**, and may be a **5 minute polling** before branch changes are picked up.
136
+
137
+ > [!TIP]
138
+ > Builds & deployments **may take up to 5 minutes** to start on `nomad`. Don't want to wait? Click "Build now" on your branch, or "Scan multibranch pipeline now" to look for you new branch immediately.
139
+ > <img src="./jenkins-build-now.png" width="500" />
140
+
141
+ > [!TIP]
142
+ > For new sites, the automatic build might not be enabled.
143
+ > Go to the repo in `nomad` and check in `Configuration` that the checkbox in `Scan Multibranch Pipeline Triggers` is ticked and the interval is set to 5min.
144
+
145
+ > [!TIP]
146
+ > Failed builds will be automatically posted to the [Teams Channel pipline-alerts-fed](https://teams.microsoft.com/l/channel/19%3Aaff4053b353c49e1a4f401982db1fb6f%40thread.tacv2/pipeline-alerts-fed?groupId=46570170-3ede-47a1-8c11-7670ce7e5aa4&tenantId=24fe244f-890e-46ef-be2f-a5202976b7a5) . This is useful to subscribe to to ensure everything is working correctly before you merge to master.
147
+
148
+ ### 🚀 Deploying
149
+
150
+ In general, be prepared to synchronise your V5 deployment with your merge to **master** Branding Repo branch.
151
+
152
+ As it only takes **1 minute** to build and deploy, you might need to take this into account with V5 work.
153
+
154
+ #### Requirements
155
+
156
+ - **V5 to have deployed its configs to V6 configuration-api for your environment**. This means V5 should be deployed to `QA` so its configs are set in `V6 dev`. This also means if you want to deploy a **master** branch of the Branding Repo, V5 would have had to deploy its configs in `Production` before we get to deploy our Branding Repo.
157
+ > **Ask V5 Backend why if it's not deployed.**
158
+ - **KONG api keys exist for this CPID**. This should be an automated process [like this example](https://github.com/wiley/madgex-internal-kong/commit/f01ddef0479a72229a580d4c6eb33b942776035f), but if it does not exist for some reason this will fail a deployment.
159
+ > **Ask Systems why if it does not exist**
160
+
161
+ #### Scenario - V5 not using Branding Repo, and V6 not live
162
+
163
+ Merge branding repo working branch to master as soon as its ready. We assume V5 is in a `Production` so configs exist to enable deploying **master** branch. This would be `webtemp` domain if this is a new client.
164
+
165
+ #### Scenario - V5 is using Branding Repo, but V6 is not live
166
+
167
+ Merge branding repo working branch to master after it passes UAT/review and is ready for V5 `Production` to see new version.
168
+
169
+ Once it is deployed to **master** you can view V6 version of the site by using the HTTP Header `x-madgex-v6` with a value of `true` and visiting a Jobseeker Site URL like `https://www.bigworkbag.com/newalert`
170
+
171
+ #### Scenario - Both V5 is using Branding Repo, and V6 is already live
172
+
173
+ Merge branding repo working branch to master after it passes UAT/review and is ready for V5 `Production` to see new version.
174
+
175
+ There is no early preview for V6 unfortunately outside of the FERT development environment, and relying on V5's UAT for Header and Footer preview only (not V6 branding).
176
+
177
+ ### Enable Header Footer Podlet usage on V5
178
+
179
+ By default V5 is not using Header or Footer from the Branding Repo.
180
+ Create the config file in `<v5-site-resources>/Config/HeaderFooterPodlet.xml` [example](https://github.com/wiley/Madgex-BigWorkBag/blob/1216a7117c49bb93a2a2c8410bd670062443aaad/ResourceRoot/Sites/BigWorkBag.CustomResources/Config/HeaderFooterPodletConfig.xml)
181
+
182
+ And set `JSEnabled` (Jobseeker Site) and/or `RSEnabled` (Recruiter Site) to `true` or `false`. By default these are `false`.
183
+
184
+ ```xml
185
+ <?xml version="1.0" encoding="utf-8"?>
186
+ <ArrayOfConfigSetting xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
187
+
188
+ <ConfigSetting>
189
+ <Key>JSEnabled</Key>
190
+ <Value>true</Value>
191
+ </ConfigSetting>
192
+
193
+ <ConfigSetting>
194
+ <Key>RSEnabled</Key>
195
+ <Value>true</Value>
196
+ </ConfigSetting>
197
+
198
+ </ArrayOfConfigSetting>
199
+ ```
200
+
201
+ > [!IMPORTANT]
202
+ > Do not set `PodletApiUrl` (Not shown in example above), this causes conflicts with other environment configs (UAT).
203
+
204
+ It is overall simpler to just create this base `HeaderFooterPodlet.xml` file so all environments are consistent, but you can also create environment-only configs if for example only want to enable it for Production `HeaderFooterPodlet.JobBoard-Production.xml`
205
+
206
+ ## V5 vs V6
207
+
208
+ - V6 depends on the Branding Repo, a site can't exist without it
209
+ - V5 does not load `madgex-design-system CSS`, V6 and FERT do
210
+ - Custom templates that do not use ShadowDOM can be affected by existing CSS on the page
211
+ - V5 will fail to deploy if it cant access the header-footer-podlet
212
+ - V6 only uses `production` **master** branch assets, there is no `dev`
213
+ - V5 uses `production` **master** branch assets for `Staging` and `Production` environments
214
+ - V5 uses `dev` **non-master** branch assets for `Local`, `QA` and `UAT`.
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@madgex/fert",
3
- "version": "7.0.12",
3
+ "version": "7.0.13",
4
4
  "description": "Tool to help build the V6 branding",
5
5
  "bin": {
6
6
  "fert": "./bin/cli.js"
@@ -24,50 +24,49 @@
24
24
  "author": "Madgex",
25
25
  "license": "UNLICENSED",
26
26
  "dependencies": {
27
- "@aws-sdk/client-cloudfront": "3.937.0",
28
- "@aws-sdk/client-ssm": "3.936.0",
27
+ "@aws-sdk/client-cloudfront": "3.982.0",
28
+ "@aws-sdk/client-ssm": "3.982.0",
29
29
  "@hapi/hapi": "21.4.4",
30
30
  "@hapi/hoek": "11.0.7",
31
31
  "@hapi/inert": "7.1.0",
32
32
  "@hapi/vision": "7.0.3",
33
33
  "@hapipal/toys": "4.0.0",
34
34
  "@madgex/config-api-sdk": "1.13.1",
35
- "@madgex/design-system": "13.0.4",
35
+ "@madgex/design-system": "13.2.1",
36
36
  "@private/header-footer-podlet-server": "github:wiley/madgex-header-footer-podlet",
37
37
  "axios": "1.13.2",
38
38
  "cac": "6.7.14",
39
39
  "chalk": "5.6.2",
40
- "chokidar4": "npm:chokidar@4.0.3",
40
+ "chokidar5": "npm:chokidar@5.0.0",
41
41
  "debug": "4.4.3",
42
- "dedent": "1.7.0",
42
+ "dedent": "1.7.1",
43
43
  "find-up-simple": "1.0.1",
44
- "flat-cache": "6.1.18",
45
- "form-data": "4.0.4",
46
- "joi": "17.13.3",
47
- "lodash": "4.17.21",
44
+ "flat-cache": "6.1.20",
45
+ "form-data": "4.0.5",
46
+ "joi": "18.0.2",
48
47
  "nunjucks": "3.2.4",
49
- "open": "8.4.2",
48
+ "open": "11.0.0",
50
49
  "ora": "5.4.1",
51
50
  "prompts": "2.4.2",
52
- "rimraf": "6.0.1",
53
- "sass": "1.93.3",
51
+ "rimraf": "6.1.2",
52
+ "sass": "1.97.3",
54
53
  "simple-git": "3.30.0",
55
54
  "simple-update-notifier": "2.0.0",
56
55
  "uuid-validate": "0.0.3",
57
- "vite": "7.1.12",
58
- "vite-plugin-static-copy": "3.1.4"
56
+ "vite": "7.3.1",
57
+ "vite-plugin-static-copy": "3.2.0"
59
58
  },
60
59
  "devDependencies": {
61
- "@commitlint/cli": "20.1.0",
62
- "@commitlint/config-conventional": "20.0.0",
60
+ "@commitlint/cli": "20.4.1",
61
+ "@commitlint/config-conventional": "20.4.1",
63
62
  "@madgex/eslint-config-madgex": "2.3.0",
64
63
  "@madgex/prettier-config-madgex": "2.0.0",
65
- "eslint": "9.39.1",
64
+ "eslint": "9.39.2",
66
65
  "husky": "9.1.7",
67
- "lint-staged": "16.2.6",
68
- "msw": "^2.12.3",
69
- "prettier": "3.6.2",
70
- "semantic-release": "24.2.9"
66
+ "lint-staged": "16.2.7",
67
+ "msw": "^2.12.8",
68
+ "prettier": "3.8.1",
69
+ "semantic-release": "25.0.3"
71
70
  },
72
71
  "lint-staged": {
73
72
  "*.{js,json}": [
@@ -2,7 +2,7 @@
2
2
  import { glob } from 'node:fs/promises';
3
3
  import path from 'node:path';
4
4
  import { createServer } from 'vite';
5
- import chokidar from 'chokidar4';
5
+ import chokidar from 'chokidar5';
6
6
  import * as Hoek from '@hapi/hoek';
7
7
 
8
8
  const internals = {};
@@ -1,4 +1,5 @@
1
1
  {% extends "furniture.njk" %}
2
+ {% from 'icons/_macro.njk' import MdsIcon %}
2
3
 
3
4
  {% block main %}
4
5
  <ul class="mds-list mds-list--inline mds-list--pipe">
@@ -14,13 +15,20 @@
14
15
  <div class="mds-grid-col-12 mds-grid-col-lg-9 ">
15
16
  <div class="mds-surface">
16
17
  <div class="mds-surface__inner">
17
- <h1>Page title</h1>
18
+ <h1>Frontend Rollout Tool</h1>
19
+
20
+ <h2>Documentation</h2>
21
+ <ul>
22
+ <li><a href="https://github.com/wiley/madgex-frontend-rollout-tool/blob/master/docs/README.md">Readme</a></li>
23
+ </ul>
24
+
18
25
  <h2>Text</h2>
19
26
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas tempus tortor nulla, id viverra lacus maximus vel.
20
27
  In tincidunt ultrices neque in maximus. Donec leo lectus, aliquet vel molestie lacinia, elementum vel arcu. Integer
21
28
  iaculis diam non mattis eleifend. Curabitur et tempus felis. Vestibulum tempor nec libero id blandit. Duis fermentum
22
29
  pulvinar eleifend. Vestibulum pellentesque mauris sed augue finibus, sit amet laoreet felis fermentum. Donec in dolor id
23
30
  elit cursus pellentesque.</p>
31
+
24
32
  <p><a href="#">Link</a><p>
25
33
  <p><button class="mds-button">Button</button></p>
26
34
  </div>
@@ -28,10 +36,12 @@
28
36
  </div>
29
37
  <div class="mds-grid-col-12 mds-grid-col-lg-3">
30
38
  <div class="mds-branded-container mds-branded-container--1 mds-padding-b4 mds-padding-bottom-b5 mds-margin-bottom-b5">
39
+ {{ MdsIcon({ path:"/design-system/assets/icons.svg", iconName: 'email',classes: 'mds-icon--md mds-margin-bottom-b2' }) }}
31
40
  <h2 class="mds-font-s2">Branded Container</h2>
32
41
  <p class="mds-margin-bottom-b4">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
33
42
  <a href="#" draggable="false" class="mds-button mds-button--small">Lorem ipsum</a>
34
43
  </div>
35
44
  </div>
36
45
  </div>
46
+
37
47
  {% endblock %}