Post 6 of 9 in "Releasing WebExtension using GitHub Actions" series
In this part we are going to create the workflow that will be responsible for publishing the extension on Firefox Add-ons marketplace.
🧱 Prepare
First, you need to find out your extension UUID. You can find it on your extension’s page at Add-on Developer Hub in the “Technical Details” section.
Next, follow the official documentation and obtain jwtIssuer
and jwtSecret
values required for accessing the API.
🔒 Add these values to secrets:
FF_EXTENSION_ID
- UUID of your extension (e.g.{c23c69a7-f889-447c-9d6b-7694be8035bc}
)FF_JWT_ISSUER
FF_JWT_SECRET
publish-on-firefox-add-ons workflow
The workflow will have the only trigger: workflow_dispatch event. It can be dispatched:
- Manually specifying any branch or tag as workflow ref.
- By publish-release-on-tag workflow after it has prepared a release with zip asset.
We will utilize already created get-zip-asset composite action to obtain packed zip that is needed for deploying the extension.
.github/workflows/publish-on-firefox-add-ons.yml :
name: publish-on-firefox-add-ons
on:
workflow_dispatch:
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: cardinalby/export-env-action@v1
with:
envFile: './.github/workflows/constants.env'
expand: true
- name: Obtain packed zip
uses: ./.github/workflows/actions/get-zip-asset
with:
githubToken: ${{ secrets.GITHUB_TOKEN }}
- name: Deploy to Firefox Addons
id: addonsDeploy
uses: cardinalby/webext-buildtools-firefox-addons-action@v1
continue-on-error: true
with:
zipFilePath: ${{ env.ZIP_FILE_PATH }}
extensionId: ${{ secrets.FF_EXTENSION_ID }}
jwtIssuer: ${{ secrets.FF_JWT_ISSUER }}
jwtSecret: ${{ secrets.FF_JWT_SECRET }}
- name: Abort on upload error
if: |
steps.addonsDeploy.outcome == 'failure' &&
steps.addonsDeploy.outputs.sameVersionAlreadyUploadedError != 'true'
run: exit 1
- As usual, at the beginning of each workflow we check out the repo and export env variables from constants.env file.
- After calling get-zip-asset composite action we expect to have zip file with packed and built extension at
env.ZIP_FILE_PATH
path. - We pass its path along with other required inputs to webext-buildtools-firefox-addons-action action to publish the extension. We use
continue-on-error: true
flag to prevent the step from failing immediately in case of error and validate the result at the following step according to our preferences. - Examining addonsDeploy step outputs we can find out the reason of its failure. If it failed because the version we try to publish is already published, we don’t consider it as error.
Timeout notes
Also, the publishing action can sometimes fail with timeoutError == 'true'
output. It means, the extension was uploaded but the waiting for its processing by Addons server was timed out. I didn’t include a handling of this error to the workflow, but you can:
- Specify longer timeout with
timeoutMs
input of webext-buildtools-firefox-addons-action action. Default timeout is 600000 ms (10 min). - Do not fail the job in the last step if
steps.addonsDeploy.outputs.timeoutError == 'true'
. - Just rerun the workflow after a while in the case of timeout. If the extension has been processed after the first run, the workflow will pass (with
steps.addonsDeploy.outputs.sameVersionAlreadyUploadedError == 'true'
).
Not covered: sources uploading
Tthe topic I didn’t touch in the article for the sake of simplicity is providing sources of the extension for Firefox Add-ons reviewers. In my example sources and packed extension are the same. But any little bit complicated extension will probably have build process including compiling TypeScript, packing css, minifying JS files, etc. In this case Firefox Add-ons requires you to provide source codes separately.
Using webext-buildtools-firefox-addons-action you can do it by specifying sourcesZipFilePath
input pointing to the zip file containing sources. To produce this file you need to add an extra step in the workflow, though.