From 160b6e21bdfaedaf662f4ef5d97ee616b68d003f Mon Sep 17 00:00:00 2001 From: ShuangYa Date: Wed, 27 May 2026 12:21:26 +0800 Subject: [PATCH 1/7] refactor: packer --- .github/workflows/dev.yml | 2 - .github/workflows/main.yml | 1 - .github/workflows/release.yml | 1 - package.json | 7 +- pnpm-lock.yaml | 101 +++----------- scripts/browser-config/get-path.js | 8 +- scripts/config.mjs | 13 +- scripts/get-snapshot-version.mjs | 59 ++------ scripts/pack-utils/amo.mjs | 167 ----------------------- scripts/pack-utils/crx.mjs | 55 -------- scripts/pack-utils/cws.mjs | 30 ----- scripts/pack-utils/edge.mjs | 26 ---- scripts/pack-utils/xpi.mjs | 50 ------- scripts/pack.mjs | 164 +++++++---------------- scripts/release.mjs | 208 +++-------------------------- scripts/utils.mjs | 69 ---------- scripts/zip.mjs | 50 ------- 17 files changed, 100 insertions(+), 911 deletions(-) delete mode 100644 scripts/pack-utils/amo.mjs delete mode 100644 scripts/pack-utils/crx.mjs delete mode 100644 scripts/pack-utils/cws.mjs delete mode 100644 scripts/pack-utils/edge.mjs delete mode 100644 scripts/pack-utils/xpi.mjs delete mode 100644 scripts/zip.mjs diff --git a/.github/workflows/dev.yml b/.github/workflows/dev.yml index e4ceabde..47ecac72 100644 --- a/.github/workflows/dev.yml +++ b/.github/workflows/dev.yml @@ -62,7 +62,6 @@ jobs: echo "INPUT_VERSION=${{ github.event.inputs.version }}" >> $GITHUB_ENV - uses: pnpm/action-setup@v6 with: - cache: true version: 11 - name: Setup Node.js uses: actions/setup-node@v6 @@ -121,7 +120,6 @@ jobs: - uses: actions/checkout@v6 - uses: pnpm/action-setup@v6 with: - cache: true version: 11 - name: Setup Node.js uses: actions/setup-node@v6 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 45703cc9..004b64b3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -34,7 +34,6 @@ jobs: - uses: actions/checkout@v6 - uses: pnpm/action-setup@v6 with: - cache: true version: 11 - name: Setup Node.js uses: actions/setup-node@v6 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b08f722c..f125708b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -35,7 +35,6 @@ jobs: echo "INPUT_VERSION=${{ github.event.inputs.version }}" >> $GITHUB_ENV - uses: pnpm/action-setup@v6 with: - cache: true version: 11 - name: Setup Node.js uses: actions/setup-node@v6 diff --git a/package.json b/package.json index 9a3794d4..54e15333 100644 --- a/package.json +++ b/package.json @@ -42,9 +42,8 @@ }, "devDependencies": { "@biomejs/biome": "^2.1.2", + "@fxb/extension-packer": "github:FirefoxBar/extension-packer", "@modern-js/tsconfig": "^2.68.5", - "@plasmohq/chrome-webstore-api": "^2.11.0", - "@plasmohq/edge-addons-api": "^2.0.0", "@rsbuild/core": "^1.4.11", "@rsbuild/plugin-react": "^1.3.4", "@swc/plugin-emotion": "^11.0.0", @@ -54,11 +53,7 @@ "@types/react": "^18.3.1", "@types/react-dom": "^18.3.1", "@types/webextension-polyfill": "^0.12.3", - "amo-upload": "^1.1.0", - "axios": "^1.7.2", - "cpr": "^3.0.1", "cross-env": "^7.0.3", - "crx": "^5.0.1", "get-port": "^7.1.0", "lint-staged": "^13.2.2", "lodash": "^4.17.21", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e727f025..02bfbaa2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -64,15 +64,12 @@ importers: '@biomejs/biome': specifier: ^2.1.2 version: 2.1.2 + '@fxb/extension-packer': + specifier: github:FirefoxBar/extension-packer + version: git+https://git@github.com:FirefoxBar/extension-packer.git#0caee83a4f285361df313d7ab85a8045f3993559 '@modern-js/tsconfig': specifier: ^2.68.5 version: 2.68.5 - '@plasmohq/chrome-webstore-api': - specifier: ^2.11.0 - version: 2.11.0 - '@plasmohq/edge-addons-api': - specifier: ^2.0.0 - version: 2.0.0 '@rsbuild/core': specifier: ^1.4.11 version: 1.4.11 @@ -100,21 +97,9 @@ importers: '@types/webextension-polyfill': specifier: ^0.12.3 version: 0.12.3 - amo-upload: - specifier: ^1.1.0 - version: 1.1.0 - axios: - specifier: ^1.7.2 - version: 1.7.2 - cpr: - specifier: ^3.0.1 - version: 3.0.1 cross-env: specifier: ^7.0.3 version: 7.0.3 - crx: - specifier: ^5.0.1 - version: 5.0.1 get-port: specifier: ^7.1.0 version: 7.1.0 @@ -409,6 +394,11 @@ packages: resolution: {integrity: sha512-PyUXQWB42s4jBli435TDiYuVsadwRHnMc27YaLouINktvTWsL3FcKrRMGawTayFk46X+n5bE23RjUTWQwrukWw==} engines: {node: '>= 0.10.0'} + '@fxb/extension-packer@git+https://git@github.com:FirefoxBar/extension-packer.git#0caee83a4f285361df313d7ab85a8045f3993559': + resolution: {commit: 0caee83a4f285361df313d7ab85a8045f3993559, repo: git@github.com:FirefoxBar/extension-packer.git, type: git} + version: 1.0.0 + engines: {node: '>=20', pnpm: '>=10'} + '@humanwhocodes/config-array@0.13.0': resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} engines: {node: '>=10.10.0'} @@ -865,9 +855,6 @@ packages: async@3.2.4: resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==} - asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - atomic-sleep@1.0.0: resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} engines: {node: '>=8.0.0'} @@ -875,9 +862,6 @@ packages: atomically@2.0.3: resolution: {integrity: sha512-kU6FmrwZ3Lx7/7y3hPS5QnbJfaohcIul5fGqf7ok+4KklIEk9tJ0C2IQPdacSbVUWv6zVHXEBWoWd6NrVMT7Cw==} - axios@1.7.2: - resolution: {integrity: sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==} - b4a@1.6.7: resolution: {integrity: sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==} @@ -1118,10 +1102,6 @@ packages: resolution: {integrity: sha512-lomjuFZKfM6MSAnV9aCZC9sc0qGbmZdfygNv+nCpqVkSKdCxCklLtd16O0EILGkImHw9ZpHkAnHaB+8Zxq5W6Q==} engines: {node: '>=8.0.0'} - combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - comma-separated-tokens@2.0.3: resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} @@ -1348,10 +1328,6 @@ packages: resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==} engines: {node: '>= 14'} - delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - dequal@2.0.3: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} @@ -1633,15 +1609,6 @@ packages: flatted@3.2.7: resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} - follow-redirects@1.15.6: - resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - foreground-child@3.3.1: resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} @@ -1650,10 +1617,6 @@ packages: resolution: {integrity: sha512-G6NsmEW15s0Uw9XnCg+33H3ViYRyiM0hMrMhhqQOR8NFc5GhYrI+6I3u7OTw7b91J2g8rtvMBZJDbcGb2YUniw==} engines: {node: '>= 18'} - form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} - engines: {node: '>= 6'} - fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} @@ -2362,14 +2325,6 @@ packages: resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} engines: {node: '>=8.6'} - mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - - mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - mimic-fn@2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} @@ -3800,6 +3755,16 @@ snapshots: '@fregante/relaxed-json@2.0.0': {} + '@fxb/extension-packer@git+https://git@github.com:FirefoxBar/extension-packer.git#0caee83a4f285361df313d7ab85a8045f3993559': + dependencies: + '@plasmohq/chrome-webstore-api': 2.11.0 + '@plasmohq/edge-addons-api': 2.0.0 + amo-upload: 1.1.0 + cpr: 3.0.1 + crx: 5.0.1 + lodash-es: 4.17.21(patch_hash=87739c1de481c0b0069b3c5cfcc3a63a3080e12ad9027e4cfb44f04521d3c4d7) + rimraf: 6.0.1 + '@humanwhocodes/config-array@0.13.0': dependencies: '@humanwhocodes/object-schema': 2.0.3 @@ -4336,8 +4301,6 @@ snapshots: async@3.2.4: {} - asynckit@0.4.0: {} - atomic-sleep@1.0.0: {} atomically@2.0.3: @@ -4345,14 +4308,6 @@ snapshots: stubborn-fs: 1.2.5 when-exit: 2.1.4 - axios@1.7.2: - dependencies: - follow-redirects: 1.15.6 - form-data: 4.0.0 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug - b4a@1.6.7: {} babel-plugin-macros@3.1.0: @@ -4600,10 +4555,6 @@ snapshots: strip-ansi: 6.0.1 wcwidth: 1.0.1 - combined-stream@1.0.8: - dependencies: - delayed-stream: 1.0.0 - comma-separated-tokens@2.0.3: {} commander@10.0.1: {} @@ -4808,8 +4759,6 @@ snapshots: escodegen: 2.1.0 esprima: 4.0.1 - delayed-stream@1.0.0: {} - dequal@2.0.3: {} devlop@1.1.0: @@ -5131,8 +5080,6 @@ snapshots: flatted@3.2.7: {} - follow-redirects@1.15.6: {} - foreground-child@3.3.1: dependencies: cross-spawn: 7.0.6 @@ -5140,12 +5087,6 @@ snapshots: form-data-encoder@4.1.0: {} - form-data@4.0.0: - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - fs-constants@1.0.0: {} fs-extra@11.3.0: @@ -6120,12 +6061,6 @@ snapshots: braces: 3.0.2 picomatch: 2.3.1 - mime-db@1.52.0: {} - - mime-types@2.1.35: - dependencies: - mime-db: 1.52.0 - mimic-fn@2.1.0: {} mimic-fn@4.0.0: {} diff --git a/scripts/browser-config/get-path.js b/scripts/browser-config/get-path.js index eba00545..5903a4c2 100644 --- a/scripts/browser-config/get-path.js +++ b/scripts/browser-config/get-path.js @@ -1,13 +1,7 @@ const browserConfig = require('./browser.config.json'); function getOutputFile(browserKey, version, extension) { - return ( - ['HeaderEditor', version, browserConfig[browserKey].MANIFEST_VER].join( - '-', - ) + - '.' + - extension - ); + return `HeaderEditor-${version}-${browserConfig[browserKey].MANIFEST_VER}.${extension}`; } function getDistDir(browser) { diff --git a/scripts/config.mjs b/scripts/config.mjs index 87b55ab7..1ba99655 100644 --- a/scripts/config.mjs +++ b/scripts/config.mjs @@ -1,13 +1,13 @@ import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; +import { readJSON } from '@fxb/extension-packer'; import extension from '../extension.json' with { type: 'json' }; import { getDistDir, getOutputFile } from './browser-config/get-path.js'; -import { readJSON } from './utils.mjs'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); -const root = join(__dirname, '..'); +export const root = join(__dirname, '..'); function getDistPath(browser) { return join(root, getDistDir(browser)); @@ -18,11 +18,6 @@ async function getVersion(path) { return manifest.version; } -const temp = join(root, 'temp'); -const pack = join(temp, 'dist-pack'); -const release = join(temp, 'release'); - +export const releasePath = join(temp, 'release'); export const scriptRoot = __dirname; -export const resolve = join; -export const path = { temp, root, pack, release }; -export { join, extension, getDistPath, getDistDir, getOutputFile, getVersion }; +export { extension, getDistPath, getDistDir, getOutputFile, getVersion }; diff --git a/scripts/get-snapshot-version.mjs b/scripts/get-snapshot-version.mjs index c16995ee..d01f31d2 100644 --- a/scripts/get-snapshot-version.mjs +++ b/scripts/get-snapshot-version.mjs @@ -1,12 +1,6 @@ -import { mkdir, writeFile } from 'node:fs/promises'; -import { dirname, join } from 'node:path'; -import { fileURLToPath } from 'node:url'; -import axios from 'axios'; - -// import { readJSON } from './utils.mjs'; - -const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); +import { join } from 'node:path'; +import { getSnapshotVersion } from '@fxb/extension-packer'; +import { root } from './config.mjs'; async function main() { const token = process.env.TOKEN; @@ -19,47 +13,16 @@ async function main() { return; } - // const pkgJson = await readJSON(join(__dirname, '../package.json')); - // const { version: versionPrefix } = pkgJson; - // console.log('Get latest release version from package.json'); + const filePath = join(root, 'temp/version.txt'); - // Get latest release version - const gitHubToken = process.env.GITHUB_TOKEN; - const gitHubBaseURL = - process.env.GITHUB_API_URL + '/repos/' + process.env.GITHUB_REPOSITORY; - const latestRelease = await axios.get(gitHubBaseURL + '/releases/latest', { - headers: { - Accept: 'application/vnd.github+json', - Authorization: 'Bearer ' + gitHubToken, - 'X-GitHub-Api-Version': '2022-11-28', - }, + return await getSnapshotVersion({ + token, + gitHubApi: process.env.GITHUB_API_URL, + gitHubRepo: process.env.GITHUB_REPOSITORY, + gitHubToken: process.env.GITHUB_TOKEN, + extName: 'header-editor', + writeTo: filePath, }); - const versionPrefix = latestRelease.data.tag_name.replace(/^v/, ''); - - // Get remote version - const params = new URLSearchParams(); - params.append('name', 'header-editor'); - params.append('ver', versionPrefix); - params.append('token', token); - - const resp = await axios.get( - 'https://server-api.sylibs.com/ext/snapshot.php?' + params.toString(), - ); - const text = resp.data; - - const filePath = join(__dirname, '../temp/version.txt'); - if (/^(\d+)$/.test(text)) { - await mkdir(join(__dirname, '../temp/'), { - recursive: true, - }); - const newVersion = `${versionPrefix}.${text}`; - await writeFile(filePath, newVersion, { - encoding: 'utf8', - }); - console.log(`Got version: ${newVersion}, wrote to: ${filePath}`); - } else { - console.log(`Invalid version: ${text}`); - } } main(); diff --git a/scripts/pack-utils/amo.mjs b/scripts/pack-utils/amo.mjs deleted file mode 100644 index 60588192..00000000 --- a/scripts/pack-utils/amo.mjs +++ /dev/null @@ -1,167 +0,0 @@ -import fs from 'node:fs/promises'; -import path from 'node:path'; -import { setTimeout as sleep } from 'node:timers/promises'; -import { signAddon } from 'amo-upload'; -import { last } from 'lodash-es'; -import { path as _path, getVersion } from '../config.mjs'; -import { copyDir, fileExists, getNote } from '../utils.mjs'; -import { createZip } from '../zip.mjs'; - -let packingSourceCode = null; -/** - * Pack source code respecting .gitignore rules - * @param {string} rootPath - Project root path - * @returns {Promise} - Path to the created source zip file - */ -async function packSourceCode(rootPath) { - const tempDir = path.join(_path.temp, 'source-package'); - const sourceZipPath = path.join(_path.temp, 'source.zip'); - if (await fileExists(sourceZipPath)) { - return sourceZipPath; - } - const clear = async () => { - try { - await fs.rm(tempDir, { recursive: true, force: true }); - } catch (err) { - console.warn('Could not clean up temporary directory:', err.message); - } - }; - try { - // Create temp directory - await fs.mkdir(tempDir, { recursive: true }); - // Read .gitignore and create filter function - const gitignorePath = path.join(rootPath, '.gitignore'); - const gitignoreContent = await fs.readFile(gitignorePath, 'utf8'); - const ignorePatterns = gitignoreContent - .split('\n') - .map(line => line.trim().replace(/\/$/, '')) - .filter(line => line && !line.startsWith('#')); - // ignore other files - ignorePatterns.push('.git'); - ignorePatterns.push('docs'); - ignorePatterns.push('tests'); - // console.log('ignorePatterns', ignorePatterns); - // Simple function to check if a pattern with * matches a string - const matchesPattern = (pattern, str) => { - if (!pattern.includes('*')) { - return pattern === str; - } - // Escape special regex characters except * - const escapedPattern = pattern.replace(/[.+?^${}()|[\]\\]/g, '\\$&'); - // Convert * to .* for regex matching - const regexPattern = escapedPattern.replace(/\*/g, '.*'); - const regex = new RegExp(`^${regexPattern}$`); - return regex.test(str); - }; - // Read all top-level entries in rootPath - const entries = await fs.readdir(rootPath); - for (const entry of entries) { - if (entry.startsWith('dist_')) { - continue; - } - // Check if this entry should be ignored - const shouldIgnore = ignorePatterns.some(pattern => - matchesPattern(pattern, entry), - ); - if (shouldIgnore) { - continue; - } - const srcPath = path.join(rootPath, entry); - const destPath = path.join(tempDir, entry); - // Check if it's a file or directory - const stat = await fs.stat(srcPath); - if (stat.isDirectory()) { - await copyDir(srcPath, destPath); - } else { - await fs.copyFile(srcPath, destPath); - } - } - // Create source code zip - await createZip(tempDir, sourceZipPath); - await clear(); - return sourceZipPath; - } finally { - await clear(); - } -} - -export const waitSubmit = []; -export async function submitAddon( - rootPath, - uploadSourceCode = false, - messagePrefix = '', - options = {}, -) { - if (!process.env.AMO_KEY) { - return Promise.reject(new Error('AMO_KEY not found')); - } - if (!process.env.AMO_SECRET) { - return Promise.reject(new Error('AMO_SECRET not found')); - } - - const time = Date.now(); - if (waitSubmit.length !== 0) { - const s = last(waitSubmit) + 10000; - if (s > time) { - waitSubmit.push(s); - await sleep(s - time); - } else { - waitSubmit.push(time); - } - } else { - waitSubmit.push(time); - } - - const opts = {}; - - // Pack source codes - if (uploadSourceCode) { - if (!packingSourceCode) { - packingSourceCode = packSourceCode(rootPath); - } - opts.sourceFile = await packingSourceCode; - } - - console.log(`[${messagePrefix}] [${options.addonId}] start signAddon`); - return signAddon({ - ...opts, - apiKey: process.env.AMO_KEY, - apiSecret: process.env.AMO_SECRET, - override: false, - pollInterval: 8000, - pollRetry: 9999, - pollRetryExisting: 9999, - retryAfterLimit: 600, - ...options, - onDebug: type => { - if ( - ![ - 'token-update', - 'request-start', - 'request-end', - 'retry-wait', - 'upload-file-poll', - 'wait-poll', - ].includes(type) - ) { - console.log(`[${messagePrefix}] [${options.addonId}] ${type}`); - } - }, - }); -} - -export default async function ({ - rootPath, - sourcePath, - zipPath, - browserConfig, - extensionConfig, -}) { - return submitAddon(rootPath, true, 'amo', { - addonId: extensionConfig.id, - addonVersion: await getVersion(sourcePath), - channel: 'listed', - distFile: zipPath, - approvalNotes: getNote(browserConfig), - }); -} diff --git a/scripts/pack-utils/crx.mjs b/scripts/pack-utils/crx.mjs deleted file mode 100644 index 66408b33..00000000 --- a/scripts/pack-utils/crx.mjs +++ /dev/null @@ -1,55 +0,0 @@ -import { readFile, writeFile } from 'node:fs/promises'; -import ChromeExtension from 'crx'; -import { getOutputFile, getVersion, join } from '../config.mjs'; -import { outputJSON } from '../utils.mjs'; - -async function createCrx(fileContent, keyContent) { - if (!keyContent) { - throw new Error('No priv key'); - } - const crx = new ChromeExtension({ - codebase: 'http://localhost:8000/myExtension.crx', - privateKey: keyContent, - }); - - crx.loaded = true; - - const crxBuffer = await crx.pack(fileContent); - - return crxBuffer; -} - -async function packCrx({ - sourcePath, - zipPath, - releasePath, - browserConfig, - extensionConfig, -}) { - const fileContent = await readFile(zipPath); - if (typeof process.env[extensionConfig.priv_key] === 'undefined') { - throw new Error(`${extensionConfig.priv_key} not found`); - } - const content = await createCrx( - fileContent, - process.env[extensionConfig.priv_key], - ); - const fileName = getOutputFile( - extensionConfig.browser, - await getVersion(sourcePath), - 'crx', - ); - const out = join(releasePath, fileName); - await writeFile(out, content); - - const infoFile = join(releasePath, `${fileName}-config.json`); - await outputJSON(infoFile, { - id: extensionConfig.id, - browser: browserConfig, - extension: extensionConfig, - }); - - return out; -} - -export default packCrx; diff --git a/scripts/pack-utils/cws.mjs b/scripts/pack-utils/cws.mjs deleted file mode 100644 index ab4918db..00000000 --- a/scripts/pack-utils/cws.mjs +++ /dev/null @@ -1,30 +0,0 @@ -import { ChromeWebstoreAPI } from '@plasmohq/chrome-webstore-api'; - -async function packCws({ zipPath, extensionConfig }) { - if (!process.env.CWS_CLIENT_ID) { - return Promise.reject(new Error('CWS_CLIENT_ID not found')); - } - if (!process.env.CWS_CLIENT_SECRET) { - return Promise.reject(new Error('CWS_CLIENT_SECRET not found')); - } - if (!process.env.CWS_TOKEN) { - return Promise.reject(new Error('CWS_TOKEN not found')); - } - - const id = extensionConfig.id; - - const client = new ChromeWebstoreAPI({ - extId: id, - refreshToken: process.env.CWS_TOKEN, - clientId: process.env.CWS_CLIENT_ID, - clientSecret: process.env.CWS_CLIENT_SECRET, - }); - - const res = await client.submit({ - filePath: zipPath, - }); - - return JSON.stringify(res); -} - -export default packCws; diff --git a/scripts/pack-utils/edge.mjs b/scripts/pack-utils/edge.mjs deleted file mode 100644 index 085abc4d..00000000 --- a/scripts/pack-utils/edge.mjs +++ /dev/null @@ -1,26 +0,0 @@ -import { createReadStream } from 'node:fs'; -import { EdgeAddonsAPI } from '@plasmohq/edge-addons-api'; -import { getNote } from '../utils.mjs'; - -export default async function ({ zipPath, browserConfig, extensionConfig }) { - if (!process.env.MS_CLIENT_ID) { - return Promise.reject(new Error('MS_CLIENT_ID not found')); - } - if (!process.env.MS_API_KEY) { - return Promise.reject(new Error('MS_API_KEY not found')); - } - - const client = new EdgeAddonsAPI({ - productId: extensionConfig.product_id, - clientId: process.env.MS_CLIENT_ID, - apiKey: process.env.MS_API_KEY, - }); - - const uploadResp = await client.upload(createReadStream(zipPath)); - console.log('[edge] upload done', uploadResp); - const uploadStatus = await client.waitForUpload(uploadResp); - console.log('[edge] upload check success', uploadStatus); - const publishResp = await client.publish(getNote(browserConfig)); - console.log('[edge] publish done', publishResp); - return JSON.stringify(await client.getPublishStatus(publishResp)); -} diff --git a/scripts/pack-utils/xpi.mjs b/scripts/pack-utils/xpi.mjs deleted file mode 100644 index 5789746d..00000000 --- a/scripts/pack-utils/xpi.mjs +++ /dev/null @@ -1,50 +0,0 @@ -import { rename } from 'node:fs/promises'; -import { setTimeout as sleep } from 'node:timers/promises'; -import { getOutputFile, getVersion, join } from '../config.mjs'; -import { outputJSON } from '../utils.mjs'; -import { submitAddon, waitSubmit } from './amo.mjs'; - -async function packXpi({ - rootPath, - sourcePath, - zipPath, - releasePath, - browserConfig, - extensionConfig, -}) { - const version = await getVersion(sourcePath); - - if (waitSubmit.length > 0) { - const last = waitSubmit[waitSubmit.length - 1]; - // wait 60s for AMO submit - const nextRun = last + 60000; - if (Date.now() < nextRun) { - console.log( - `[xpi] [${extensionConfig.id}] wait ${nextRun - Date.now()}ms`, - ); - await sleep(nextRun - Date.now()); - } - } - - const fileName = getOutputFile(extensionConfig.browser, version, 'xpi'); - const outFile = join(releasePath, fileName); - - await submitAddon(rootPath, false, 'xpi', { - addonId: extensionConfig.id, - addonVersion: version, - channel: 'unlisted', - distFile: zipPath, - output: outFile, - }); - - console.log(`[xpi] [${extensionConfig.id}] downloaded to ${outFile}`); - const infoFile = join(releasePath, `${fileName}-config.json`); - await outputJSON(infoFile, { - id: extensionConfig.id, - browser: browserConfig, - extension: extensionConfig, - }); - return outFile; -} - -export default packXpi; diff --git a/scripts/pack.mjs b/scripts/pack.mjs index 68a3cc34..b261f2bd 100644 --- a/scripts/pack.mjs +++ b/scripts/pack.mjs @@ -1,117 +1,15 @@ -/** - * 进行多渠道打包 - * - * dist:原本的输出文件夹 - * dist-pack:用于打包的文件夹 - * dist-pack/{platform}:各个平台的文件夹 - * dist-pack/{platform}.zip:各个平台的打包文件 - * dist-pack/release:其他平台打包输出结果 - * 在这里,打包文件夹统一命名为pack - */ - -import { mkdir, unlink } from 'node:fs/promises'; import { join } from 'node:path'; -import { rimraf } from 'rimraf'; +import { getVersion, pack } from '@fxb/extension-packer'; import getManifest from './browser-config/get-manifest.js'; -import { - join as _join, - path as _path, - extension, - getDistPath, - getVersion, - scriptRoot, -} from './config.mjs'; -import amo from './pack-utils/amo.mjs'; -import crx from './pack-utils/crx.mjs'; -import cws from './pack-utils/cws.mjs'; -import edge from './pack-utils/edge.mjs'; -import xpi from './pack-utils/xpi.mjs'; -import { copyDir, outputJSON, readJSON } from './utils.mjs'; -import { createZip } from './zip.mjs'; +import { getDistPath, getOutputFile, releasePath, root } from './config.mjs'; +import { getNote } from './utils.mjs'; -const packUtils = { - amo, - cws, - xpi, - edge, - crx, +const fileExt = { + crx: 'crx', + xpi: 'xpi', }; -/** - * 打包一个平台的产物 - * @param {*} name - * @param {*} browserConfig 对应browser.config.json中的单项配置 - * @param {*} extensionConfig 对应extension.json中的单项配置 - * @returns - */ -async function prepareOnePlatform(name, extensionConfig) { - if (typeof packUtils[name] === 'undefined') { - console.error(`pack-utils for ${name} not found`); - return; - } - const dirName = [name, extensionConfig.browser].join('_'); - const thisPack = _join(_path.pack, dirName); - const zipPath = _join(_path.pack, `${dirName}.zip`); - try { - // 复制一份到dist下面 - await copyDir(getDistPath(extensionConfig.browser), thisPack); - // 重新生成manifest - const version = await getVersion(thisPack); - await outputJSON( - _join(thisPack, 'manifest.json'), - getManifest(extensionConfig.browser, { - dev: false, - version, - packer: name, - }), - ); - // 打包成zip - console.log(`[${name}] zip ${thisPack} -> ${zipPath}`); - await createZip(thisPack, zipPath); - } catch (e) { - console.error(`[${name}] prepare error`); - console.error(e); - } - return { dirName, thisPack, zipPath }; -} -async function packOnePlatform(name, prepare, browserConfig, extensionConfig) { - const { thisPack, zipPath } = prepare; - if (typeof packUtils[name] === 'undefined') { - console.error(`pack-utils for ${name} not found`); - return; - } - try { - const res = await packUtils[name]({ - rootPath: _path.root, - sourcePath: thisPack, - zipPath, - releasePath: _path.release, - browserConfig, - extensionConfig, - }); - console.log(`[${name}] pack success: ${res}`); - } catch (e) { - console.error(`[${name}] pack error`); - console.error(e); - } - try { - await unlink(zipPath); - } catch (_) { - // ignore - } -} - async function main() { - // 检查打包目录是否存在 - await rimraf(_path.pack); - await rimraf(_path.release); - await mkdir(_path.pack, { - recursive: true, - }); - await mkdir(_path.release, { - recursive: true, - }); - let platform = []; if (process.env.INPUT_PLATFORM) { platform = process.env.INPUT_PLATFORM.split(','); @@ -126,19 +24,51 @@ async function main() { const browserConfig = await readJSON( join(scriptRoot, 'browser-config/browser.config.json'), ); + const extensionConfig = await readJSON(join(root, 'extension.json')); - const queue = []; - - for (const name of platform) { - const platformConfig = extension[name]; - for (const item of platformConfig) { - const browser = browserConfig[item.browser]; - const prepare = await prepareOnePlatform(name, item); - queue.push(packOnePlatform(name, { ...prepare }, browser, item)); + const finalPlatform = []; + const addPlatform = async name => { + for (const item of extensionConfig[name]) { + const distPath = getDistPath(item.browser); + const version = await getVersion(distPath); + const finalItem = { + name, + dist: distPath, + output: getOutputFile( + item.browser, + version, + name in fileExt ? fileExt[name] : '1', + ), + }; + if (item.priv_key) { + finalItem.privKey = item.priv_key; + } + finalPlatform.push(finalItem); } + }; + for (const name of platform) { + await addPlatform(name); } - await Promise.all(queue); + await pack( + { + tempPath: join(root, 'pack-temp'), + rootPath: root, + releasePath, + browserConfig, + extensionConfig, + msClientID: process.env.MS_CLIENT_ID, + msApiKey: process.env.MS_API_KEY, + amoKey: process.env.AMO_KEY, + amoSecret: process.env.AMO_SECRET, + cwsClientID: process.env.CWS_CLIENT_ID, + cwsClientSecret: process.env.CWS_CLIENT_SECRET, + cwsToken: process.env.CWS_TOKEN, + getManifest, + getNote, + }, + finalPlatform, + ); } main(); diff --git a/scripts/release.mjs b/scripts/release.mjs index 4f04bca1..80fa37e4 100644 --- a/scripts/release.mjs +++ b/scripts/release.mjs @@ -1,211 +1,39 @@ -import { Blob } from 'node:buffer'; -import { createHash } from 'node:crypto'; -import { readdir, readFile } from 'node:fs/promises'; import { join } from 'node:path'; -import { URLSearchParams } from 'node:url'; -import axios from 'axios'; -import { get } from 'lodash-es'; -import { - path as _path, - extension, - getDistPath, - getVersion, - scriptRoot, -} from './config.mjs'; -import { fileExists, readJSON } from './utils.mjs'; - -function hash(content) { - const fsHash = createHash('sha256'); - fsHash.update(content); - return fsHash.digest('hex'); -} +import { getVersion, readJSON, release } from '@fxb/extension-packer'; +import { extension, getDistPath, releasePath, scriptRoot } from './config.mjs'; async function main() { if (!extension.github.enable) { return; } - const repo = process.env.GITHUB_REPOSITORY; - if (!repo) { - console.log('GITHUB_REPOSITORY not found'); - return; - } - const token = process.env.TOKEN; - if (!token) { - console.log('TOKEN not found'); - return; - } - if (!process.env.GITHUB_TOKEN) { - console.log('GITHUB_TOKEN not found'); - return; - } - // Get version - let version = ''; const browserConfig = await readJSON( join(scriptRoot, 'browser-config/browser.config.json'), ); - const browserList = Object.keys(browserConfig); + + let distRootPath = ''; for (const browser of browserList) { const path = getDistPath(browser); - if (await fileExists(join(path, 'manifest.json'))) { - version = await getVersion(path); - console.log(`Get version from ${path}`); - break; - } - } - if (!version) { - console.log('version not found'); - return; - } - - const tagName = process.env.INPUT_RELEASE_TAG || process.env.GITHUB_REF_NAME; - if (!tagName) { - console.log('No tag name'); - return; - } - - // Git basic infos - const gitName = repo.split('/'); - const gitHubBaseURL = - process.env.GITHUB_API_URL + '/repos/' + process.env.GITHUB_REPOSITORY; - const gitHubToken = process.env.GITHUB_TOKEN; - const gitHubApiHeader = { - Accept: 'application/vnd.github+json', - Authorization: 'Bearer ' + gitHubToken, - 'X-GitHub-Api-Version': '2022-11-28', - 'Content-Type': 'application/json', - }; - - const assets = []; - - const dirContent = await readdir(_path.release); - for (const file of dirContent) { - if (!file.endsWith('.xpi') && !file.endsWith('.crx')) { - continue; - } - const fullPath = join(_path.release, file); - if (!(await fileExists(fullPath))) { - continue; - } - const fileContent = await readFile(fullPath); - const info = await readJSON(join(_path.release, file + '-config.json')); - assets.push({ - id: info.id, - name: file, - path: fullPath, - hash: hash(fileContent), - content: fileContent, - config: info, - url: `https://github.com/${repo}/releases/download/${tagName}/${file}`, - }); - } - - if (assets.length === 0) { - console.log('No assets found'); - return; - } - - // Check if release is exists - console.log('Get release info...', tagName); - const res = await axios.get(`${gitHubBaseURL}/releases`, { - headers: gitHubApiHeader, - }); - let releaseInfo = res.data.find(x => x.tag_name === tagName); - if (!releaseInfo) { - console.log('Release not exists, creating...'); try { - const res = await axios.post( - `${gitHubBaseURL}/releases`, - { - owner: gitName[0], - repo: gitName[1], - tag_name: tagName, - name: version, - body: '', - draft: false, - prerelease: false, - }, - { - headers: gitHubApiHeader, - }, - ); - console.log(`Release created: #${res.data.id}`); - releaseInfo = res.data; - } catch (e) { - console.log('fail: ', e.response.status, e.response.data); - return; - } - } else { - console.log(`Release exists: #${releaseInfo.id} ${releaseInfo.name}`); - } - const releaseId = releaseInfo.id; - const releaseUploadUrl = releaseInfo.upload_url.replace( - /\/assets(.*)$/, - '/assets', - ); - - // Upload all assets to release - for (const it of assets) { - const fileContent = await readFile(it.path); - const blob = new Blob([fileContent], { - type: 'application/octet-stream', - }); - console.log('Upload file: ' + it.path); - try { - await axios.post( - `${releaseUploadUrl}?name=${encodeURIComponent(it.name)}`, - blob, - { - headers: { - ...gitHubApiHeader, - 'Content-Type': 'application/octet-stream', - }, - }, - ); - console.log('success'); + await getVersion(path); + distRootPath = path; + break; } catch (e) { - console.log('fail: ', e.response.status, e.response.data); + // ignore } } - // Update release description - try { - console.log('Update release description...'); - await axios.patch( - `${gitHubBaseURL}/releases/${releaseId}`, - { - tag_name: tagName, - name: version, - draft: false, - prerelease: false, - }, - { - headers: gitHubApiHeader, - }, - ); - console.log('success'); - } catch (e) { - console.log('fail: ', e.response.status, e.response.data); - } - - // notify the update server - const notifyAssets = assets.map(x => ({ - ...x, - content: '', - config: undefined, - min_version: get(x, 'config.extension.min_version'), - })); - console.log('notify the update server', notifyAssets); - const params = new URLSearchParams({ - token: token, - name: 'header-editor', - version, - assets: JSON.stringify(notifyAssets), + return await release({ + token: process.env.TOKEN, + gitHubApi: process.env.GITHUB_API_URL, + gitHubRepo: process.env.GITHUB_REPOSITORY, + gitHubToken: process.env.GITHUB_TOKEN, + distRootPath, + browserConfig, + tagName: process.env.INPUT_RELEASE_TAG || process.env.GITHUB_REF_NAME, + releasePath, + extName: 'header-editor', }); - await axios.post( - 'https://server-api.sylibs.com/ext/update.php', - params.toString(), - ); } main(); diff --git a/scripts/utils.mjs b/scripts/utils.mjs index 28906fdb..03354196 100644 --- a/scripts/utils.mjs +++ b/scripts/utils.mjs @@ -1,72 +1,3 @@ -import fs from 'node:fs/promises'; -import path from 'node:path'; -import cpr from 'cpr'; - -/** - * Check if a file exists - * @param {*} fullPath - * @returns - */ -export async function fileExists(fullPath) { - try { - await fs.access(fullPath, fs.constants.R_OK); - return true; - } catch (e) { - return false; - } -} - -/** - * Read a JSON file - * @param {string} file - The path to the JSON file - * @param {Object} [options] - Options for reading the file - * @returns {Promise} - The parsed JSON object - */ -export async function readJSON(file, options = {}) { - const data = await fs.readFile(file, options.encoding || 'utf8'); - return JSON.parse(data); -} - -/** - * Write a JSON file, creating parent directories if needed - * @param {string} file - The path to the JSON file - * @param {any} data - The data to write - * @param {Object} [options] - Options for writing the file - * @returns {Promise} - */ -export async function outputJSON(file, data, options = {}) { - // Ensure the directory exists - const dir = path.dirname(file); - await fs.mkdir(dir, { recursive: true }); - - // Stringify the data - const jsonData = JSON.stringify(data, null, options.spaces || null); - - // Write the file - await fs.writeFile(file, jsonData, options.encoding || 'utf8'); -} - -export function copyDir(source, target) { - return new Promise((resolve, reject) => { - cpr( - source, - target, - { - deleteFirst: true, - overwrite: true, - confirm: false, - }, - (err, files) => { - if (err) { - reject(err); - } else { - resolve(files); - } - }, - ); - }); -} - export function getNote(browserConfig) { const repo = process.env.GITHUB_REPOSITORY; const runId = process.env.GITHUB_RUN_ID; diff --git a/scripts/zip.mjs b/scripts/zip.mjs deleted file mode 100644 index f111fef3..00000000 --- a/scripts/zip.mjs +++ /dev/null @@ -1,50 +0,0 @@ -import { execFile } from 'node:child_process'; -import fs from 'node:fs/promises'; -import path from 'node:path'; - -function quotePath(p) { - return '"' + p + '"'; -} - -function exec(command, args, options) { - return new Promise((resolve, reject) => { - execFile(command, args, options, err => { - if (err) { - reject(err); - } else { - resolve(); - } - }); - }); -} - -export async function createZip(inPath, outPath) { - if (process.platform === 'win32') { - try { - await fs.rm(outPath, { recursive: true, maxRetries: 3 }); - } catch (e) { - // ignore - } - return exec( - 'powershell.exe', - [ - '-nologo', - '-noprofile', - '-command', - '& { param([String]$myInPath, [String]$myOutPath); Add-Type -A "System.IO.Compression.FileSystem"; [IO.Compression.ZipFile]::CreateFromDirectory($myInPath, $myOutPath); exit !$? }', - '-myInPath', - quotePath(inPath), - '-myOutPath', - quotePath(outPath), - ], - { - cwd: path.dirname(inPath), - maxBuffer: Infinity, - }, - ); - } - return exec('zip', ['-r', '-y', outPath, '.'], { - cwd: inPath, - maxBuffer: Infinity, - }); -} From 1cd01e0ce098cc7dca9e8f26a4274c66b680cfc7 Mon Sep 17 00:00:00 2001 From: ShuangYa Date: Wed, 27 May 2026 12:28:07 +0800 Subject: [PATCH 2/7] fix: packer url --- package.json | 2 +- pnpm-lock.yaml | 96 +++++++++++++++++++++++++------------------------- 2 files changed, 49 insertions(+), 49 deletions(-) diff --git a/package.json b/package.json index 54e15333..2f1b21e7 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ }, "devDependencies": { "@biomejs/biome": "^2.1.2", - "@fxb/extension-packer": "github:FirefoxBar/extension-packer", + "@fxb/extension-packer": "https://codeload.github.com/FirefoxBar/extension-packer/tar.gz/master", "@modern-js/tsconfig": "^2.68.5", "@rsbuild/core": "^1.4.11", "@rsbuild/plugin-react": "^1.3.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 02bfbaa2..b6fa3355 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -65,8 +65,8 @@ importers: specifier: ^2.1.2 version: 2.1.2 '@fxb/extension-packer': - specifier: github:FirefoxBar/extension-packer - version: git+https://git@github.com:FirefoxBar/extension-packer.git#0caee83a4f285361df313d7ab85a8045f3993559 + specifier: https://codeload.github.com/FirefoxBar/extension-packer/tar.gz/master + version: https://codeload.github.com/FirefoxBar/extension-packer/tar.gz/master '@modern-js/tsconfig': specifier: ^2.68.5 version: 2.68.5 @@ -394,8 +394,8 @@ packages: resolution: {integrity: sha512-PyUXQWB42s4jBli435TDiYuVsadwRHnMc27YaLouINktvTWsL3FcKrRMGawTayFk46X+n5bE23RjUTWQwrukWw==} engines: {node: '>= 0.10.0'} - '@fxb/extension-packer@git+https://git@github.com:FirefoxBar/extension-packer.git#0caee83a4f285361df313d7ab85a8045f3993559': - resolution: {commit: 0caee83a4f285361df313d7ab85a8045f3993559, repo: git@github.com:FirefoxBar/extension-packer.git, type: git} + '@fxb/extension-packer@https://codeload.github.com/FirefoxBar/extension-packer/tar.gz/master': + resolution: {gitHosted: true, integrity: sha512-RlsOjZiz9TGSQdZitpJ2BbDrXesAioeSFFNShkQm0J1sheexTCtjTr5jzCrdQ+xLDHPHxZ5idps11ac3TmF/EQ==, tarball: https://codeload.github.com/FirefoxBar/extension-packer/tar.gz/master} version: 1.0.0 engines: {node: '>=20', pnpm: '>=10'} @@ -590,8 +590,8 @@ packages: '@sec-ant/readable-stream@0.4.1': resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} - '@sindresorhus/is@7.0.2': - resolution: {integrity: sha512-d9xRovfKNz1SKieM0qJdO+PQonjnnIfSNWfHYnBSJ9hkjm0ZPw6HlxscDXYstp3z+7V2GOFHc+J0CYrYTjqCJw==} + '@sindresorhus/is@7.2.0': + resolution: {integrity: sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==} engines: {node: '>=18'} '@swc/counter@0.1.3': @@ -637,8 +637,8 @@ packages: '@types/hast@3.0.4': resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} - '@types/http-cache-semantics@4.0.4': - resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} + '@types/http-cache-semantics@4.2.0': + resolution: {integrity: sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==} '@types/js-cookie@2.2.7': resolution: {integrity: sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA==} @@ -1395,8 +1395,8 @@ packages: error-stack-parser@2.1.4: resolution: {integrity: sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==} - es-toolkit@1.46.1: - resolution: {integrity: sha512-5eNtXOs3tbfxXOj04tjjseeWkRWaoCjdEI+96DgwzZoe6c9juL49pXlzAFTI72aWC9Y8p7168g6XIKjh7k6pyQ==} + es-toolkit@1.47.0: + resolution: {integrity: sha512-n1GuoD0WEQZMBk5tttoZSqwgyLx01oqa5XsBmCHwPyNe1S9jPBEmtR2pSgp2kJuWE3ciFZ6yRHmY4pM4C3OOkw==} es6-error@4.1.1: resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==} @@ -1796,8 +1796,8 @@ packages: resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} engines: {node: '>=8'} - index-to-position@1.1.0: - resolution: {integrity: sha512-XPdx9Dq4t9Qk1mTMbWONJqU7boCoumEH7fRET37HX5+khDUl3J2W6PdALxhILYlIYx2amlwYcRPp28p0tSiojg==} + index-to-position@1.2.0: + resolution: {integrity: sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw==} engines: {node: '>=18'} inflight@1.0.6: @@ -2409,8 +2409,8 @@ packages: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} - normalize-url@8.0.2: - resolution: {integrity: sha512-Ee/R3SyN4BuynXcnTaekmaVdbDAEiNrHqjQIA37mHU8G9pf7aaAD4ZX3XjBLo6rsdcxA/gtkcNYZLt30ACgynw==} + normalize-url@8.1.1: + resolution: {integrity: sha512-JYc0DPlpGWB40kH5g07gGTrYuMqV653k3uBKY6uITPWds3M0ov3GaWGp9lbE3Bzngx8+XkfzgvASb9vk9JDFXQ==} engines: {node: '>=14.16'} npm-run-path@4.0.1: @@ -2548,8 +2548,8 @@ packages: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} - pbf@3.2.1: - resolution: {integrity: sha512-ClrV7pNOn7rtmoQVF4TS1vyU0WhYRnP92fzbfF75jAIwpnzdJXf8iTd4CMEqO4yUenH6NDqLiwjqlh6QgZzgLQ==} + pbf@3.3.0: + resolution: {integrity: sha512-XDF38WCH3z5OV/OVa8GKUNtLAyneuzbCisx7QUCF8Q6Nutx0WnJrQe5O+kOtBlLfRNUws98Y58Lblp+NJG5T4Q==} hasBin: true pend@1.2.0: @@ -2630,8 +2630,8 @@ packages: proto-list@1.2.4: resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} - protocol-buffers-schema@3.6.0: - resolution: {integrity: sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==} + protocol-buffers-schema@3.6.1: + resolution: {integrity: sha512-VG2K63Igkiv9p76tk1lilczEK1cT+kCjKtkdhw1dQZV3k3IXJbd3o6Ho8b9zJZaHSnT2hKe4I+ObmX9w6m5SmQ==} proxy-agent@6.5.0: resolution: {integrity: sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==} @@ -2729,8 +2729,8 @@ packages: readable-stream@2.3.8: resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} - readable-stream@3.6.1: - resolution: {integrity: sha512-+rQmrWMYGA90yenhTYsLWAsLsqVC8osOw6PKE1HDYiO0gdPeKe/xDHNzIAIn4C91YQ6oenEhfYqqc1883qHbjQ==} + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} readable-stream@4.7.0: @@ -2985,8 +2985,8 @@ packages: spdx-expression-parse@3.0.1: resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} - spdx-license-ids@3.0.22: - resolution: {integrity: sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==} + spdx-license-ids@3.0.23: + resolution: {integrity: sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==} split-on-first@3.0.0: resolution: {integrity: sha512-qxQJTx2ryR0Dw0ITYyekNQWpz6f8dGd7vffGNflQQ3Iqj9NJ6qiZ7ELpZsJ/QBhIVAiDfXdag3+Gp8RvWa62AA==} @@ -3755,7 +3755,7 @@ snapshots: '@fregante/relaxed-json@2.0.0': {} - '@fxb/extension-packer@git+https://git@github.com:FirefoxBar/extension-packer.git#0caee83a4f285361df313d7ab85a8045f3993559': + '@fxb/extension-packer@https://codeload.github.com/FirefoxBar/extension-packer/tar.gz/master': dependencies: '@plasmohq/chrome-webstore-api': 2.11.0 '@plasmohq/edge-addons-api': 2.0.0 @@ -3994,7 +3994,7 @@ snapshots: '@sec-ant/readable-stream@0.4.1': {} - '@sindresorhus/is@7.0.2': {} + '@sindresorhus/is@7.2.0': {} '@swc/counter@0.1.3': {} @@ -4044,7 +4044,7 @@ snapshots: dependencies: '@types/unist': 2.0.6 - '@types/http-cache-semantics@4.0.4': {} + '@types/http-cache-semantics@4.2.0': {} '@types/js-cookie@2.2.7': {} @@ -4226,7 +4226,7 @@ snapshots: dependencies: commander: 14.0.3 console-table-printer: 2.15.0 - es-toolkit: 1.46.1 + es-toolkit: 1.47.0 jsonwebtoken: 9.0.3 read-package-up: 12.0.0 @@ -4255,7 +4255,7 @@ snapshots: archiver-utils@2.1.0: dependencies: glob: 7.2.3 - graceful-fs: 4.2.10 + graceful-fs: 4.2.11 lazystream: 1.0.1 lodash.defaults: 4.2.0 lodash.difference: 4.5.0 @@ -4271,7 +4271,7 @@ snapshots: async: 2.6.4 buffer-crc32: 0.2.13 glob: 7.2.3 - readable-stream: 3.6.1 + readable-stream: 3.6.2 tar-stream: 2.2.0 zip-stream: 2.1.3 @@ -4357,7 +4357,7 @@ snapshots: dependencies: buffer: 5.7.1 inherits: 2.0.4 - readable-stream: 3.6.1 + readable-stream: 3.6.2 bluebird@3.7.2: {} @@ -4417,12 +4417,12 @@ snapshots: cacheable-request@12.0.1: dependencies: - '@types/http-cache-semantics': 4.0.4 + '@types/http-cache-semantics': 4.2.0 get-stream: 9.0.1 http-cache-semantics: 4.2.0 keyv: 4.5.4 mimic-response: 4.0.0 - normalize-url: 8.0.2 + normalize-url: 8.1.1 responselike: 3.0.0 callsites@3.1.0: {} @@ -4632,7 +4632,7 @@ snapshots: cpr@3.0.1: dependencies: - graceful-fs: 4.2.10 + graceful-fs: 4.2.11 minimist: 1.2.8 mkdirp: 0.5.6 rimraf: 2.7.1 @@ -4640,7 +4640,7 @@ snapshots: crc32-stream@3.0.1: dependencies: crc: 3.8.0 - readable-stream: 3.6.1 + readable-stream: 3.6.2 crc@3.8.0: dependencies: @@ -4669,7 +4669,7 @@ snapshots: archiver: 3.1.1 commander: 2.20.3 node-rsa: 1.1.1 - pbf: 3.2.1 + pbf: 3.3.0 css-select@5.1.0: dependencies: @@ -4823,7 +4823,7 @@ snapshots: dependencies: stackframe: 1.3.4 - es-toolkit@1.46.1: {} + es-toolkit@1.47.0: {} es6-error@4.1.1: {} @@ -5176,7 +5176,7 @@ snapshots: got@14.4.4: dependencies: - '@sindresorhus/is': 7.0.2 + '@sindresorhus/is': 7.2.0 '@szmarczak/http-timer': 5.0.1 cacheable-lookup: 7.0.0 cacheable-request: 12.0.1 @@ -5308,7 +5308,7 @@ snapshots: indent-string@4.0.0: {} - index-to-position@1.1.0: {} + index-to-position@1.2.0: {} inflight@1.0.6: dependencies: @@ -6154,7 +6154,7 @@ snapshots: normalize-path@3.0.0: {} - normalize-url@8.0.2: {} + normalize-url@8.1.1: {} npm-run-path@4.0.1: dependencies: @@ -6279,7 +6279,7 @@ snapshots: parse-json@8.3.0: dependencies: '@babel/code-frame': 7.27.1 - index-to-position: 1.1.0 + index-to-position: 1.2.0 type-fest: 4.41.0 parse5-htmlparser2-tree-adapter@7.0.0: @@ -6313,7 +6313,7 @@ snapshots: path-type@4.0.0: {} - pbf@3.2.1: + pbf@3.3.0: dependencies: ieee754: 1.2.1 resolve-protobuf-schema: 2.1.0 @@ -6397,7 +6397,7 @@ snapshots: proto-list@1.2.4: {} - protocol-buffers-schema@3.6.0: {} + protocol-buffers-schema@3.6.1: {} proxy-agent@6.5.0: dependencies: @@ -6539,7 +6539,7 @@ snapshots: string_decoder: 1.1.1 util-deprecate: 1.0.2 - readable-stream@3.6.1: + readable-stream@3.6.2: dependencies: inherits: 2.0.4 string_decoder: 1.3.0 @@ -6660,7 +6660,7 @@ snapshots: resolve-protobuf-schema@2.1.0: dependencies: - protocol-buffers-schema: 3.6.0 + protocol-buffers-schema: 3.6.1 resolve@1.22.10: dependencies: @@ -6815,16 +6815,16 @@ snapshots: spdx-correct@3.2.0: dependencies: spdx-expression-parse: 3.0.1 - spdx-license-ids: 3.0.22 + spdx-license-ids: 3.0.23 spdx-exceptions@2.5.0: {} spdx-expression-parse@3.0.1: dependencies: spdx-exceptions: 2.5.0 - spdx-license-ids: 3.0.22 + spdx-license-ids: 3.0.23 - spdx-license-ids@3.0.22: {} + spdx-license-ids@3.0.23: {} split-on-first@3.0.0: {} @@ -6953,7 +6953,7 @@ snapshots: end-of-stream: 1.4.4 fs-constants: 1.0.0 inherits: 2.0.4 - readable-stream: 3.6.1 + readable-stream: 3.6.2 tar-stream@3.1.7: dependencies: @@ -7255,7 +7255,7 @@ snapshots: dependencies: archiver-utils: 2.1.0 compress-commons: 2.1.1 - readable-stream: 3.6.1 + readable-stream: 3.6.2 zod@3.24.4: {} From 663b410383c9038773bf7ca7dc33484391898f7c Mon Sep 17 00:00:00 2001 From: ShuangYa Date: Wed, 27 May 2026 13:31:28 +0800 Subject: [PATCH 3/7] fix: packer --- package.json | 2 +- pnpm-lock.yaml | 13 ++++++++----- pnpm-workspace.yaml | 2 ++ 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 2f1b21e7..54e15333 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ }, "devDependencies": { "@biomejs/biome": "^2.1.2", - "@fxb/extension-packer": "https://codeload.github.com/FirefoxBar/extension-packer/tar.gz/master", + "@fxb/extension-packer": "github:FirefoxBar/extension-packer", "@modern-js/tsconfig": "^2.68.5", "@rsbuild/core": "^1.4.11", "@rsbuild/plugin-react": "^1.3.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b6fa3355..90d087ba 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,6 +4,9 @@ settings: autoInstallPeers: false excludeLinksFromLockfile: false +overrides: + '@fxb/extension-packer': https://github.com/FirefoxBar/extension-packer.git + patchedDependencies: lodash: a9e8e63b9137cb9b2a30f2548a31b8fe8ed02dbff524f5c3b3817d3fb5c377af lodash-es: 87739c1de481c0b0069b3c5cfcc3a63a3080e12ad9027e4cfb44f04521d3c4d7 @@ -65,8 +68,8 @@ importers: specifier: ^2.1.2 version: 2.1.2 '@fxb/extension-packer': - specifier: https://codeload.github.com/FirefoxBar/extension-packer/tar.gz/master - version: https://codeload.github.com/FirefoxBar/extension-packer/tar.gz/master + specifier: github:FirefoxBar/extension-packer + version: https://codeload.github.com/FirefoxBar/extension-packer/tar.gz/d8d04c82b35f654f0a357d3f05a4d7f45d5aed71 '@modern-js/tsconfig': specifier: ^2.68.5 version: 2.68.5 @@ -394,8 +397,8 @@ packages: resolution: {integrity: sha512-PyUXQWB42s4jBli435TDiYuVsadwRHnMc27YaLouINktvTWsL3FcKrRMGawTayFk46X+n5bE23RjUTWQwrukWw==} engines: {node: '>= 0.10.0'} - '@fxb/extension-packer@https://codeload.github.com/FirefoxBar/extension-packer/tar.gz/master': - resolution: {gitHosted: true, integrity: sha512-RlsOjZiz9TGSQdZitpJ2BbDrXesAioeSFFNShkQm0J1sheexTCtjTr5jzCrdQ+xLDHPHxZ5idps11ac3TmF/EQ==, tarball: https://codeload.github.com/FirefoxBar/extension-packer/tar.gz/master} + '@fxb/extension-packer@https://codeload.github.com/FirefoxBar/extension-packer/tar.gz/d8d04c82b35f654f0a357d3f05a4d7f45d5aed71': + resolution: {gitHosted: true, integrity: sha512-Llmh1K6moglYG4kivi59/xzeDF9e3wUqzPo5dLaGDKFznLs1yRB/XPA/WeU0bcpEsEc2pAKv8OHswDy1Tz3Pzg==, tarball: https://codeload.github.com/FirefoxBar/extension-packer/tar.gz/d8d04c82b35f654f0a357d3f05a4d7f45d5aed71} version: 1.0.0 engines: {node: '>=20', pnpm: '>=10'} @@ -3755,7 +3758,7 @@ snapshots: '@fregante/relaxed-json@2.0.0': {} - '@fxb/extension-packer@https://codeload.github.com/FirefoxBar/extension-packer/tar.gz/master': + '@fxb/extension-packer@https://codeload.github.com/FirefoxBar/extension-packer/tar.gz/d8d04c82b35f654f0a357d3f05a4d7f45d5aed71': dependencies: '@plasmohq/chrome-webstore-api': 2.11.0 '@plasmohq/edge-addons-api': 2.0.0 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 1444e645..136fce59 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -7,3 +7,5 @@ allowBuilds: patchedDependencies: lodash: patches/lodash.patch lodash-es: patches/lodash-es.patch +overrides: + '@fxb/extension-packer': https://github.com/FirefoxBar/extension-packer.git From ceb0fde268aebf832ae57ef26168821c1a48ca79 Mon Sep 17 00:00:00 2001 From: ShuangYa Date: Wed, 27 May 2026 13:33:59 +0800 Subject: [PATCH 4/7] fix: packer --- package.json | 2 +- pnpm-lock.yaml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 54e15333..5fcd7f65 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ }, "devDependencies": { "@biomejs/biome": "^2.1.2", - "@fxb/extension-packer": "github:FirefoxBar/extension-packer", + "@fxb/extension-packer": "*", "@modern-js/tsconfig": "^2.68.5", "@rsbuild/core": "^1.4.11", "@rsbuild/plugin-react": "^1.3.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 90d087ba..74d67443 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -68,7 +68,7 @@ importers: specifier: ^2.1.2 version: 2.1.2 '@fxb/extension-packer': - specifier: github:FirefoxBar/extension-packer + specifier: https://github.com/FirefoxBar/extension-packer.git version: https://codeload.github.com/FirefoxBar/extension-packer/tar.gz/d8d04c82b35f654f0a357d3f05a4d7f45d5aed71 '@modern-js/tsconfig': specifier: ^2.68.5 @@ -398,7 +398,7 @@ packages: engines: {node: '>= 0.10.0'} '@fxb/extension-packer@https://codeload.github.com/FirefoxBar/extension-packer/tar.gz/d8d04c82b35f654f0a357d3f05a4d7f45d5aed71': - resolution: {gitHosted: true, integrity: sha512-Llmh1K6moglYG4kivi59/xzeDF9e3wUqzPo5dLaGDKFznLs1yRB/XPA/WeU0bcpEsEc2pAKv8OHswDy1Tz3Pzg==, tarball: https://codeload.github.com/FirefoxBar/extension-packer/tar.gz/d8d04c82b35f654f0a357d3f05a4d7f45d5aed71} + resolution: {gitHosted: true, tarball: https://codeload.github.com/FirefoxBar/extension-packer/tar.gz/d8d04c82b35f654f0a357d3f05a4d7f45d5aed71} version: 1.0.0 engines: {node: '>=20', pnpm: '>=10'} From fde3d13ee13ee10022d46f826db5d32cacdcfd29 Mon Sep 17 00:00:00 2001 From: ShuangYa Date: Wed, 27 May 2026 13:36:28 +0800 Subject: [PATCH 5/7] fix: pack --- scripts/config.mjs | 1 + scripts/pack.mjs | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/scripts/config.mjs b/scripts/config.mjs index 1ba99655..3a17710d 100644 --- a/scripts/config.mjs +++ b/scripts/config.mjs @@ -18,6 +18,7 @@ async function getVersion(path) { return manifest.version; } +export const temp = join(root, 'temp'); export const releasePath = join(temp, 'release'); export const scriptRoot = __dirname; export { extension, getDistPath, getDistDir, getOutputFile, getVersion }; diff --git a/scripts/pack.mjs b/scripts/pack.mjs index b261f2bd..bd8caf04 100644 --- a/scripts/pack.mjs +++ b/scripts/pack.mjs @@ -1,7 +1,13 @@ import { join } from 'node:path'; import { getVersion, pack } from '@fxb/extension-packer'; import getManifest from './browser-config/get-manifest.js'; -import { getDistPath, getOutputFile, releasePath, root } from './config.mjs'; +import { + getDistPath, + getOutputFile, + releasePath, + root, + temp, +} from './config.mjs'; import { getNote } from './utils.mjs'; const fileExt = { @@ -52,7 +58,7 @@ async function main() { await pack( { - tempPath: join(root, 'pack-temp'), + tempPath: join(temp, 'pack'), rootPath: root, releasePath, browserConfig, From 76d895dc9966cb0e26aa318c626a871df938a591 Mon Sep 17 00:00:00 2001 From: ShuangYa Date: Wed, 27 May 2026 13:43:07 +0800 Subject: [PATCH 6/7] chore: remove axios --- locale/create-pr.js | 47 +++++++++++++++++-------------------- tests/e2e/scripts/utils.mjs | 7 ++---- 2 files changed, 23 insertions(+), 31 deletions(-) diff --git a/locale/create-pr.js b/locale/create-pr.js index cc52593f..72a664e7 100644 --- a/locale/create-pr.js +++ b/locale/create-pr.js @@ -1,17 +1,11 @@ -const axios = require('axios'); +const baseURL = `${process.env.GITHUB_API_URL}/repos/${process.env.GITHUB_REPOSITORY}`; -const token = process.env.GITHUB_TOKEN; - -const baseURL = - process.env.GITHUB_API_URL + '/repos/' + process.env.GITHUB_REPOSITORY; -const request = axios.create({ - baseURL: baseURL, - validateStatus: () => true, -}); - -request.defaults.headers.common['Accept'] = 'application/vnd.github+json'; -request.defaults.headers.common['Authorization'] = 'Bearer ' + token; -request.defaults.headers.common['X-GitHub-Api-Version'] = '2022-11-28'; +const apiHeader = { + Accept: 'application/vnd.github+json', + Authorization: `Bearer ${process.env.GITHUB_TOKEN}`, + 'X-GitHub-Api-Version': '2022-11-28', + 'Content-Type': 'application/json', +}; async function main() { if (!token) { @@ -21,34 +15,35 @@ async function main() { console.log('baseURL: ' + baseURL); - const pulls = await request.get('/pulls', { - params: { - state: 'open', - head: 'dev-locale', - base: 'dev', + const pulls = await fetch( + `${baseURL}/pulls?state=open&head=dev-locale&base=dev`, + { + headers: apiHeader, }, - }); + ); - if (pulls.data.length > 0) { + const data = await pulls.json(); + if (data.length > 0) { // already has PR - const item = pulls.data[0]; + const item = data[0]; console.log('PR already exists: ' + item.html_url); return; } // Create new PR - const create = await request.post( - '/pulls', - JSON.stringify({ + const create = await fetch(`${baseURL}/pulls`, { + method: 'POST', + body: JSON.stringify({ title: 'locale: update locales', body: '', head: 'dev-locale', base: 'dev', }), - ); + headers: apiHeader, + }); if (create.status === 201) { - console.log('PR created: ' + create.data.html_url); + console.log(`PR created: ${(await create.json()).html_url}`); } else { console.log('PR created failed: ' + create.status); } diff --git a/tests/e2e/scripts/utils.mjs b/tests/e2e/scripts/utils.mjs index 7b1666dd..f6a68666 100644 --- a/tests/e2e/scripts/utils.mjs +++ b/tests/e2e/scripts/utils.mjs @@ -4,7 +4,6 @@ import path from 'node:path'; import { setTimeout as sleep } from 'node:timers/promises'; import { fileURLToPath } from 'node:url'; import { promisify } from 'node:util'; -import axios from 'axios'; import getPort from 'get-port'; import puppeteer from 'puppeteer'; import resolve from 'resolve'; @@ -208,10 +207,8 @@ export async function waitTestServer() { // Check if test server is running while (true) { try { - const res = await axios.get(`${testServer}health-check.php`, { - timeout: 5000, - }); - if (String(res.data).includes('It works!')) { + const res = await fetch(`${testServer}health-check.php`); + if (String(await res.text()).includes('It works!')) { break; } // Sleep 1 second From a5c86c5cfeee0cc7f49d8cb06fea16233aaf7e0a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 27 May 2026 05:45:01 +0000 Subject: [PATCH 7/7] [skip ci] sync locale --- public/_locales/zh_TW/messages.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/_locales/zh_TW/messages.json b/public/_locales/zh_TW/messages.json index 16d4a461..c10e6453 100644 --- a/public/_locales/zh_TW/messages.json +++ b/public/_locales/zh_TW/messages.json @@ -1 +1 @@ -{"action":{"message":"動作"},"add":{"message":"新增"},"all_rules":{"message":"所有規則"},"auto":{"message":"自動"},"auto_enable_modify_body":{"message":"已自動開啟「變更回應本文」,如不需要請手動關閉"},"basic_information":{"message":"基本資訊"},"batch_delete":{"message":"批次刪除"},"batch_mode":{"message":"批次作業"},"browser_version":{"message":"瀏覽器版本"},"cancel":{"message":"取消"},"check_update":{"message":"檢查更新"},"choose":{"message":"選擇"},"clone":{"message":"複製"},"cloud_backup":{"message":"雲端備份"},"cloud_backup_at":{"message":"最後備份於 $date$","placeholders":{"date":{"content":"$1"}}},"cloud_no_backup":{"message":"無備份"},"cloud_over_limit":{"message":"超出備份大小限制"},"code":{"message":"代碼"},"code_empty":{"message":"代碼不能為空"},"common_mark":{"message":"設為常用"},"common_mark_tip":{"message":"將任意規則或分組設為常用後,會在此處顯示"},"common_unmark":{"message":"取消常用"},"dark_mode":{"message":"深色模式"},"dark_mode_help":{"message":"深色模式為實驗性功能,重新整理頁面以確認效果"},"debug_mode_enable":{"message":"啟用偵錯模式"},"debug_mode_enable_help":{"message":"開啟「偵錯模式」後,將於背景頁面輸出執行記錄"},"delete":{"message":"刪除"},"delete_confirm":{"message":"您確定要刪除這些規則嗎?"},"description":{"message":"管理瀏覽器要求"},"disable":{"message":"停用"},"display_common_header":{"message":"編輯時顯示常用標頭"},"display_common_header_help":{"message":"在編輯規則時,顯示常用的要求標頭和回應標頭"},"download":{"message":"下載"},"download_rule":{"message":"下載規則"},"edit":{"message":"編輯"},"enable":{"message":"啟用"},"enable_he":{"message":"啟用 Header Editor"},"encoding":{"message":"編碼"},"encoding_desc":{"message":"僅用於解碼"},"enter_group_name":{"message":"請輸入分組名稱"},"env_info":{"message":"環境資訊"},"excludeRule":{"message":"排除規則"},"exec_function":{"message":"自訂函數"},"exec_normal":{"message":"一般"},"exec_type":{"message":"執行類型"},"execution":{"message":"執行"},"export":{"message":"匯出"},"export_and_import":{"message":"匯出與匯入"},"extButtonTitle":{"message":"Header Editor"},"extName":{"message":"Header Editor"},"ext_version":{"message":"套件版本"},"feedback":{"message":"意見反應"},"group":{"message":"分組"},"headerName":{"message":"標頭名稱"},"headerValue":{"message":"標頭內容"},"header_empty":{"message":"標頭名稱不能為空"},"help":{"message":"說明"},"import":{"message":"匯入"},"import_drop":{"message":"不要匯入"},"import_new":{"message":"新增"},"import_override":{"message":"覆寫現有"},"import_success":{"message":"匯入成功"},"include_header_in_custom_function":{"message":"在自訂函數中包含要求標頭"},"include_header_in_custom_function_help":{"message":"向處理回應標頭的自訂函數中傳入要求標頭,開啟後可能會降低性能"},"init_rule_failed":{"message":"初始化規則失敗"},"lite_edit_tip":{"message":"精簡版不支援某些功能"},"lite_not_support":{"message":"精簡版不支援此功能"},"manage":{"message":"管理"},"manage_collapse_group":{"message":"預設摺疊分組"},"marked_as_common":{"message":"已設為常用"},"matchRule":{"message":"比對規則"},"matchType":{"message":"比對類型"},"match_all":{"message":"全部"},"match_domain":{"message":"網域"},"match_method":{"message":"要求方法"},"match_prefix":{"message":"網址首碼"},"match_regexp":{"message":"規則運算式"},"match_resourceType":{"message":"資源類型"},"match_rule_empty":{"message":"比對規則不能為空"},"match_url":{"message":"網址"},"modify_body":{"message":"修改回應本文"},"modify_body_help":{"message":"允許變更回應本文,開啟後可能會降低性能"},"more_information":{"message":"詳細資訊"},"name":{"message":"名稱"},"name_empty":{"message":"名稱不能為空"},"no_update":{"message":"沒有更新"},"ok":{"message":"確定"},"options":{"message":"選項"},"pack_up_or_unfurl":{"message":"摺疊/展開分組"},"quick_edit":{"message":"快速編輯"},"quick_edit_help":{"message":"在彈出式視窗中顯示編輯按鈕"},"redirectTo":{"message":"重新導向至"},"redirect_empty":{"message":"重新導向目標不能為空"},"rename":{"message":"重新命名"},"request_headers":{"message":"要求標頭"},"request_stage":{"message":"要求階段"},"resourceType_csp_report":{"message":"CSP 報告(在 Content-Security-Policy 標頭中設定)"},"resourceType_font":{"message":"字型"},"resourceType_image":{"message":"圖片"},"resourceType_main_frame":{"message":"主框架(在分頁中載入的網頁)"},"resourceType_media":{"message":"媒體(影片和音訊)"},"resourceType_object":{"message":"物件(透過分頁載入)"},"resourceType_other":{"message":"其他"},"resourceType_ping":{"message":"Ping(在超連結的 ping 屬性設定)"},"resourceType_script":{"message":"指令碼"},"resourceType_stylesheet":{"message":"CSS 樣式"},"resourceType_sub_frame":{"message":"子框架(在