diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6941a93..c9bdef3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -52,19 +52,17 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Sync Protocol Constants + - name: Build Extensions run: | - chmod +x ./scripts/sync-constants.sh - ./scripts/sync-constants.sh - - - name: Create Extension Zip - run: | - zip -r koala-sync-extension.zip extension/ -x "*.DS_Store*" + npm install + npm run build:extension - name: Create GitHub Release uses: softprops/action-gh-release@v1 with: - files: koala-sync-extension.zip + files: | + dist/koalasync-chrome.zip + dist/koalasync-firefox.zip name: Release ${{ github.ref_name }} generate_release_notes: true draft: false diff --git a/extension/manifest.json b/extension/manifest.base.json similarity index 90% rename from extension/manifest.json rename to extension/manifest.base.json index 6976083..ca7cace 100644 --- a/extension/manifest.json +++ b/extension/manifest.base.json @@ -22,10 +22,6 @@ "128": "icons/icon128.png" } }, - "background": { - "service_worker": "background.js", - "type": "module" - }, "content_scripts": [ { "matches": ["https://koalasync.shik3i.net/*"], diff --git a/package.json b/package.json new file mode 100644 index 0000000..c1fa042 --- /dev/null +++ b/package.json @@ -0,0 +1,13 @@ +{ + "name": "koalasync", + "version": "1.2.1", + "description": "KoalaSync Build Scripts", + "private": true, + "scripts": { + "build:extension": "node scripts/build-extension.js" + }, + "devDependencies": { + "archiver": "^7.0.1", + "fs-extra": "^11.2.0" + } +} diff --git a/scripts/build-extension.js b/scripts/build-extension.js new file mode 100644 index 0000000..2d526e8 --- /dev/null +++ b/scripts/build-extension.js @@ -0,0 +1,122 @@ +const fs = require('fs'); +const path = require('path'); +const archiver = require('archiver'); + +const rootDir = path.join(__dirname, '..'); +const extDir = path.join(rootDir, 'extension'); +const distDir = path.join(rootDir, 'dist'); +const baseManifestPath = path.join(extDir, 'manifest.base.json'); + +// Ensure dist directory exists +if (fs.existsSync(distDir)) { + fs.rmSync(distDir, { recursive: true, force: true }); +} +fs.mkdirSync(distDir, { recursive: true }); + +// Sync shared constants from root /shared to /extension/shared +console.log('Syncing protocol constants...'); +const masterSharedDir = path.join(rootDir, 'shared'); +const extSharedDir = path.join(extDir, 'shared'); + +if (!fs.existsSync(extSharedDir)) { + fs.mkdirSync(extSharedDir, { recursive: true }); +} + +const sharedFiles = ['constants.js', 'blacklist.js']; +for (const file of sharedFiles) { + const src = path.join(masterSharedDir, file); + const dest = path.join(extSharedDir, file); + if (fs.existsSync(src)) { + fs.copyFileSync(src, dest); + } +} +console.log('✓ constants.js and blacklist.js synced to extension/shared/'); + +// Read the base manifest +const baseManifest = JSON.parse(fs.readFileSync(baseManifestPath, 'utf8')); + +// Helper to copy files, ignoring manifest.json and manifest.base.json +function copyExtensionFiles(targetDir) { + fs.mkdirSync(targetDir, { recursive: true }); + const items = fs.readdirSync(extDir); + for (const item of items) { + if (item === 'manifest.json' || item === 'manifest.base.json') continue; + const srcPath = path.join(extDir, item); + const destPath = path.join(targetDir, item); + if (fs.lstatSync(srcPath).isDirectory()) { + fs.cpSync(srcPath, destPath, { recursive: true }); + } else { + fs.copyFileSync(srcPath, destPath); + } + } +} + +// Helper to zip a directory +function zipDirectory(sourceDir, outPath) { + return new Promise((resolve, reject) => { + const archive = archiver('zip', { zlib: { level: 9 } }); + const stream = fs.createWriteStream(outPath); + + archive + .directory(sourceDir, false) + .on('error', err => reject(err)) + .pipe(stream); + + stream.on('close', () => resolve()); + archive.finalize(); + }); +} + +async function buildBrowser(browserName, manifestModifier) { + console.log(`Building for ${browserName}...`); + const browserDistDir = path.join(distDir, browserName); + + // 1. Copy files + copyExtensionFiles(browserDistDir); + + // 2. Modify and write manifest + const browserManifest = manifestModifier(JSON.parse(JSON.stringify(baseManifest))); + fs.writeFileSync( + path.join(browserDistDir, 'manifest.json'), + JSON.stringify(browserManifest, null, 2) + ); + + // 3. Zip it + const zipPath = path.join(distDir, `koalasync-${browserName}.zip`); + await zipDirectory(browserDistDir, zipPath); + console.log(`Successfully built and zipped ${browserName} -> ${zipPath}`); +} + +async function run() { + try { + // Build Chrome + await buildBrowser('chrome', (manifest) => { + manifest.background = { + service_worker: "background.js", + type: "module" + }; + return manifest; + }); + + // Build Firefox + await buildBrowser('firefox', (manifest) => { + manifest.background = { + scripts: ["background.js"], + type: "module" + }; + manifest.browser_specific_settings = { + gecko: { + id: "koalasync@shik3i.net" + } + }; + return manifest; + }); + + console.log('Build complete!'); + } catch (error) { + console.error('Build failed:', error); + process.exit(1); + } +} + +run(); diff --git a/scripts/sync-constants.bat b/scripts/sync-constants.bat deleted file mode 100644 index 2ff54fa..0000000 --- a/scripts/sync-constants.bat +++ /dev/null @@ -1,12 +0,0 @@ -@echo off -REM KoalaSync - Protocol Synchronization Script (Windows) -REM -REM This script copies the master constants.js file from the shared directory -REM to the extension directory. Since Chrome Extensions cannot load files -REM outside their root, this manual sync is required after any changes to -REM the shared protocol. - -if not exist extension\shared mkdir extension\shared -copy /y shared\constants.js extension\shared\constants.js -copy /y shared\blacklist.js extension\shared\blacklist.js -echo ✓ constants.js and blacklist.js synced to extension\shared\ diff --git a/scripts/sync-constants.sh b/scripts/sync-constants.sh deleted file mode 100755 index 8ac72ba..0000000 --- a/scripts/sync-constants.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh -# KoalaSync - Protocol Synchronization Script (Linux/macOS) -# -# This script copies the master constants.js file from the shared directory -# to the extension directory. Since Chrome Extensions cannot load files -# outside their root, this manual sync is required after any changes to -# the shared protocol. - -mkdir -p extension/shared -cp shared/constants.js extension/shared/constants.js -cp shared/blacklist.js extension/shared/blacklist.js -echo "✓ constants.js and blacklist.js synced to extension/shared/"