Skip to content

Instantly share code, notes, and snippets.

@NiklasGollenstede
Last active May 30, 2021 20:08
Show Gist options
  • Save NiklasGollenstede/87664c7f2822b15f86362388270a16a8 to your computer and use it in GitHub Desktop.
Save NiklasGollenstede/87664c7f2822b15f86362388270a16a8 to your computer and use it in GitHub Desktop.
WebExtension `-dev` channel releases

Configuration to build, sign, and release Firefox extensions on pushes to GitHub.

Please read the README for more information.

# Requirements:
# `npm run build` creates one or more unsigned release `.zip`s in the `build/` dir
# `npm run sign` creates one or more signed `.xpi`/`.crx`s with unique manifest `version` in the `build/` dir
branches: { only: [ master ] } # build only on master
skip_non_tags: false # build on every commit push (or manually)
skip_tags: true # (commits create tags, so) don't build on tags
# appveyor automatically skips commits with `[skip ci]` in the message (title)
image:
- Ubuntu
environment:
AMO_JWT_ISSUER: "user:11844708:244" # generate at https://addons.mozilla.org/developers/addon/api/key/
AMO_JWT_SECRET: # encrypt the secret with https://ci.appveyor.com/tools/encrypt
secure: qK0cmL39oH20zxiczXoa9W/xovxGLKXDx/bgBGBfTSJ3mqw/smXs3nE1eHGaOpwgVb3yn1/d76USsqFD0+2K70ZIp1OpHNrs4pjw9oaIc2g=
clone_depth: 1 # git
install:
# cwd = /home/appveyor/projects/${repo}
- if [ "$APPVEYOR_SSH_KEY" ] ; then curl -sflL 'https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-ssh.sh' | bash -e - ; fi
# read version from package.json
- export package_version=$(node -p '(JSON.parse(require("fs").readFileSync("./package.json")).version || "")')
- export manifest_version=$package_version\b$APPVEYOR_BUILD_NUMBER # the same version that npm sign will create
- appveyor UpdateBuild -Version $manifest_version
- nvm use 14
#
# build
- mkdir ../artifacts
- if [ -e package-lock.json ] ; then npm ci ; else npm install ; fi
- npm run build # create an unsigned potential release version
- mv build/*.zip ../artifacts # move to ../artifacts for optional manual publish
- rm -rf build
- npm run sign # create `-dev`-channel beta build, uses $APPVEYOR_BUILD_NUMBER for version
- mv build/*.xpi ../artifacts # move to ../artifacts for GitHub release
#
# invalidate current automatic update manifest, see https://gist.github.com/NiklasGollenstede/60aa2dc957f985eff2b7a2655ea1092b
- export update_url=$(node -p '(JSON.parse(require("fs").readFileSync("./build/firefox/manifest.json")).applications.gecko.update_url || "")')
- wget --method=DELETE -qO- $update_url || echo 'Failed to reset update URL'
- mkdir artifacts && mv ../artifacts/* artifacts
build: off
# these can be downloaded (publically) from appveyor and are available for deployment
artifacts:
- path: artifacts/*
deploy:
release: v$(manifest_version)
description: build v$(manifest_version)
provider: GitHub
auth_token: # token with `public_repo` access. Create at https://github.com/settings/tokens then encrypt at https://ci.appveyor.com/tools/encrypt
secure: maxxggRkssdjgLe3OEQaVQXBOtFyHVit/AsK0gBqSn8Uwf2tg9w/dvAR5Ivyn27O
artifact: /.*\.xpi$/
draft: false
prerelease: false # pre-releases would not count as `/latest` release, but the update server needs that
force_update: false # name should be unique anyway
on:
branch: master # release from master branch only
# don't restrict appveyor_repo_tag: if triggered manually and a tag already exists, create another one

This appveyor.yml configures the free-for-OSS CI build service AppVeyor to release AMO-signed beta versions of a Firefox WebExtension on GitHub, optionally with automatic updates using this tiny update server.

What you can get

  • You push to master on GitHub
  • AppVeyor releases a beta version on GitHub
    • e.g. 2.7.3b42 as version
    • signed using AMOs signing API
      • must use different id, e.g. with -dev suffix
    • released as tag e.g. v2.7.3b42 on GitHub
  • the update server now serves a update manifest pointing to the new dev channel release --> automatic updates work

What you need

For the above to work, your repo needs to provide:

  • (optional): A script (default: npm build) that creates a unsigned .zip file (default: in build/) that could be released on AMO
  • (mandatory): A script (default: npm run sign) that uses the env var manifest_version (or APPVEYOR_BUILD_NUMBER directly) to build and sign a dev version with a different applications.gecko.id (e.g. with -dev suffix). (default: .xpi in build/)
  • (optional): A update_url in the manifest.json (default: in build/ after previous step) to invalidate the cache of the update server

If your setup doesn't match this, you will need ...

Setup

Your project must be publically hosted on GitHub (or Bitbucket, ...) and you need to have/create an associated AppVeyor account. Then add the repo as project and use this .appveyor.yml as configuration:

  • either copy it to the root of your repository
  • or (especially to experiment with this) link to it under "Settings" > "General" > "Custom configuration .yml file name" (can be a direct HTTP link to this Gist)
  • you may also want to trick "Do not build on 'Pull request' events" on the same page

That's it, appveyor sets its git hooks automatically. You can start the first build by clicking "New Build" (under "Latest Build") or pushing a commit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment