Skip to content

Commit daa1c82

Browse files
committed
Add Firefox metadata recovery workflow
1 parent 52881b5 commit daa1c82

4 files changed

Lines changed: 181 additions & 0 deletions

File tree

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: Firefox metadata
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
version:
7+
description: "Firefox version to update, for example 2.6.1"
8+
required: true
9+
type: string
10+
11+
permissions:
12+
contents: read
13+
14+
jobs:
15+
update-firefox-metadata:
16+
runs-on: ubuntu-latest
17+
steps:
18+
- name: Checkout
19+
uses: actions/checkout@v6
20+
21+
- name: Setup Node.js
22+
uses: actions/setup-node@v6
23+
with:
24+
node-version: 22
25+
26+
- name: Install dependencies
27+
run: npm ci
28+
29+
- name: Update Firefox metadata
30+
run: npm run release:update-firefox-metadata -- --version "${{ inputs.version }}"
31+
env:
32+
FIREFOX_EXTENSION_ID: ${{ secrets.FIREFOX_EXTENSION_ID }}
33+
FIREFOX_JWT_ISSUER: ${{ secrets.FIREFOX_JWT_ISSUER }}
34+
FIREFOX_JWT_SECRET: ${{ secrets.FIREFOX_JWT_SECRET }}

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"release:firefox-sources": "node scripts/create-firefox-sources-zip.mjs",
2121
"release:submit": "node scripts/submit-stores.mjs",
2222
"release:submit:dry-run": "node scripts/submit-stores.mjs --dry-run",
23+
"release:update-firefox-metadata": "node scripts/update-firefox-metadata.mjs",
2324
"release:check-edge-api-key": "node scripts/check-edge-api-key-expiry.mjs"
2425
},
2526
"pre-commit": [
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/* global process */
2+
3+
import path from 'node:path'
4+
import { fileURLToPath } from 'node:url'
5+
import { updateFirefoxVersionNotes } from './submit-stores.mjs'
6+
7+
const REQUIRED_FIREFOX_METADATA_ENV = [
8+
'FIREFOX_EXTENSION_ID',
9+
'FIREFOX_JWT_ISSUER',
10+
'FIREFOX_JWT_SECRET',
11+
]
12+
13+
export function parseFirefoxMetadataArgs(args) {
14+
let version = ''
15+
16+
for (let index = 0; index < args.length; index += 1) {
17+
const arg = args[index]
18+
if (arg === '--version') {
19+
version = args[index + 1] || ''
20+
index += 1
21+
} else if (arg.startsWith('--version=')) {
22+
version = arg.slice('--version='.length)
23+
}
24+
}
25+
26+
return { version }
27+
}
28+
29+
export function findMissingFirefoxMetadataEnv(env = process.env) {
30+
return REQUIRED_FIREFOX_METADATA_ENV.filter((name) => !env[name])
31+
}
32+
33+
export async function updateFirefoxMetadata({
34+
argv = process.argv.slice(2),
35+
env = process.env,
36+
updateImpl = updateFirefoxVersionNotes,
37+
logger = console.log,
38+
} = {}) {
39+
const { version } = parseFirefoxMetadataArgs(argv)
40+
if (!version) {
41+
throw new Error(
42+
'Missing Firefox metadata version. Use --version <version>, for example --version 2.6.1',
43+
)
44+
}
45+
46+
const missingEnv = findMissingFirefoxMetadataEnv(env)
47+
if (missingEnv.length > 0) {
48+
throw new Error(`Missing Firefox metadata environment variables: ${missingEnv.join(', ')}`)
49+
}
50+
51+
logger(`Updating Firefox metadata for ChatGPTBox ${version}`)
52+
await updateImpl({
53+
extensionId: env.FIREFOX_EXTENSION_ID,
54+
version,
55+
jwtIssuer: env.FIREFOX_JWT_ISSUER,
56+
jwtSecret: env.FIREFOX_JWT_SECRET,
57+
})
58+
}
59+
60+
const currentFile = fileURLToPath(import.meta.url)
61+
if (process.argv[1] && path.resolve(process.argv[1]) === currentFile) {
62+
updateFirefoxMetadata().catch((error) => {
63+
console.error(error)
64+
process.exit(1)
65+
})
66+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import assert from 'node:assert/strict'
2+
import test from 'node:test'
3+
import {
4+
findMissingFirefoxMetadataEnv,
5+
parseFirefoxMetadataArgs,
6+
updateFirefoxMetadata,
7+
} from '../../../scripts/update-firefox-metadata.mjs'
8+
9+
test('parseFirefoxMetadataArgs reads the target version', () => {
10+
assert.deepEqual(parseFirefoxMetadataArgs(['--version', '2.6.1']), { version: '2.6.1' })
11+
assert.deepEqual(parseFirefoxMetadataArgs(['--version=2.6.1']), { version: '2.6.1' })
12+
})
13+
14+
test('findMissingFirefoxMetadataEnv reports required Firefox secrets only', () => {
15+
assert.deepEqual(findMissingFirefoxMetadataEnv({}), [
16+
'FIREFOX_EXTENSION_ID',
17+
'FIREFOX_JWT_ISSUER',
18+
'FIREFOX_JWT_SECRET',
19+
])
20+
21+
assert.deepEqual(
22+
findMissingFirefoxMetadataEnv({
23+
FIREFOX_EXTENSION_ID: 'chatgptbox',
24+
FIREFOX_JWT_ISSUER: 'issuer',
25+
FIREFOX_JWT_SECRET: 'secret',
26+
}),
27+
[],
28+
)
29+
})
30+
31+
test('updateFirefoxMetadata patches the requested Firefox version only', async () => {
32+
const calls = []
33+
34+
await updateFirefoxMetadata({
35+
argv: ['--version', '2.6.1'],
36+
env: {
37+
FIREFOX_EXTENSION_ID: 'chatgptbox',
38+
FIREFOX_JWT_ISSUER: 'issuer',
39+
FIREFOX_JWT_SECRET: 'secret',
40+
},
41+
updateImpl: async (params) => {
42+
calls.push(params)
43+
},
44+
logger: () => {},
45+
})
46+
47+
assert.equal(calls.length, 1)
48+
assert.deepEqual(calls[0], {
49+
extensionId: 'chatgptbox',
50+
version: '2.6.1',
51+
jwtIssuer: 'issuer',
52+
jwtSecret: 'secret',
53+
})
54+
})
55+
56+
test('updateFirefoxMetadata fails before patching when version or secrets are missing', async () => {
57+
await assert.rejects(
58+
updateFirefoxMetadata({
59+
argv: [],
60+
env: {},
61+
updateImpl: async () => {
62+
throw new Error('should not patch')
63+
},
64+
logger: () => {},
65+
}),
66+
/Missing Firefox metadata version/,
67+
)
68+
69+
await assert.rejects(
70+
updateFirefoxMetadata({
71+
argv: ['--version', '2.6.1'],
72+
env: {},
73+
updateImpl: async () => {
74+
throw new Error('should not patch')
75+
},
76+
logger: () => {},
77+
}),
78+
/Missing Firefox metadata environment variables/,
79+
)
80+
})

0 commit comments

Comments
 (0)