aboutsummaryrefslogtreecommitdiffstats
path: root/deploy-ui-gcs/index.js
diff options
context:
space:
mode:
authorJan Tuomi <jans.tuomi@gmail.com>2022-02-06 17:08:22 +0200
committerJan Tuomi <jans.tuomi@gmail.com>2022-02-11 15:24:52 +0200
commit664e622fbb5d528e14d42da7baf9505b79f3d041 (patch)
tree7cb89d71aa9650a4c009be5c4be1f043a8797743 /deploy-ui-gcs/index.js
Initial commit
Diffstat (limited to 'deploy-ui-gcs/index.js')
-rw-r--r--deploy-ui-gcs/index.js101
1 files changed, 101 insertions, 0 deletions
diff --git a/deploy-ui-gcs/index.js b/deploy-ui-gcs/index.js
new file mode 100644
index 0000000..1701f6e
--- /dev/null
+++ b/deploy-ui-gcs/index.js
@@ -0,0 +1,101 @@
+const { Storage } = require("@google-cloud/storage")
+const PubSub = require("@google-cloud/pubsub")
+const JSZip = require("jszip")
+
+const storage = new Storage()
+// const projectId = process.env.GCP_PROJECT || process.env.GCLOUD_PROJECT
+const artifactBucketName = "gs://slam-lang-gh-artifacts"
+const uiDeployBucketName = "gs://slam-lang-ui"
+
+const pubsub = new PubSub();
+const resultTopicName = "deploy-ui-gcs-result"
+/**
+ * Triggered from a message on a Cloud Pub/Sub topic.
+ *
+ * @param {!Object} event Event payload.
+ * @param {!Object} context Metadata for the event.
+ */
+exports.deployPubSub = async (event, context) => {
+ console.log("Received event:", event)
+
+ const json = JSON.parse(Buffer.from(event.data, "base64").toString("utf8"))
+ const revision = json.revision
+ console.log("Parsed revision from event:", revision)
+ const resultPublisher = pubsub.topic(resultTopicName).publisher()
+
+ try {
+ const archiveName = `ui-${revision}.zip`
+
+ const artifactBucket = storage.bucket(artifactBucketName)
+ const archiveFile = artifactBucket.file(archiveName)
+
+ console.log("Downloading zip archive", archiveName)
+ const zipData = await archiveFile.download()
+ if (zipData.length !== 1) {
+ throw new Error("zipData.length !== 1")
+ }
+
+ const zipContent = await JSZip.loadAsync(zipData[0])
+ const zippedPaths = Object.keys(zipContent.files)
+
+ console.log("Zipped content to deploy:", zippedPaths)
+
+ const uiDeployBucket = storage.bucket(uiDeployBucketName)
+
+ const prevFiles = await uiDeployBucket.getFiles()
+ if (prevFiles.length !== 1) {
+ throw new Error("prevFiles.length !== 1")
+ }
+ const prevFilePaths = prevFiles[0].map(f => f.name)
+ console.log("Existing files:", prevFilePaths)
+
+ const newFilePaths = []
+ zippedPaths.forEach(filePath => {
+ const zipFile = zipContent.files[filePath]
+ if (zipFile.dir) return
+
+ const deployFilePath = filePath.replace(/^dist\//, "")
+ newFilePaths.push(deployFilePath)
+
+ const newBucketFile = uiDeployBucket.file(deployFilePath)
+
+ const nodeStream = zipFile.nodeStream()
+ nodeStream.pipe(
+ newBucketFile.createWriteStream({
+ resumable: false,
+ validation: false,
+ contentType: "auto",
+ metadata: {
+ "Cache-Control": "no-store",
+ },
+ })
+ )
+ })
+ console.log("Deployed new files:", newFilePaths)
+
+ const filePathsToDelete = prevFilePaths
+ .filter(prevFilePath => !newFilePaths.includes(prevFilePath))
+
+ console.log("Obsolete files to delete:", filePathsToDelete)
+
+ await Promise.all(
+ filePathsToDelete.map(filePath =>
+ uiDeployBucket.file(filePath).delete()
+ )
+ )
+
+ console.log("Done!");
+
+ await resultPublisher.publish(Buffer.from(JSON.stringify({
+ revision,
+ ok: true
+ })))
+ } catch (err) {
+ console.error(err)
+ await resultPublisher.publish(Buffer.from(JSON.stringify({
+ revision,
+ ok: false
+ })))
+ throw err
+ }
+};