Confirmed users
656
edits
No edit summary |
|||
| Line 12: | Line 12: | ||
1. Bump the version number in install.rdf. It's not possible to sign the same version twice, so each change requires a version bump. If appropriate, you may want to add a new minor version number (e.g x.y.z). | 1. Bump the version number in install.rdf. It's not possible to sign the same version twice, so each change requires a version bump. If appropriate, you may want to add a new minor version number (e.g x.y.z). | ||
2. Pack the addon into an xpi. An xpi file is simply a renamed zip file. For example, you could use: | 2. If your extension is not generated by the build, skip to step 3. Otherwise, you'll first need to build your extension with `mach build`. After building, cd to the final extension directory (usually in $OBJDIR/dist/xpi-stage). | ||
3. Pack the addon into an xpi. An xpi file is simply a renamed zip file. For example, you could use: | |||
$ zip -r my-addon.xpi . | $ zip -r my-addon.xpi . | ||
4. Sign the addon with jpm and the credentials you obtained from step 1 of the prerequisites: | |||
$ jpm sign --api-key <amo key> --api-secret <amo secret> --xpi <path to xpi> | $ jpm sign --api-key <amo key> --api-secret <amo secret> --xpi <path to xpi> | ||
5. If validation failed, open the link to see what needs to be changed. If it was successful, you should have a new .xpi file in your working directory. If appropriate, move and/or rename this file to whatever the relevant automation is expecting. | |||
6. Add the signed extension to your commit: | |||
$ hg add my-addon-signed.xpi | |||
$ hg commit -m "Bug 1234567 - Update my-addon.xpi" | |||
== Common Footguns == | |||
Here are some problems to watch out for: | |||
* If you or someone else previously bumped an addon's version number to test changes on try, but never actually committed the changes, then simply incrementing that addon's version number by one won't work. You'll need the last signed version, which is not necessarily the last checked in version. | |||
* After an addon is signed by one key, it can't later be signed by a second. So it's important to use the shared automation account. | |||
* Addons with an application id of "toolkit@mozilla.org" don't currently get signed. There is a bug in jpm that makes it seem like the signing worked, but no key files are left behind. To work around this, change the application id to Firefox's uuid. | |||
== How to Avoid Addon Signing == | |||
Signing extensions can potentially be a pretty big pain. But with a bit of effort, that pain can be avoided. | |||
=== Don't use Addons === | |||
The best way to avoid the hassle of addon signing, is to not use addons! Often addons are used as a means of running JavaScript in chrome scope. Many years ago they were the only viable option to do this, but that is no longer the case. There are several tools like [https://developer.mozilla.org/en-US/docs/SpecialPowers specialpowers] or [https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette marionette], that allow chrome privileges to content scopes. So if you find yourself writing an addon simply to execute some chrome JS, do a bit of research and make sure there isn't an easier solution available. | |||
=== Use Temporary Addons === | |||
If you absolutely must use an addon, there is a way to work around signing via temporary addons. Temporary addons have a few limitations: | |||
1. They must be [https://developer.mozilla.org/en-US/Add-ons/Bootstrapped_extensions bootstrapped] | |||
2. They'll get uninstalled on Firefox restart | |||
3. They can't be installed via the profile (you'll need to be able to run chrome JS) | |||
If those restrictions don't bother you, you can use the `[https://dxr.mozilla.org/mozilla-central/rev/d848a5628d801a460a7244cbcdea22d328d8b310/toolkit/mozapps/extensions/AddonManager.jsm#2236AddonManager.installTemporaryAddon()]` API to install them. You'll need a way to run chrome privileged JS to install it. Alternatively, there's also a [http://marionette-client.readthedocs.org/en/latest/reference.html#addons marionette API] to install it. For example: | |||
from marionette_driver.addons import Addons | |||
addons = Addons(marionette) | |||
addons.install('path/to/bootstrapped-addon.xpi', temp=True) | |||
If this is an option for you, the short term hassle may be worth the long term benefit of not having to sign. | |||