Skip to content

Commit 47c29d2

Browse files
author
Ben Siggery
committed
feat(pie-monorepo): DSW-2679 add mechanism to upload multiple components to cdn
1 parent 6dce5e9 commit 47c29d2

File tree

5 files changed

+154
-39
lines changed

5 files changed

+154
-39
lines changed

.github/workflows/changeset-release.yml

+14-38
Original file line numberDiff line numberDiff line change
@@ -201,41 +201,17 @@ jobs:
201201
}
202202
env:
203203
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
204-
205-
publish-cookie-banner-cdn:
206-
needs: changesets
207-
runs-on: ${{ inputs.os }}
208-
if: needs.changesets.outputs.published == 'true' && contains(fromJson(needs.changesets.outputs.publishedPackages).*.name, '@justeattakeaway/pie-cookie-banner')
209-
steps:
210-
# Checkout the Repo
211-
- name: Checkout
212-
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
213-
214-
# Setup Repo
215-
- name: Setup Repo
216-
uses: ./.github/actions/setup-repo
217-
with:
218-
node-version: ${{ inputs.node-version }}
219-
os: ${{ inputs.os }}
220-
221-
# Build
222-
- name: Build Cookie Banner
223-
uses: ./.github/actions/run-script
224-
with:
225-
script-name: "build --filter=pie-cookie-banner"
226-
227-
- name: Extract cookie banner version
228-
id: extract-version
229-
run: |
230-
PACKAGES='${{ needs.changesets.outputs.publishedPackages }}'
231-
cookie_banner_version=$(echo $PACKAGES | jq -r '.[] | select(.name == "@justeattakeaway/pie-cookie-banner") | .version')
232-
echo "COOKIE_BANNER_VERSION=$cookie_banner_version" >> $GITHUB_ENV
233-
234-
- name: Upload to S3
235-
run: |
236-
aws s3 sync $GITHUB_WORKSPACE/packages/components/pie-cookie-banner/cdn_dist/ s3://$PIE_CDN_BUCKET_NAME/pie-cookie-banner/$COOKIE_BANNER_VERSION/ --region $AWS_REGION --content-type "text/javascript"
237-
env:
238-
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_KEY_ID }}
239-
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
240-
AWS_REGION: eu-west-1
241-
PIE_CDN_BUCKET_NAME: ${{ vars.PIE_CDN_BUCKET_NAME }}
204+
205+
- name: Publish packages to CDN
206+
if: steps.changesets-main.outputs.published == 'true'
207+
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
208+
env:
209+
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_KEY_ID }}
210+
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
211+
AWS_REGION: eu-west-1
212+
PIE_CDN_BUCKET_NAME: ${{ vars.PIE_CDN_BUCKET_NAME }}
213+
with:
214+
script: |
215+
const publishedPackages = JSON.parse('${{ steps.changesets-main.outputs.publishedPackages }}');
216+
const publishToCdn = require('${{ github.workspace }}/packages/tools/pie-monorepo-utils/pie-cdn/publish-to-cdn.js');
217+
await publishToCdn({ publishedPackages });

