diff --git a/src/cmd/sign.js b/src/cmd/sign.js index 25c20b96c3..1e1108f26e 100644 --- a/src/cmd/sign.js +++ b/src/cmd/sign.js @@ -33,6 +33,7 @@ export default function sign( channel, amoMetadata, uploadSourceCode, + onlyHumanReadableSourceCode, webextVersion, }, { @@ -43,6 +44,20 @@ export default function sign( } = {}, ) { return withTempDir(async function (tmpDir) { + if (!uploadSourceCode && !onlyHumanReadableSourceCode) { + throw new UsageError( + 'Incomplete command. Either --upload-source-code or --only-human-readable-source-code ' + + 'CLI options should be explicitly included in the sign command.' + ); + } + + if (uploadSourceCode && onlyHumanReadableSourceCode) { + throw new UsageError( + 'Invalid options. Only one of --upload-source-code or --only-human-readable-source-code ' + + 'CLI options should be included in the sign command.' + ); + } + await prepareArtifactsDir(artifactsDir); let manifestData; diff --git a/src/program.js b/src/program.js index 35d794a912..a5dbb9a3a2 100644 --- a/src/program.js +++ b/src/program.js @@ -582,10 +582,22 @@ Example: $0 --help run. describe: 'Path to an archive file containing human readable source code of this submission, ' + 'if the code in --source-dir has been processed to make it unreadable. ' + + 'Use --only-human-readable-source-code option if source code assets ' + + 'in the submission are all human readable.' + 'See https://extensionworkshop.com/documentation/publish/source-code-submission/ for ' + - 'details. Only used with `use-submission-api`', + 'details.', type: 'string', }, + 'only-human-readable-source-code': { + describe: + 'Signal that all source code assets in the xpi file are already human readable ' + + 'and uploading a separate source code archive is not necessary.' + + 'See https://extensionworkshop.com/documentation/publish/source-code-submission/ for ' + + 'details.', + type: 'boolean', + demandOption: false, + default: null, + }, }, ) .command('run', 'Run the extension', commands.run, { diff --git a/tests/functional/test.cli.sign.js b/tests/functional/test.cli.sign.js index 6db035e984..5eada29d5c 100644 --- a/tests/functional/test.cli.sign.js +++ b/tests/functional/test.cli.sign.js @@ -60,6 +60,7 @@ describe('web-ext sign', () => { '--verbose', '--channel', 'listed', + '--only-human-readable-source-code', '--amo-base-url', 'http://localhost:8989/fake/api/v5', '--api-key', @@ -97,6 +98,7 @@ describe('web-ext sign', () => { sign: { amoBaseUrl: 'http://localhost:8989/fake/api/v5', channel: 'listed', + onlyHumanReadableSourceCode: true, }, sourceDir: srcDir, }, diff --git a/tests/unit/test-cmd/test.sign.js b/tests/unit/test-cmd/test.sign.js index 372d6593d0..1b2ad854ab 100644 --- a/tests/unit/test-cmd/test.sign.js +++ b/tests/unit/test-cmd/test.sign.js @@ -57,15 +57,22 @@ describe('sign', () => { * Run the sign command with stubs for all dependencies. */ function sign(tmpDir, stubs, { extraArgs = {}, extraOptions = {} } = {}) { + const signCLIOptions = { + verbose: false, + artifactsDir: path.join(tmpDir.path(), 'artifacts-dir'), + sourceDir: tmpDir.path(), + channel: 'listed', + ...stubs.signingConfig, + ...extraArgs, + }; + if ( + !('uploadSourceCode' in signCLIOptions) && + !('onlyHumanReadableSourceCode' in signCLIOptions) + ) { + signCLIOptions.onlyHumanReadableSourceCode = true; + } return completeSignCommand( - { - verbose: false, - artifactsDir: path.join(tmpDir.path(), 'artifacts-dir'), - sourceDir: tmpDir.path(), - channel: 'listed', - ...stubs.signingConfig, - ...extraArgs, - }, + signCLIOptions, { ...stubs.signingOptions, ...extraOptions, @@ -89,6 +96,7 @@ describe('sign', () => { sourceDir, artifactsDir: path.join(tmpDir.path(), 'artifacts'), channel: 'listed', + onlyHumanReadableSourceCode: true, ...stubs.signingConfig, apiProxy, }, @@ -223,6 +231,21 @@ describe('sign', () => { }); })); + it('rejects an UsageError if --upload-source-code or --only-human-readable-source-code are both falsey', async () => { + const signPromise = completeSignCommand({}); + await assert.isRejected(signPromise, UsageError); + await assert.isRejected(signPromise, /Incomplete command. Either .* CLI options should be explicitly included/); + }); + + it('rejects an UsageError if --upload-source-code and --only-human-readable-source-code are both truthy', async () => { + const signPromise = completeSignCommand({ + uploadSourceCode: 'fake-source-code-path.zip', + onlyHumanReadableSourceCode: true, + }); + await assert.isRejected(signPromise, UsageError); + await assert.isRejected(signPromise, /Invalid options. Only one of .* CLI options should be included/); + }); + it('passes the uploadSourceCode parameter to submissionAPI signer as submissionSource', () => withTempDir((tmpDir) => { const stubs = getStubs();