-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Expand file tree
/
Copy pathpublish-to-s3.mjs
More file actions
executable file
·122 lines (101 loc) · 3.22 KB
/
Copy pathpublish-to-s3.mjs
File metadata and controls
executable file
·122 lines (101 loc) · 3.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import { join } from 'node:path';
import { existsSync, realpathSync, readFileSync } from 'node:fs';
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
import { buildInfo as buildBuildInfo } from '../broccoli/build-info.cjs';
import projectFileMap from '../config/s3ProjectConfig.cjs';
const buildInfo = buildBuildInfo();
// To invoke this from the commandline you need the following to env vars to exist:
//
// S3_BUCKET_NAME
// S3_SECRET_ACCESS_KEY
// S3_ACCESS_KEY_ID
//
// Once you have those, you execute with the following:
//
// ```sh
// ./bin/publish-to-s3.mjs
// ```
class S3Publisher {
projectFileMap;
commit;
channel;
bucketName;
date = new Date().toISOString().replace(/-/g, '').replace(/T.+/, '');
constructor(options) {
if (!options.projectFileMap) {
throw new Error('You must pass in a function with a project file map to use!');
}
new Date().toISOString().replace(/-/g, '').replace(/T.+/, '');
const s3Config = {
bucketName: process.env.S3_BUCKET_NAME,
accessKeyId: process.env.S3_ACCESS_KEY_ID,
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY,
};
if (!s3Config.bucketName || !s3Config.accessKeyId || !s3Config.secretAccessKey) {
throw new Error('Missing AWS credentials.');
}
this.projectFileMap = options.projectFileMap;
this.commit = options.commit;
this.channel = options.channel;
this.bucketName = s3Config.bucketName;
this.s3 = new S3Client({
region: 'us-east-1',
credentials: {
accessKeyId: s3Config.accessKeyId,
secretAccessKey: s3Config.secretAccessKey,
},
});
}
async publish() {
try {
const files = this.projectFileMap(this.commit, this.date);
for (const file in files) {
const localDests = files[file].destinations[this.channel || 'wildcard'];
if (!localDests) {
throw new Error(
`${this.channel} is not a supported branch and no wildcard entry has been specified`
);
}
if (!localDests.length) {
throw new Error('There are no locations for this branch');
}
for (const destination in localDests) {
await this.uploader(localDests[destination], file, files);
}
}
} catch (err) {
exitGracefully(err);
}
}
async uploader(destination, file, files) {
let filePath = join(process.cwd(), 'dist', file);
if (!existsSync(filePath)) {
throw new Error("FilePath: '" + filePath + "' doesn't exist!");
}
filePath = realpathSync(filePath);
const data = readFileSync(filePath);
await this.uploadFile(data, files[file].contentType, destination);
}
async uploadFile(data, type, destination) {
const command = new PutObjectCommand({
Bucket: this.bucketName,
Key: destination,
Body: data,
ContentType: type,
ACL: 'public-read',
});
await this.s3.send(command);
}
}
if (!buildInfo.isBuildForTag) {
const publisher = new S3Publisher({
projectFileMap,
commit: buildInfo.sha,
channel: buildInfo.channel,
});
await publisher.publish();
}
function exitGracefully(err) {
console.log(err); // eslint-disable-line no-console
process.exit(1); // eslint-disable-line n/no-process-exit
}