2022-11-04 16:11:33 +00:00
import fs from "fs/promises" ;
import { createRequire } from "module" ;
import tempDir from "temp-dir" ;
import { signAddon } from "sign-addon" ;
2023-02-27 01:23:26 +00:00
import { Client as AMOClient } from "sign-addon/lib/amo-client.js" ;
2021-03-09 19:11:46 +00:00
async function sign (
apiKey ,
apiSecret ,
extensionId ,
unsignedPath ,
version ,
2023-02-27 01:23:26 +00:00
destination ,
sourcePath
2021-03-09 19:11:46 +00:00
) {
const result = await signAddon ( {
xpiPath : unsignedPath ,
version ,
apiKey ,
apiSecret ,
id : extensionId ,
downloadDir : tempDir ,
} ) ;
2023-03-03 04:01:46 +00:00
//Since sign-addon doesn't support source upload, let's make the request
2023-03-10 22:56:32 +00:00
//ourselves. We aren't actually using any API methods on AMOClient, just
//the authentication mechanism, so this should be safe.
2023-03-03 04:01:46 +00:00
const client = new AMOClient ( {
apiKey ,
apiSecret ,
apiUrlPrefix : "https://addons.mozilla.org/api/v5" ,
downloadDir : tempDir ,
} ) ;
2023-02-27 01:23:26 +00:00
2023-03-10 22:56:32 +00:00
//NOTE: The extension ID is already wrapped in curly braces in GitHub
var sourceCodeUpload = client . patch ( {
url : ` /addons/addon/ ${ encodeURIComponent (
extensionId
) } / versions / $ { encodeURIComponent ( version ) } / ` ,
formData : {
2023-03-11 00:54:29 +00:00
source : fs . createReadStream ( sourcePath ) ,
2023-03-10 22:56:32 +00:00
} ,
} ) ;
2023-02-27 01:23:26 +00:00
2023-03-10 22:56:32 +00:00
const build _date = new Date ( ) . toISOString ( ) ;
2023-02-27 01:23:26 +00:00
2023-03-10 22:56:32 +00:00
var notesUpload = client . patch ( {
url : ` /addons/addon/ ${ encodeURIComponent (
extensionId
) } / versions / $ { encodeURIComponent ( version ) } / ` ,
json : {
approval _notes : ` This version was derived from the source code available at https://github.com/ruffle-rs/ruffle/releases/tag/nightly- ${ build _date . substr (
0 ,
10
) } - a ZIP file from this Git tag has been attached . If you download it yourself instead of using the ZIP file provided , make sure to grab the reproducible version of the ZIP , as it contains versioning information that will not be present on the main source download . \ n \
2023-02-27 01:23:26 +00:00
\ n \
We highly recommend using the Docker build workflow . You can invoke it using the following three commands : \ n \
\ n \
rm - rf web / docker / docker _builds / * \ n \
docker build -- tag ruffle - web - docker - f web / docker / Dockerfile . \ n \
docker cp $ ( docker create ruffle - web - docker : latest ) : / r u f f l e / w e b / p a c k a g e s w e b / d o c k e r / d o c k e r _ b u i l d s / p a c k a g e s \ n \
\ n \
These commands are run at the root of the project . The compiled XPI will be in web / docker / docker _builds / packages / extension / dist / firefox _unsigned . xpi . Please take care to use this file ( and not the surrounding packages directory ) when comparing against the extension submission . \ n \
\ n \
Alternatively , you may also attempt building using npm and cargo . However , this workflow is more complicated to set up . It is documented here : \ n \
https : //github.com/ruffle-rs/ruffle/blob/master/web/README.md\n\
\ n \
Note that the commands for the npm / cargo workflow are run in the web subdirectory . If you ' re working with the Dockerfile you should be in the root of the project . \ n \
\ n \
The compiled version of this extension was built on Ubuntu 22.04 by our CI runner . \ n \
\ n \
As this is indeed a complicated build process , please let me know if there is anything I can do to assist . ` ,
2023-03-10 22:56:32 +00:00
} ,
} ) ;
2023-03-03 04:01:46 +00:00
2023-03-10 22:56:32 +00:00
try {
await Promise . all ( sourceCodeUpload , notesUpload ) ;
console . log ( "Successfully uploaded source code and approval notes" ) ;
} catch ( e ) {
console . error ( ` Got exception when uploading submission data: ${ e } ` ) ;
2023-02-27 01:23:26 +00:00
}
2021-03-09 19:11:46 +00:00
if ( ! result . success ) {
throw result ;
}
if ( result . downloadedFiles . length === 1 ) {
2021-04-16 03:25:10 +00:00
// Copy the downloaded file to the destination.
// (Avoid `rename` because it fails if the destination is on a different drive.)
2022-11-04 16:11:33 +00:00
await fs . copyFile ( result . downloadedFiles [ 0 ] , destination ) ;
await fs . unlink ( result . downloadedFiles [ 0 ] ) ;
2021-03-09 19:11:46 +00:00
} else {
console . warn (
"Unexpected downloads for signed Firefox extension, expected 1."
) ;
console . warn ( result ) ;
}
}
2022-11-04 16:11:33 +00:00
try {
2021-03-09 19:11:46 +00:00
if (
process . env . MOZILLA _API _KEY &&
process . env . MOZILLA _API _SECRET &&
process . env . FIREFOX _EXTENSION _ID
) {
2022-11-04 16:11:33 +00:00
// TODO: Import as a JSON module once it becomes stable.
const require = createRequire ( import . meta . url ) ;
2021-04-15 19:29:17 +00:00
const { version } = require ( "../assets/manifest.json" ) ;
2021-03-09 19:11:46 +00:00
await sign (
process . env . MOZILLA _API _KEY ,
process . env . MOZILLA _API _SECRET ,
process . env . FIREFOX _EXTENSION _ID ,
process . argv [ 2 ] ,
version ,
2023-02-27 01:23:26 +00:00
process . argv [ 3 ] ,
process . argv [ 4 ]
2021-03-09 19:11:46 +00:00
) ;
} else {
console . log (
"Skipping signing of Firefox extension. To enable this, please provide MOZILLA_API_KEY, MOZILLA_API_SECRET and FIREFOX_EXTENSION_ID environment variables"
) ;
}
2022-11-04 16:11:33 +00:00
} catch ( error ) {
2021-04-16 03:26:49 +00:00
console . error ( "Error while signing Firefox extension:" ) ;
console . error ( error ) ;
process . exit ( - 1 ) ;
2022-11-04 16:11:33 +00:00
}