diff --git a/package.json b/package.json index 6136ef39d..c670e232e 100644 --- a/package.json +++ b/package.json @@ -48,10 +48,13 @@ "lodash": "4.17.21" }, "dependencies": { - "execa": "8.0.1", "cssnano": "6.0.3", + "execa": "8.0.1", + "fast-glob": "3.3.2", + "ignore-walk": "6.0.4", "js-yaml": "4.1.0", "postcss": "8.4.33", + "tar": "6.2.0", "terser": "5.27.0", "typescript": "5.3.3" }, @@ -61,8 +64,8 @@ "cross-env": "7.0.3", "cypress": "13.6.3", "eslint": "8.56.0", - "start-server-and-test": "2.0.3", - "ncp": "2.0.0" + "ncp": "2.0.0", + "start-server-and-test": "2.0.3" }, "optionalDependencies": { "@tensorflow/tfjs-core": "4.4.0" diff --git a/packages/backend/src/server/web/ClientServerService.ts b/packages/backend/src/server/web/ClientServerService.ts index 8e1a89d55..a5094e6a8 100644 --- a/packages/backend/src/server/web/ClientServerService.ts +++ b/packages/backend/src/server/web/ClientServerService.ts @@ -51,6 +51,7 @@ const clientAssets = `${_dirname}/../../../../frontend/assets/`; const assets = `${_dirname}/../../../../../built/_frontend_dist_/`; const swAssets = `${_dirname}/../../../../../built/_sw_dist_/`; const viteOut = `${_dirname}/../../../../../built/_vite_/`; +const tarball = `${_dirname}/../../../../../built/tarball/`; @Injectable() export class ClientServerService { @@ -291,6 +292,13 @@ export class ClientServerService { decorateReply: false, }); + fastify.register(fastifyStatic, { + root: tarball, + prefix: '/tarball/', + immutable: true, + decorateReply: false, + }); + fastify.get('/favicon.ico', async (request, reply) => { return reply.sendFile('/favicon.ico', staticAssets); }); diff --git a/packages/frontend/src/pages/about.vue b/packages/frontend/src/pages/about.vue index 69cb6ef64..8e5fcda28 100644 --- a/packages/frontend/src/pages/about.vue +++ b/packages/frontend/src/pages/about.vue @@ -86,6 +86,7 @@ SPDX-License-Identifier: AGPL-3.0-only nodeinfo robots.txt manifest.json + source code diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 640713067..643529826 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,12 +18,21 @@ importers: execa: specifier: 8.0.1 version: 8.0.1 + fast-glob: + specifier: 3.3.2 + version: 3.3.2 + ignore-walk: + specifier: 6.0.4 + version: 6.0.4 js-yaml: specifier: 4.1.0 version: 4.1.0 postcss: specifier: 8.4.33 version: 8.4.33 + tar: + specifier: 6.2.0 + version: 6.2.0 terser: specifier: 5.27.0 version: 5.27.0 @@ -13488,6 +13497,13 @@ packages: resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} dev: true + /ignore-walk@6.0.4: + resolution: {integrity: sha512-t7sv42WkwFkyKbivUCglsQW5YWMskWtbEf4MNKX5u/CCWHKSPzN4FtBQGsQZgCLbxOzpVlcbWVK5KB3auIOjSw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + dependencies: + minimatch: 9.0.3 + dev: false + /ignore@5.2.4: resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} engines: {node: '>= 4'} @@ -19095,6 +19111,18 @@ packages: mkdirp: 1.0.4 yallist: 4.0.0 + /tar@6.2.0: + resolution: {integrity: sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==} + engines: {node: '>=10'} + dependencies: + chownr: 2.0.0 + fs-minipass: 2.1.0 + minipass: 5.0.0 + minizlib: 2.1.2 + mkdirp: 1.0.4 + yallist: 4.0.0 + dev: false + /taskkill@5.0.0: resolution: {integrity: sha512-+HRtZ40Vc+6YfCDWCeAsixwxJgMbPY4HHuTgzPYH3JXvqHWUlsCfy+ylXlAKhFNcuLp4xVeWeFBUhDk+7KYUvQ==} engines: {node: '>=14.16'} diff --git a/scripts/build-assets.mjs b/scripts/build-assets.mjs index d2dabe853..8a8a50d9b 100644 --- a/scripts/build-assets.mjs +++ b/scripts/build-assets.mjs @@ -12,6 +12,7 @@ import * as terser from 'terser'; import { build as buildLocales } from '../locales/index.js'; import generateDTS from '../locales/generateDTS.js'; import meta from '../package.json' assert { type: "json" }; +import buildTarball from './tarball.mjs'; let locales = buildLocales(); @@ -77,12 +78,13 @@ async function build() { copyBackendViews(), buildBackendScript(), buildBackendStyle(), + buildTarball(), ]); } await build(); -if (process.argv.includes("--watch")) { +if (process.argv.includes('--watch')) { const watcher = fs.watch('./locales'); for await (const event of watcher) { const filename = event.filename?.replaceAll('\\', '/'); diff --git a/scripts/tarball.mjs b/scripts/tarball.mjs new file mode 100644 index 000000000..936a43d27 --- /dev/null +++ b/scripts/tarball.mjs @@ -0,0 +1,32 @@ +import { createWriteStream } from 'node:fs'; +import { mkdir } from 'node:fs/promises'; +import { resolve } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import glob from 'fast-glob'; +import walk from 'ignore-walk'; +import Pack from 'tar/lib/pack.js'; +import meta from '../package.json' assert { type: "json" }; + +const cwd = fileURLToPath(new URL('..', import.meta.url)); +const ignore = [ + '**/.git/**/*', + '**/*ignore', + '**/.gitmodules', + // Exclude files you don't want to include in the tarball here +]; + +export default async function build() { + const mkdirPromise = mkdir(resolve(cwd, 'built', 'tarball'), { recursive: true }); + const pack = new Pack({ cwd, gzip: true }); + const patterns = await walk({ path: cwd, ignoreFiles: ['.gitignore'] }); + + for await (const entry of glob.stream(patterns, { cwd, ignore, dot: true })) { + pack.add(entry); + } + + pack.end(); + + await mkdirPromise; + + pack.pipe(createWriteStream(resolve(cwd, 'built', 'tarball', `misskey-${meta.version}.tar.gz`))); +}