Automate Firefox Addon Publishing
If you’re like me, you always want to speed up aspects of your life especially routine tasks. I’ll be doing this in Python but you can easily convert the code to a language of your choice.
Prerequisites
We’re going to be using the Firefox Add-ons API to upload your add-on so you will need some API keys. You can get your API keys from here. Enter the pair of API keys into a .env
file like so:
jwt-issuer=string
jwt-secret=string
Third Party Libraries
After you do that, you will need to install some necessary modules (add to requirements.txt
): pip install requests PyJWT
After installing these two modules, copy the snippet at the bottom of the article.
Modifying the Script
GUID
: include the ‘{’ and ‘}’ into the string if applicable
addon_files
: a list of source files of the add-on (relative path)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from glob import glob | |
import io | |
import os | |
import time | |
import uuid | |
from zipfile import ZipFile | |
# third party libraries | |
import jwt # PyJWT | |
import requests | |
# get API keys from https://addons.mozilla.org/developers/addon/api/key/ | |
# and put them into a .env file like so: | |
# jwt-issuer=string | |
# jwt-secret=string | |
GUID = 'GUID GOES HERE' # make sure to include the '{' and '}' if your GUID has it | |
addon_files = ['manifest.json', 'style.css'] + glob('icons/*.png') | |
# read environmental variables | |
with open('.env') as f: | |
line = f.readline() | |
while line: | |
k, v = line.split('=', 1) | |
os.environ[k] = v.strip() | |
line = f.readline() | |
def create_zip(file): | |
""" file: filename or file-type object """ | |
with ZipFile(file, 'w') as zf: | |
for file in addon_files: | |
zf.write(file) | |
def upload(version): | |
# e.g. version = '1.1.1.1' | |
# create auth JWT token | |
jwt_secret = os.environ['jwt-secret'] | |
jwt_issuer = os.environ['jwt-issuer'] | |
jwt_obj = { | |
'iss': jwt_issuer, | |
'jti': str(uuid.uuid4()), | |
'iat': time.time(), | |
'exp': time.time() + 60 | |
} | |
jwt_obj = jwt.encode(jwt_obj, jwt_secret, algorithm='HS256').decode() | |
file = io.BytesIO() | |
create_zip(file) | |
print(f'uploading version {version}') | |
data = {'upload': ('manifest.zip', file.getvalue()), 'channel': 'listed'} | |
headers = {'Authorization': f'JWT {jwt_obj}'} | |
url = f'https://addons.mozilla.org/api/v4/addons/{GUID}/versions/{version}/' | |
r = requests.put(url, data, headers=headers, files=data) | |
print(r.status_code) | |
print(r.json()) |