diff --git a/.gitea/workflows/build-and-copy.yml b/.gitea/workflows/build-and-copy.yml new file mode 100644 index 0000000..78bfa6e --- /dev/null +++ b/.gitea/workflows/build-and-copy.yml @@ -0,0 +1,59 @@ +name: Build and copy to prod +on: + push: + schedule: + - cron: '0 * * * *' +jobs: + build-and-copy: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Node + uses: actions/setup-node@v3 + with: + node-version: 20.x + - name: Install dependencies 📦 + run: npm ci + - name: Cache build + id: cache-eleventy-build + uses: actions/cache@v4 + with: + path: .cache + key: cache-eleventy-build-${{ gitea.run_id }} + restore-keys: | + cache-eleventy-build + - name: Cache _site + id: cache-site + uses: actions/cache@v4 + with: + path: _site + key: cache-site-${{ gitea.run_id }} + restore-keys: | + cache-site + - name: Build eleventy + run: npm run build + env: + NODE_ENV: production + UMAMI_API_KEY: ${{ secrets.UMAMI_API_KEY }} + - name: Sync to Bunny + run: node ./scripts/upload-to-bunny.js + env: + BUNNY_STORAGE_ENDPOINT: ${{ secrets.BUNNY_STORAGE_ENDPOINT }} + BUNNY_STORAGE_PASSWORD: ${{ secrets.BUNNY_STORAGE_PASSWORD }} + BUNNY_STORAGE_BUCKET: ${{ secrets.BUNNY_STORAGE_BUCKET }} + - name: Purge XML files from cache + run: | + curl --request POST \ + --url 'https://api.bunny.net/purge?url=https%3A%2F%2Flewisdale.dev%2F%2A.xml&async=false' \ + --header 'AccessKey: ${{ secrets.BUNNY_ACCESS_KEY }}' + - name: Purge JSON files from cache + run: | + curl --request POST \ + --url 'https://api.bunny.net/purge?url=https%3A%2F%2Flewisdale.dev%2F%2A.json&async=false' \ + --header 'AccessKey: ${{ secrets.BUNNY_ACCESS_KEY }}' + - name: Purge CSS files from cache + run: | + curl --request POST \ + --url 'https://api.bunny.net/purge?url=https%3A%2F%2Flewisdale.dev%2F%2A.css&async=false' \ + --header 'AccessKey: ${{ secrets.BUNNY_ACCESS_KEY }}' \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 0c86004..f3f2978 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,6 +30,7 @@ "markdown-it-obsidian-callouts": "^0.2.6", "markdown-it-prism": "^2.3.0", "npm-run-all": "^4.1.5", + "p-map": "^7.0.2", "postcss": "^8.4.21", "postcss-cli": "^10.1.0", "postcss-import": "^15.1.0", @@ -4260,6 +4261,17 @@ "node": ">=4" } }, + "node_modules/p-map": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.2.tgz", + "integrity": "sha512-z4cYYMMdKHzw4O5UkWJImbZynVIo0lSGTXc7bzB1e/rrDqkgGUNysK/o4bTr+0+xKvvLoTyGqYC4Fgljy9qe1Q==", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-queue": { "version": "6.6.2", "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", @@ -8986,6 +8998,11 @@ "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==" }, + "p-map": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.2.tgz", + "integrity": "sha512-z4cYYMMdKHzw4O5UkWJImbZynVIo0lSGTXc7bzB1e/rrDqkgGUNysK/o4bTr+0+xKvvLoTyGqYC4Fgljy9qe1Q==" + }, "p-queue": { "version": "6.6.2", "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", diff --git a/package.json b/package.json index 0f9af9d..12458cd 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "markdown-it-obsidian-callouts": "^0.2.6", "markdown-it-prism": "^2.3.0", "npm-run-all": "^4.1.5", + "p-map": "^7.0.2", "postcss": "^8.4.21", "postcss-cli": "^10.1.0", "postcss-import": "^15.1.0", diff --git a/scripts/upload-to-bunny.js b/scripts/upload-to-bunny.js new file mode 100644 index 0000000..118ca1f --- /dev/null +++ b/scripts/upload-to-bunny.js @@ -0,0 +1,33 @@ +import pMap from 'p-map'; +import { readdir, lstat } from 'node:fs/promises'; +import { createReadStream } from 'node:fs'; +import * as path from 'node:path'; + +const config = { + endpoint: process.env.BUNNY_STORAGE_ENDPOINT, + password: process.env.BUNNY_STORAGE_PASSWORD, + bucket: process.env.BUNNY_STORAGE_BUCKET +}; + +const files = await readdir('./_site', { recursive: true }); + + +await pMap(files, async (file) => { + const filePath = path.join('./_site', file); + const stat = await lstat(filePath); + if (stat.isDirectory()) return; + + const url = `https://${config.endpoint}/${config.bucket}/${file}`; + console.log(`Uploading ${filePath} to ${url}`); + + const readStream = createReadStream(filePath); + + await fetch(url, { + method: 'PUT', + headers: { + accessKey: config.password, + }, + body: readStream, + duplex: 'half' + }); +}, { concurrency: 50 });