packages/components/pie-cookie-banner/package.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@
2121
"**/*.d.ts"
2222
],
2323
"pieMetadata": {
24-
"componentStatus": "stable"
24+
"componentStatus": "stable",
25+
"cdnPublish": true,
26+
"cdnSourceFolder": "cdn_dist",
27+
"cdnContentType": "text/javascript"
2528
},
2629
"scripts": {
2730
"build": "run -T vite build && yarn build:cdn",

packages/tools/pie-css/package.json

+5
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
"scss"
1313
],
1414
"main": "dist/index.css",
15+
"pieMetadata": {
16+
"cdnPublish": true,
17+
"cdnSourceFolder": "dist",
18+
"cdnContentType": "text/css"
19+
},
1520
"scripts": {
1621
"build": "run -T ts-node ./buildCss.ts",
1722
"lint:scripts": "run -T eslint .",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/* eslint-disable camelcase */
2+
const fs = require('fs');
3+
const path = require('path');
4+
const { execSync } = require('child_process');
5+
const findMonorepoRoot = require('../utils/find-monorepo-root.js');
6+
7+
/**
8+
* Identifies packages that need to be published to the CDN
9+
* @param {Array} publishedPackages - Array of published packages from changesets
10+
* @returns {Array} - Array of packages that need CDN publishing
11+
*/
12+
async function identifyCdnPackages(publishedPackages) {
13+
// Get workspace info to locate package directories
14+
const monorepoRoot = findMonorepoRoot();
15+
const workspaceOutput = execSync('yarn workspaces list --json', { cwd: monorepoRoot }).toString();
16+
const workspaces = workspaceOutput.trim().split('\n').map(line => JSON.parse(line));
17+
18+
// Find packages that need CDN publishing
19+
const cdnPackages = [];
20+
21+
for (const pkg of publishedPackages) {
22+
// Find workspace location for this package
23+
const workspace = workspaces.find(ws => ws.name === pkg.name);
24+
if (!workspace) continue;
25+
26+
// Read package.json to check for CDN configuration
27+
try {
28+
const packageJsonPath = path.join(monorepoRoot, workspace.location, 'package.json');
29+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
30+
31+
// Validate required CDN configuration
32+
if (packageJson.pieMetadata && packageJson.pieMetadata.cdnPublish === true) {
33+
// Validate all required CDN properties are present
34+
if (!packageJson.pieMetadata.cdnSourceFolder) {
35+
console.error(`Missing required cdnSourceFolder for ${pkg.name}. Skipping CDN publishing.`);
36+
continue;
37+
}
38+
39+
if (!packageJson.pieMetadata.cdnContentType) {
40+
console.error(`Missing required cdnContentType for ${pkg.name}. Skipping CDN publishing.`);
41+
continue;
42+
}
43+
44+
cdnPackages.push({
45+
name: pkg.name,
46+
version: pkg.version,
47+
location: path.join(monorepoRoot, workspace.location),
48+
cdnSourceFolder: packageJson.pieMetadata.cdnSourceFolder,
49+
cdnContentType: packageJson.pieMetadata.cdnContentType
50+
});
51+
}
52+
} catch (error) {
53+
console.error(`Error processing ${pkg.name}:`, error);
54+
}
55+
}
56+
57+
return cdnPackages;
58+
}
59+
60+
/**
61+
* Publishes packages to the CDN
62+
* @param {Array} cdnPackages - Array of packages to publish to the CDN
63+
*/
64+
async function publishToCdn(cdnPackages) {
65+
console.log('Publishing packages to CDN:', cdnPackages);
66+
67+
for (const pkg of cdnPackages) {
68+
try {
69+
// Get package name
70+
const packageName = pkg.name.replace('@justeattakeaway/', '');
71+
72+
// Build the path to the source folder
73+
const sourcePath = path.join(pkg.location, pkg.cdnSourceFolder);
74+
75+
// Check if the source folder exists
76+
if (!fs.existsSync(sourcePath)) {
77+
console.log(`Source directory '${pkg.cdnSourceFolder}' not found for ${pkg.name}, skipping upload`);
78+
continue;
79+
}
80+
81+
console.log(`Uploading ${pkg.name} to S3 from ${sourcePath}...`);
82+
execSync(
83+
`aws s3 sync ${sourcePath}/ s3://$PIE_CDN_BUCKET_NAME/${packageName}/v${pkg.version}/ --region $AWS_REGION --content-type "${pkg.cdnContentType}"`,
84+
{ stdio: 'inherit' }
85+
);
86+
87+
console.log(`Successfully published ${pkg.name}@${pkg.version} to CDN`);
88+
} catch (error) {
89+
console.error(`Error processing ${pkg.name}:`, error);
90+
throw error;
91+
}
92+
}
93+
}
94+
95+
/**
96+
* @param {Object} options - Options object
97+
* @param {Array} options.publishedPackages - Array of published packages from changesets
98+
*/
99+
module.exports = async ({ publishedPackages }) => {
100+
try {
101+
// Identify packages for CDN publishing
102+
const cdnPackages = await identifyCdnPackages(publishedPackages);
103+
104+
if (cdnPackages.length === 0) {
105+
console.log('No packages need CDN publishing');
106+
return;
107+
}
108+
109+
await publishToCdn(cdnPackages);
110+
111+
} catch (error) {
112+
console.error('Error publishing to CDN:', error);
113+
throw error;
114+
}
115+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
const fs = require('fs');
2+
const path = require('path');
3+
4+
function findMonorepoRoot (startPath = process.cwd(), expectedFile = 'yarn.lock') {
5+
let testedPath = startPath;
6+
let fileExists = false;
7+
8+
do {
9+
fileExists = fs.existsSync(path.join(testedPath, expectedFile));
10+
if (!fileExists) testedPath = path.join(testedPath, '../');
11+
} while (fileExists === false);
12+
13+
return testedPath;
14+
}
15+
16+
module.exports = findMonorepoRoot;

0 commit comments

Comments
 (0)