Uploading the static assets to R2 bucket (#3921)
Uploads all the folders inside `./assets` folder to a new R2 bucket called `cdn`. Uses the package version as the prefix, so that we can host multiple versions of the assets. ### Change Type <!-- ❗ Please select a 'Scope' label ❗️ --> - [ ] `sdk` — Changes the tldraw SDK - [ ] `dotcom` — Changes the tldraw.com web app - [ ] `docs` — Changes to the documentation, examples, or templates. - [ ] `vs code` — Changes to the vscode plugin - [x] `internal` — Does not affect user-facing stuff <!-- ❗ Please select a 'Type' label ❗️ --> - [ ] `bugfix` — Bug fix - [ ] `feature` — New feature - [ ] `improvement` — Improving existing features - [ ] `chore` — Updating dependencies, other boring stuff - [ ] `galaxy brain` — Architectural changes - [ ] `tests` — Changes to any test code - [x] `tools` — Changes to infrastructure, CI, internal scripts, debugging tools, etc. - [ ] `dunno` — I don't know ### Test Plan 1. Add a step-by-step description of how to test your PR here. 2. - [ ] Unit Tests - [ ] End to end tests ### Release Notes - Upload our static assets (fonts, icons, embed-icons, translations) to a R2 bucket so that we can move away from using unpkg and start using our own cdn.
This commit is contained in:
parent
735161c4a8
commit
beb0bca5fe
5 changed files with 76 additions and 3 deletions
|
@ -1,5 +1,6 @@
|
||||||
import { exec } from './lib/exec'
|
import { exec } from './lib/exec'
|
||||||
import { getLatestVersion, publish, setAllVersions } from './lib/publishing'
|
import { getLatestVersion, publish, setAllVersions } from './lib/publishing'
|
||||||
|
import { uploadStaticAssets } from './upload-static-assets'
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const sha = (await exec('git', ['rev-parse', 'HEAD'])).trim().slice(0, 12)
|
const sha = (await exec('git', ['rev-parse', 'HEAD'])).trim().slice(0, 12)
|
||||||
|
@ -14,12 +15,14 @@ async function main() {
|
||||||
const versionString = `${nextVersion.major}.${nextVersion.minor}.${nextVersion.patch}-canary.${sha}`
|
const versionString = `${nextVersion.major}.${nextVersion.minor}.${nextVersion.patch}-canary.${sha}`
|
||||||
|
|
||||||
await setAllVersions(versionString)
|
await setAllVersions(versionString)
|
||||||
|
return versionString
|
||||||
}
|
}
|
||||||
|
|
||||||
// module was called directly
|
// module was called directly
|
||||||
|
|
||||||
setCanaryVersions()
|
const versionString = await setCanaryVersions()
|
||||||
publish('canary')
|
await uploadStaticAssets(versionString)
|
||||||
|
await publish('canary')
|
||||||
}
|
}
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { appendFileSync } from 'fs'
|
import { appendFileSync } from 'fs'
|
||||||
import { exec } from './lib/exec'
|
import { exec } from './lib/exec'
|
||||||
import { getLatestVersion, publish } from './lib/publishing'
|
import { getLatestVersion, publish } from './lib/publishing'
|
||||||
|
import { uploadStaticAssets } from './upload-static-assets'
|
||||||
|
|
||||||
// This expects the package.json files to be in the correct state.
|
// This expects the package.json files to be in the correct state.
|
||||||
// You might want to run this locally after a failed publish attempt on CI.
|
// You might want to run this locally after a failed publish attempt on CI.
|
||||||
|
@ -16,7 +17,9 @@ async function main() {
|
||||||
appendFileSync(process.env.GITHUB_OUTPUT, `is_latest_version=${isLatestVersion}\n`)
|
appendFileSync(process.env.GITHUB_OUTPUT, `is_latest_version=${isLatestVersion}\n`)
|
||||||
}
|
}
|
||||||
|
|
||||||
publish()
|
await uploadStaticAssets(latestVersionInBranch.version)
|
||||||
|
|
||||||
|
await publish()
|
||||||
}
|
}
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { generateAutoRcFile } from './lib/labels'
|
||||||
import { nicelog } from './lib/nicelog'
|
import { nicelog } from './lib/nicelog'
|
||||||
import { getLatestVersion, publish, setAllVersions } from './lib/publishing'
|
import { getLatestVersion, publish, setAllVersions } from './lib/publishing'
|
||||||
import { getAllWorkspacePackages } from './lib/workspace'
|
import { getAllWorkspacePackages } from './lib/workspace'
|
||||||
|
import { uploadStaticAssets } from './upload-static-assets'
|
||||||
|
|
||||||
type ReleaseType =
|
type ReleaseType =
|
||||||
| {
|
| {
|
||||||
|
@ -131,6 +132,9 @@ async function main() {
|
||||||
// create a release on github
|
// create a release on github
|
||||||
await auto.runRelease({ useVersion: nextVersion })
|
await auto.runRelease({ useVersion: nextVersion })
|
||||||
|
|
||||||
|
// upload static assets
|
||||||
|
await uploadStaticAssets(nextVersion)
|
||||||
|
|
||||||
// finally, publish the packages [IF THIS STEP FAILS, RUN THE `publish-manual.ts` script locally]
|
// finally, publish the packages [IF THIS STEP FAILS, RUN THE `publish-manual.ts` script locally]
|
||||||
await publish()
|
await publish()
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { generateAutoRcFile } from './lib/labels'
|
||||||
import { nicelog } from './lib/nicelog'
|
import { nicelog } from './lib/nicelog'
|
||||||
import { getLatestVersion, publish, setAllVersions } from './lib/publishing'
|
import { getLatestVersion, publish, setAllVersions } from './lib/publishing'
|
||||||
import { getAllWorkspacePackages } from './lib/workspace'
|
import { getAllWorkspacePackages } from './lib/workspace'
|
||||||
|
import { uploadStaticAssets } from './upload-static-assets'
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const huppyToken = process.env.HUPPY_TOKEN
|
const huppyToken = process.env.HUPPY_TOKEN
|
||||||
|
@ -103,6 +104,8 @@ async function main() {
|
||||||
// create a release on github
|
// create a release on github
|
||||||
await auto.runRelease({ useVersion: nextVersion })
|
await auto.runRelease({ useVersion: nextVersion })
|
||||||
|
|
||||||
|
await uploadStaticAssets(nextVersion)
|
||||||
|
|
||||||
// if we're on the latest version, publish to npm under 'latest' tag.
|
// if we're on the latest version, publish to npm under 'latest' tag.
|
||||||
// otherwise we don't want to overwrite the latest tag, so we publish under 'revision'.
|
// otherwise we don't want to overwrite the latest tag, so we publish under 'revision'.
|
||||||
// semver rules will still be respected because there's no prerelease tag in the version,
|
// semver rules will still be respected because there's no prerelease tag in the version,
|
||||||
|
|
60
scripts/upload-static-assets.ts
Normal file
60
scripts/upload-static-assets.ts
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
import { PutObjectCommand, S3Client } from '@aws-sdk/client-s3'
|
||||||
|
import fs from 'fs'
|
||||||
|
import path from 'path'
|
||||||
|
import { makeEnv } from './lib/makeEnv'
|
||||||
|
|
||||||
|
const env = makeEnv(['R2_ACCESS_KEY_ID', 'R2_ACCESS_KEY_SECRET'])
|
||||||
|
|
||||||
|
const R2_URL = 'https://c34edc4e76350954b63adebde86d5eb1.r2.cloudflarestorage.com'
|
||||||
|
const R2_BUCKET = 'cdn'
|
||||||
|
const ASSETS_FOLDER = './assets'
|
||||||
|
|
||||||
|
const R2 = new S3Client({
|
||||||
|
region: 'auto',
|
||||||
|
endpoint: R2_URL,
|
||||||
|
credentials: {
|
||||||
|
accessKeyId: env.R2_ACCESS_KEY_ID,
|
||||||
|
secretAccessKey: env.R2_ACCESS_KEY_SECRET,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
async function uploadFile(key: string, fullPath: string) {
|
||||||
|
const fileStream = fs.createReadStream(fullPath)
|
||||||
|
const uploadParams = {
|
||||||
|
Bucket: R2_BUCKET,
|
||||||
|
Key: key,
|
||||||
|
Body: fileStream,
|
||||||
|
}
|
||||||
|
await R2.send(new PutObjectCommand(uploadParams))
|
||||||
|
}
|
||||||
|
|
||||||
|
async function uploadDirectory(prefix: string, directoryPath: string) {
|
||||||
|
const entries = fs.readdirSync(directoryPath, { withFileTypes: true })
|
||||||
|
|
||||||
|
for (const entry of entries) {
|
||||||
|
const fullPath = path.join(directoryPath, entry.name)
|
||||||
|
const key = path.join(prefix, entry.name)
|
||||||
|
|
||||||
|
if (entry.isDirectory()) {
|
||||||
|
await uploadDirectory(key, fullPath)
|
||||||
|
} else if (entry.isFile()) {
|
||||||
|
await uploadFile(key, fullPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function uploadStaticAssets(version: string) {
|
||||||
|
try {
|
||||||
|
const entries = fs.readdirSync(ASSETS_FOLDER, { withFileTypes: true })
|
||||||
|
// Loop through all the folders in the assets folder and upload them.
|
||||||
|
for (const entry of entries) {
|
||||||
|
if (entry.isDirectory()) {
|
||||||
|
const folderName = entry.name
|
||||||
|
await uploadDirectory(`${version}/${folderName}`, `${ASSETS_FOLDER}/${folderName}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue