Skip to content

Commit

Permalink
feat: web-ext sign now supports extensions without explicit IDs
Browse files Browse the repository at this point in the history
  • Loading branch information
kumar303 committed Jul 1, 2016
1 parent 8d3379a commit b0f238a
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 32 deletions.
52 changes: 28 additions & 24 deletions src/cmd/sign.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@
import {signAddon as defaultAddonSigner} from '../util/es6-modules';

import defaultBuilder from './build';
import {InvalidManifest} from '../errors';
import {withTempDir} from '../util/temp-dir';
import getValidatedManifest from '../util/manifest';
import getValidatedManifest, {getManifestId} from '../util/manifest';
import {prepareArtifactsDir} from '../util/artifacts';
import {createLogger} from '../util/logger';

Expand All @@ -13,7 +12,7 @@ const log = createLogger(__filename);

export default function sign(
{verbose, sourceDir, artifactsDir, apiKey, apiSecret,
apiUrlPrefix, timeout}: Object,
apiUrlPrefix, id, timeout}: Object,
{build=defaultBuilder, signAddon=defaultAddonSigner,
preValidatedManifest=null}: Object = {}): Promise {

Expand All @@ -27,15 +26,6 @@ export default function sign(
return getValidatedManifest(sourceDir);
}
})
.then((manifestData) => {
if (!manifestData.applications) {
// TODO: remove this when signing supports manifests
// without IDs: https://github.com/mozilla/web-ext/issues/178
throw new InvalidManifest(
'applications.gecko.id in manifest.json is required for signing');
}
return manifestData;
})
.then((manifestData) => {
return build(
{sourceDir, artifactsDir: tmpDir.path()},
Expand All @@ -44,21 +34,35 @@ export default function sign(
return {buildResult, manifestData};
});
})
.then(({buildResult, manifestData}) => signAddon({
apiKey,
apiSecret,
apiUrlPrefix,
timeout,
verbose,
xpiPath: buildResult.extensionPath,
id: manifestData.applications.gecko.id,
version: manifestData.version,
downloadDir: artifactsDir,
}))
.then(({buildResult, manifestData}) => {
const manifestId = getManifestId(manifestData);
if (id && manifestId) {
log.warn(`Overriding manifest.json ID: ${id}`);
}
if (!id) {
id = manifestId;
}
return signAddon({
apiKey,
apiSecret,
apiUrlPrefix,
timeout,
verbose,
id,
xpiPath: buildResult.extensionPath,
version: manifestData.version,
downloadDir: artifactsDir,
});
})
.then((signingResult) => {
// All information about the downloaded files would have
// already been logged by signAddon().
log.info(signingResult.success ? 'SUCCESS' : 'FAIL');
if (signingResult.success) {
log.info(`Extension ID: ${signingResult.id}`);
log.info('SUCCESS');
} else {
log.info('FAIL');
}
return signingResult;
});
}
Expand Down
7 changes: 7 additions & 0 deletions src/program.js
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,13 @@ Example: $0 --help run.
demand: true,
type: 'string',
},
'id': {
describe:
'A custom ID for the extension. This will override ' +
'any ID declared by manifest.json.',
demand: false,
type: 'string',
},
'timeout' : {
describe: 'Number of milliseconds to wait before giving up',
type: 'number',
Expand Down
74 changes: 66 additions & 8 deletions tests/test-cmd/test.sign.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import {describe, it} from 'mocha';
import {assert} from 'chai';
import sinon from 'sinon';

import {getManifestId} from '../../src/util/manifest';
import {withTempDir} from '../../src/util/temp-dir';
import {basicManifest, manifestWithoutApps} from '../test-util/test.manifest';
import completeSignCommand from '../../src/cmd/sign';
import {onlyInstancesOf, InvalidManifest} from '../../src/errors';
import {makeSureItFails, fixturePath} from '../helpers';


Expand Down Expand Up @@ -84,7 +84,7 @@ describe('sign', () => {
}
));

it('requires an application ID when signing', () => withTempDir(
it('allows an empty application ID when signing', () => withTempDir(
(tmpDir) => {
const stubs = getStubs();
return sign(
Expand All @@ -93,12 +93,55 @@ describe('sign', () => {
preValidatedManifest: manifestWithoutApps,
},
})
.then(makeSureItFails())
.catch(onlyInstancesOf(InvalidManifest, (error) => {
assert.equal(
error.message,
'applications.gecko.id in manifest.json is required for signing');
}));
.then(() => {
assert.equal(stubs.signAddon.called, true);
assert.strictEqual(
stubs.signAddon.firstCall.args[0].id,
getManifestId(manifestWithoutApps));
});
}
));

it('allows a custom ID when no ID in manifest.json', () => withTempDir(
(tmpDir) => {
const customId = 'some-custom-id';
const stubs = getStubs();
return sign(
path.join(tmpDir.path(), 'artifacts-dir'), stubs, {
extraArgs: {
id: customId,
},
extraOptions: {
preValidatedManifest: manifestWithoutApps,
},
})
.then(() => {
assert.equal(stubs.signAddon.called, true);
assert.equal(stubs.signAddon.firstCall.args[0].id,
customId);
});
}
));

it('prefers a custom ID over a manifest.json ID', () => withTempDir(
(tmpDir) => {
const customId = 'some-custom-id';
const stubs = getStubs();
return sign(
path.join(tmpDir.path(), 'artifacts-dir'), stubs, {
extraArgs: {
id: customId,
},
extraOptions: {
// This manifest has an ID in it.
preValidatedManifest: basicManifest,
},
})
.then(() => {
assert.equal(stubs.signAddon.called, true);
assert.equal(stubs.signAddon.firstCall.args[0].id,
customId);
});
}
));

Expand All @@ -112,6 +155,21 @@ describe('sign', () => {
}
));

it('might fail', () => withTempDir(
(tmpDir) => {
return sign(
tmpDir.path(), {
...getStubs(),
signAddon: () => Promise.resolve({
success: false,
}),
})
.then((result) => {
assert.equal(result.success, false);
});
}
));

it('calls the add-on signer', () => withTempDir(
(tmpDir) => {
let stubs = getStubs();
Expand Down

0 comments on commit b0f238a

Please sign in to comment.